@@ -1007,6 +1007,7 @@ public abstract class CVCWithFrames : CabViewControl
10071007 public bool MouseControl ;
10081008 public int Orientation ;
10091009 public int Direction ;
1010+ public bool Reversed { get ; protected set ; } = false ;
10101011
10111012 public List < double > Values
10121013 {
@@ -1022,8 +1023,8 @@ public class CVCDiscrete : CVCWithFrames
10221023 public List < int > Positions = new List < int > ( ) ;
10231024
10241025 private int _ValuesRead ;
1025- private int numPositions ;
1026- private bool canFill = true ;
1026+ private int NumPositions ;
1027+ private bool CanFill = true ;
10271028
10281029 public struct NewScreenData
10291030 {
@@ -1076,7 +1077,7 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
10761077 stf . MustMatch ( "(" ) ;
10771078 // If Positions are not filled before by Values
10781079 bool shouldFill = ( Positions . Count == 0 ) ;
1079- numPositions = stf . ReadInt ( null ) ; // Number of Positions
1080+ NumPositions = stf . ReadInt ( null ) ; // Number of Positions
10801081
10811082 var minPosition = 0 ;
10821083 var positionsRead = 0 ;
@@ -1117,20 +1118,20 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
11171118
11181119 // Check if eligible for filling
11191120
1120- if ( Positions . Count > 1 && Positions [ 0 ] != 0 ) canFill = false ;
1121+ if ( Positions . Count > 1 && Positions [ 0 ] != 0 ) CanFill = false ;
11211122 else
11221123 {
11231124 for ( var iPos = 1 ; iPos <= Positions . Count - 1 ; iPos ++ )
11241125 {
11251126 if ( Positions [ iPos ] > Positions [ iPos - 1 ] ) continue ;
1126- canFill = false ;
1127+ CanFill = false ;
11271128 break ;
11281129 }
11291130 }
11301131
11311132 // This is a protection against GP40 locomotives that erroneously have positions pointing beyond frame count limit.
11321133
1133- if ( Positions . Count > 1 && canFill && Positions . Count < FramesCount && Positions [ Positions . Count - 1 ] >= FramesCount && Positions [ 0 ] == 0 )
1134+ if ( Positions . Count > 1 && CanFill && Positions . Count < FramesCount && Positions [ Positions . Count - 1 ] >= FramesCount && Positions [ 0 ] == 0 )
11341135 {
11351136 STFException . TraceInformation ( stf , "Some NumPositions entries refer to non-exisiting frames, trying to renumber" ) ;
11361137 Positions [ Positions . Count - 1 ] = FramesCount - 1 ;
@@ -1155,7 +1156,7 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
11551156 }
11561157 // Avoid later repositioning, put every value to its Position
11571158 // But before resize Values if needed
1158- if ( numValues != numPositions )
1159+ if ( numValues != NumPositions )
11591160 {
11601161 while ( Values . Count <= Positions [ _ValuesRead ] )
11611162 {
@@ -1214,7 +1215,7 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
12141215
12151216 // Only shuffle data in following cases
12161217
1217- if ( Values . Count != Positions . Count || ( Values . Count < FramesCount & canFill ) || ( Values . Count > 0 && Values [ 0 ] == Values [ Values . Count - 1 ] && Values [ 0 ] == 0 ) )
1218+ if ( Values . Count != Positions . Count || ( Values . Count < FramesCount & CanFill ) || ( Values . Count > 0 && Values [ 0 ] == Values [ Values . Count - 1 ] && Values [ 0 ] == 0 ) )
12181219 {
12191220
12201221 // Fixup Positions and Values collections first
@@ -1257,7 +1258,11 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
12571258 // Fill empty Values
12581259 for ( int i = 0 ; i < ( FramesCount - 1 ) ; i ++ )
12591260 Values . Add ( 0 ) ;
1260- Values [ 0 ] = MinValue ;
1261+ // Some dummy controls will have only one frame
1262+ if ( Values . Count > 0 )
1263+ Values [ 0 ] = MinValue ;
1264+ else
1265+ Values . Add ( MinValue ) ;
12611266
12621267 // Add maximum value to the end
12631268 Values . Add ( MaxValue ) ;
@@ -1353,13 +1358,21 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
13531358 break ;
13541359 }
13551360 }
1356- // catch (Exception error)
1357- // {
1358- // if (error is STFException) // Parsing error, so pass it on
1359- // throw;
1360- // else // Unexpected error, so provide a hint
1361- // throw new STFException(stf, "Problem with NumPositions/NumValues/NumFrames/ScaleRange");
1362- // } // End of Need check the Values collection for validity
1361+ // catch (Exception error)
1362+ // {
1363+ // if (error is STFException) // Parsing error, so pass it on
1364+ // throw;
1365+ // else // Unexpected error, so provide a hint
1366+ // throw new STFException(stf, "Problem with NumPositions/NumValues/NumFrames/ScaleRange");
1367+ // } // End of Need check the Values collection for validity
1368+
1369+ // Ensure resulting set of values has the correct format (sorted least to greatest) and resort
1370+ // Assume values have been entered in reverse order if final value is less than initial value
1371+ if ( Values . Count > 0 && Values [ 0 ] > Values [ Values . Count - 1 ] )
1372+ Reversed = true ;
1373+ // Force sort values from least to greatest
1374+ Values . Sort ( ) ;
1375+
13631376 } // End of Constructor
13641377
13651378 protected void ParseNewScreen ( STFReader stf )
@@ -1407,7 +1420,7 @@ public CVCMultiStateDisplay(STFReader stf, string basepath)
14071420 stf . ParseBlock ( new STFReader . TokenProcessor [ ] {
14081421 new STFReader . TokenProcessor ( "style" , ( ) => { MSStyles . Add ( ParseNumStyle ( stf ) ) ;
14091422 } ) ,
1410- new STFReader . TokenProcessor ( "switchval" , ( ) => { Values . Add ( stf . ReadFloatBlock ( STFReader . UNITS . None , null ) )
1423+ new STFReader . TokenProcessor ( "switchval" , ( ) => { Values . Add ( stf . ReadDoubleBlock ( null ) )
14111424 ; } ) ,
14121425 } ) ; } ) ,
14131426 } ) ;
@@ -1419,6 +1432,13 @@ public CVCMultiStateDisplay(STFReader stf, string basepath)
14191432 new STFReader . TokenProcessor ( "ortsscreenpage" , ( ) => { ParseScreen ( stf ) ; } ) ,
14201433 new STFReader . TokenProcessor ( "ortscabviewpoint" , ( ) => { ParseCabViewpoint ( stf ) ; } ) ,
14211434 } ) ;
1435+
1436+ // Ensure resulting set of values has the correct format (sorted least to greatest) and resort
1437+ // Assume values have been entered in reverse order if final value is less than initial value
1438+ if ( Values . Count > 0 && Values [ 0 ] > Values [ Values . Count - 1 ] )
1439+ Reversed = true ;
1440+ // Force sort values from least to greatest
1441+ Values . Sort ( ) ;
14221442 }
14231443 protected int ParseNumStyle ( STFReader stf )
14241444 {
@@ -1457,7 +1477,7 @@ public CVCAnimatedDisplay(STFReader stf, string basepath)
14571477 stf . ParseBlock ( new STFReader . TokenProcessor [ ] {
14581478 new STFReader . TokenProcessor ( "style" , ( ) => { MSStyles . Add ( ParseNumStyle ( stf ) ) ;
14591479 } ) ,
1460- new STFReader . TokenProcessor ( "switchval" , ( ) => { Values . Add ( stf . ReadFloatBlock ( STFReader . UNITS . None , null ) )
1480+ new STFReader . TokenProcessor ( "switchval" , ( ) => { Values . Add ( stf . ReadDoubleBlock ( null ) )
14611481 ; } ) ,
14621482 } ) ; } ) ,
14631483 } ) ;
@@ -1469,6 +1489,13 @@ public CVCAnimatedDisplay(STFReader stf, string basepath)
14691489 new STFReader . TokenProcessor ( "ortsscreenpage" , ( ) => { ParseScreen ( stf ) ; } ) ,
14701490 new STFReader . TokenProcessor ( "ortscabviewpoint" , ( ) => { ParseCabViewpoint ( stf ) ; } ) ,
14711491 } ) ;
1492+
1493+ // Ensure resulting set of values has the correct format (sorted least to greatest) and resort
1494+ // Assume values have been entered in reverse order if final value is less than initial value
1495+ if ( Values . Count > 0 && Values [ 0 ] > Values [ Values . Count - 1 ] )
1496+ Reversed = true ;
1497+ // Force sort values from least to greatest
1498+ Values . Sort ( ) ;
14721499 }
14731500 protected int ParseNumStyle ( STFReader stf )
14741501 {
0 commit comments