@@ -2005,6 +2005,7 @@ public class CabViewDiscreteRenderer : CabViewControlRenderer, ICabViewMouseCont
20052005 float Scale = 1 ;
20062006 int OldFrameIndex = 0 ;
20072007 public bool ButtonState = false ;
2008+ int SplitIndex = - 1 ;
20082009
20092010 /// <summary>
20102011 /// Accumulated mouse movement. Used for controls with no assigned notch controllers, e.g. headlight and reverser.
@@ -2040,6 +2041,8 @@ public CabViewDiscreteRenderer(Viewer viewer, MSTSLocomotive locomotive, CVCWith
20402041 break ;
20412042 default : ChangedValue = ( value ) => value + NormalizedMouseMovement ( ) ; break ;
20422043 }
2044+ // The cab view control index shown when combined control is at the split position
2045+ SplitIndex = PercentToIndex ( Locomotive . CombinedControlSplitPosition ) ;
20432046 }
20442047
20452048 public override void PrepareFrame ( RenderFrame frame , ElapsedTime elapsedTime )
@@ -2145,21 +2148,12 @@ public virtual int GetDrawIndex()
21452148 index = PercentToIndex ( dynBrakePercent ) ;
21462149 break ;
21472150 case CABViewControlTypes . CPH_DISPLAY :
2148- if ( Locomotive . CombinedControlType == MSTSLocomotive . CombinedControl . ThrottleDynamic && Locomotive . DynamicBrakeController ? . CurrentValue > 0 )
2149- // TODO <CSComment> This is a sort of hack to allow MSTS-compliant operation of Dynamic brake indications in the standard USA case with 8 steps (e.g. Dash9)
2150- // This hack returns to code of previous OR versions (e.g. release 1.0).
2151- // The clean solution for MSTS compliance would be not to increment the percentage of the dynamic brake at first dynamic brake key pression, so that
2152- // subsequent steps become of 12.5% as in MSTS instead of 11.11% as in OR. This requires changes in the physics logic </CSComment>
2153- index = ( int ) ( ( ControlDiscrete . FramesCount ) * Locomotive . GetCombinedHandleValue ( false ) ) ;
2154- else
2155- index = PercentToIndex ( Locomotive . GetCombinedHandleValue ( false ) ) ;
2156- break ;
21572151 case CABViewControlTypes . CP_HANDLE :
2158- if ( Locomotive . CombinedControlType == MSTSLocomotive . CombinedControl . ThrottleDynamic && Locomotive . DynamicBrakeController ? . CurrentValue > 0
2159- || Locomotive . CombinedControlType == MSTSLocomotive . CombinedControl . ThrottleAir && Locomotive . TrainBrakeController ? . CurrentValue > 0 )
2160- index = PercentToIndex ( Locomotive . GetCombinedHandleValue ( false ) ) ;
2161- else
2162- index = PercentToIndex ( Locomotive . GetCombinedHandleValue ( false ) ) ;
2152+ var combinedHandlePosition = Locomotive . GetCombinedHandleValue ( false ) ;
2153+ index = PercentToIndex ( combinedHandlePosition ) ;
2154+ // Make sure power indications are not shown when locomotive is in braking range
2155+ if ( combinedHandlePosition > Locomotive . CombinedControlSplitPosition )
2156+ index = Math . Max ( index , SplitIndex + 1 ) ;
21632157 break ;
21642158 case CABViewControlTypes . ORTS_SELECTED_SPEED_DISPLAY :
21652159 if ( Locomotive . CruiseControl == null )
@@ -2816,9 +2810,29 @@ protected int PercentToIndex(float percent)
28162810 {
28172811 try
28182812 {
2819- var val = ControlDiscrete . Values [ 0 ] <= ControlDiscrete . Values [ ControlDiscrete . Values . Count - 1 ] ?
2820- ControlDiscrete . Values . Where ( v => ( float ) v <= percent + 0.00001 ) . Last ( ) : ControlDiscrete . Values . Where ( v => ( float ) v <= percent + 0.00001 ) . First ( ) ;
2821- index = ControlDiscrete . Values . IndexOf ( val ) ;
2813+ // Binary search process to find the control value closest to percent
2814+ List < double > vals = ControlDiscrete . Values ;
2815+ // Check if control values were defined in reverse, reverse them back for this calculation
2816+ // This is less efficient, so creators should be encouraged to not do this
2817+ bool reversed = ControlDiscrete . Values [ 0 ] > ControlDiscrete . Values [ ControlDiscrete . Values . Count - 1 ] ;
2818+ if ( reversed )
2819+ vals . Reverse ( ) ;
2820+
2821+ // Returns index of first val larger than percent, or bitwise compliment of this index if percent isn't in the list
2822+ int checkIndex = vals . BinarySearch ( percent ) ;
2823+
2824+ if ( checkIndex < 0 )
2825+ checkIndex = ~ checkIndex ;
2826+ if ( checkIndex > vals . Count - 1 )
2827+ checkIndex = vals . Count - 1 ;
2828+ // Choose lower index if it is closer to percent
2829+ if ( checkIndex > 0 && Math . Abs ( vals [ checkIndex - 1 ] - percent ) < Math . Abs ( vals [ checkIndex ] - percent ) )
2830+ checkIndex -- ;
2831+ // Re-reverse the index as needed
2832+ if ( reversed )
2833+ checkIndex = ( vals . Count - 1 ) - checkIndex ;
2834+
2835+ index = checkIndex ;
28222836 }
28232837 catch
28242838 {
0 commit comments