@@ -2005,6 +2005,7 @@ public class CabViewDiscreteRenderer : CabViewControlRenderer, ICabViewMouseCont
2005
2005
float Scale = 1 ;
2006
2006
int OldFrameIndex = 0 ;
2007
2007
public bool ButtonState = false ;
2008
+ int SplitIndex = - 1 ;
2008
2009
2009
2010
/// <summary>
2010
2011
/// 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
2040
2041
break ;
2041
2042
default : ChangedValue = ( value ) => value + NormalizedMouseMovement ( ) ; break ;
2042
2043
}
2044
+ // The cab view control index shown when combined control is at the split position
2045
+ SplitIndex = PercentToIndex ( Locomotive . CombinedControlSplitPosition ) ;
2043
2046
}
2044
2047
2045
2048
public override void PrepareFrame ( RenderFrame frame , ElapsedTime elapsedTime )
@@ -2145,21 +2148,12 @@ public virtual int GetDrawIndex()
2145
2148
index = PercentToIndex ( dynBrakePercent ) ;
2146
2149
break ;
2147
2150
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 ;
2157
2151
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 ) ;
2163
2157
break ;
2164
2158
case CABViewControlTypes . ORTS_SELECTED_SPEED_DISPLAY :
2165
2159
if ( Locomotive . CruiseControl == null )
@@ -2816,9 +2810,29 @@ protected int PercentToIndex(float percent)
2816
2810
{
2817
2811
try
2818
2812
{
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 ;
2822
2836
}
2823
2837
catch
2824
2838
{
0 commit comments