17
17
18
18
// This file is the responsibility of the 3D & Environment Team.
19
19
20
+ using System ;
21
+ using System . Collections . Generic ;
22
+ using System . Linq ;
20
23
using Microsoft . Xna . Framework ;
21
24
using Microsoft . Xna . Framework . Graphics ;
22
25
using Orts . Formats . Msts ;
25
28
using Orts . Viewer3D . RollingStock . SubSystems . ETCS ;
26
29
using ORTS . Common ;
27
30
using ORTS . Scripting . Api . ETCS ;
28
- using System ;
29
- using System . Collections . Generic ;
30
- using System . Linq ;
31
31
using static Orts . Viewer3D . RollingStock . Subsystems . ETCS . DriverMachineInterface ;
32
32
33
33
namespace Orts . Viewer3D . RollingStock . Subsystems . ETCS
34
34
{
35
35
public class DriverMachineInterface
36
36
{
37
37
public readonly MSTSLocomotive Locomotive ;
38
- public readonly bool GaugeOnly ;
39
38
public readonly Viewer Viewer ;
40
39
public IList < DMIWindow > Windows = new List < DMIWindow > ( ) ;
41
40
float PrevScale = 1 ;
@@ -44,8 +43,8 @@ public class DriverMachineInterface
44
43
bool Active ;
45
44
public float Scale { get ; private set ; }
46
45
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 ;
49
48
50
49
public readonly ETCSDefaultWindow ETCSDefaultWindow ;
51
50
@@ -70,6 +69,16 @@ public class DriverMachineInterface
70
69
71
70
public bool Blinker2Hz { get ; private set ; }
72
71
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
+
73
82
float BlinkerTime ;
74
83
75
84
public float CurrentTime => ( float ) Viewer . Simulator . ClockTime ;
@@ -88,12 +97,40 @@ public class DriverMachineInterface
88
97
DMIButton ActiveButton ;
89
98
public DriverMachineInterface ( float height , float width , MSTSLocomotive locomotive , Viewer viewer , CabViewControl control )
90
99
{
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
+ }
91
129
Viewer = viewer ;
92
130
Locomotive = locomotive ;
93
131
Scale = Math . Min ( width / Width , height / Height ) ;
94
132
if ( Scale < 0.5 ) MipMapScale = 2 ;
95
133
else MipMapScale = 1 ;
96
- GaugeOnly = control is CVCDigital ;
97
134
98
135
Shader = new DriverMachineInterfaceShader ( Viewer . GraphicsDevice ) ;
99
136
ETCSDefaultWindow = new ETCSDefaultWindow ( this , control ) ;
@@ -259,20 +296,22 @@ public class ETCSDefaultWindow : DMIWindow
259
296
TargetDistance TargetDistance ;
260
297
TTIandLSSMArea TTIandLSSMArea ;
261
298
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 )
263
300
{
264
- if ( control is CVCDigital )
301
+ if ( dmi . CurrentDMIMode == DMIMode . GaugeOnly )
265
302
{
266
303
var dig = control as CVCDigital ;
267
304
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 ;
274
313
}
275
- else
314
+ if ( dmi . CurrentDMIMode != DMIMode . PlanningArea )
276
315
{
277
316
var param = ( control as CVCScreen ) . CustomParameters ;
278
317
int maxSpeed = 400 ;
@@ -286,34 +325,37 @@ public ETCSDefaultWindow(DriverMachineInterface dmi, CabViewControl control) : b
286
325
maxSpeed == 240 || maxSpeed == 260 ,
287
326
maxVisibleSpeed ,
288
327
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
+ }
317
359
}
318
360
}
319
361
}
@@ -324,8 +366,8 @@ public class DMIArea
324
366
public readonly DriverMachineInterface DMI ;
325
367
protected Texture2D ColorTexture => DMI . ColorTexture ;
326
368
public float Scale => DMI . Scale ;
327
- public int Height ;
328
- public int Width ;
369
+ public readonly int Height ;
370
+ public readonly int Width ;
329
371
protected List < RectanglePrimitive > Rectangles = new List < RectanglePrimitive > ( ) ;
330
372
protected List < TextPrimitive > Texts = new List < TextPrimitive > ( ) ;
331
373
protected List < TexturePrimitive > Textures = new List < TexturePrimitive > ( ) ;
@@ -574,13 +616,6 @@ public class DMIButton : DMIArea
574
616
public bool ShowButtonBorder ;
575
617
public float FirstPressed ;
576
618
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
- }
584
619
public DMIButton ( string displayName , bool upType , Action pressedAction , int width , int height , DriverMachineInterface dmi , bool showButtonBorder = false ) : base ( dmi , width , height )
585
620
{
586
621
DisplayName = displayName ;
@@ -725,13 +760,11 @@ public CircularSpeedGaugeRenderer(Viewer viewer, MSTSLocomotive locomotive, CVCD
725
760
: base ( viewer , locomotive , control , shader )
726
761
{
727
762
// 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 ) ;
729
764
}
730
765
public override void PrepareFrame ( RenderFrame frame , ElapsedTime elapsedTime )
731
766
{
732
767
base . PrepareFrame ( frame , elapsedTime ) ;
733
- DrawPosition . Width = DrawPosition . Width * 640 / 280 ;
734
- DrawPosition . Height = DrawPosition . Height * 480 / 300 ;
735
768
DMI . SizeTo ( DrawPosition . Width , DrawPosition . Height ) ;
736
769
DMI . ETCSDefaultWindow . BackgroundColor = Color . Transparent ;
737
770
DMI . PrepareFrame ( elapsedTime . ClockSeconds ) ;
@@ -769,19 +802,19 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
769
802
return ;
770
803
771
804
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 ;
774
807
DrawPosition . X = ( int ) ( Position . X * xScale ) - Viewer . CabXOffsetPixels + Viewer . CabXLetterboxPixels ;
775
808
DrawPosition . Y = ( int ) ( Position . Y * yScale ) + Viewer . CabYOffsetPixels + Viewer . CabYLetterboxPixels ;
776
809
DrawPosition . Width = ( int ) ( Control . Width * xScale ) ;
777
810
DrawPosition . Height = ( int ) ( Control . Height * yScale ) ;
778
811
if ( Zoomed )
779
812
{
780
- DrawPosition . Width = 640 ;
781
- DrawPosition . Height = 480 ;
813
+ DrawPosition . Width = DMI . Width ;
814
+ DrawPosition . Height = DMI . Height ;
782
815
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 ;
785
818
DMI . ETCSDefaultWindow . BackgroundColor = ColorBackground ;
786
819
}
787
820
else
@@ -796,7 +829,7 @@ public bool IsMouseWithin()
796
829
{
797
830
int x = ( int ) ( ( UserInput . MouseX - DrawPosition . X ) / DMI . Scale ) ;
798
831
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 ;
800
833
foreach ( var area in DMI . ActiveWindow . SubAreas )
801
834
{
802
835
if ( ! ( area is DMIButton ) ) continue ;
0 commit comments