@@ -236,46 +236,71 @@ public override void HandleUserInput(ElapsedTime elapsedTime)
236236 if ( UserInput . IsPressed ( UserCommand . DebugResetWheelSlip ) ) { Locomotive . Train . SignalEvent ( Event . _ResetWheelSlip ) ; }
237237 if ( UserInput . IsPressed ( UserCommand . DebugToggleAdvancedAdhesion ) ) { Locomotive . Train . SignalEvent ( Event . _ResetWheelSlip ) ; Locomotive . Simulator . UseAdvancedAdhesion = ! Locomotive . Simulator . UseAdvancedAdhesion ; }
238238
239- if ( UserInput . RDState != null )
239+ ExternalDeviceState [ ] externalDevices = { UserInput . RDState , UserInput . WebDeviceState } ;
240+ foreach ( var external in externalDevices )
240241 {
241- if ( UserInput . RDState . BailOff )
242+ if ( external == null ) continue ;
243+ // Handle other cabcontrols
244+ foreach ( var kvp in external . CabControls )
242245 {
243- Locomotive . SetBailOff ( true ) ;
244- }
245- if ( UserInput . RDState . Changed )
246- {
247- Locomotive . AlerterReset ( ) ;
248-
249- Locomotive . SetThrottlePercentWithSound ( UserInput . RDState . ThrottlePercent ) ;
250- Locomotive . SetTrainBrakePercent ( UserInput . RDState . TrainBrakePercent ) ;
251- Locomotive . SetEngineBrakePercent ( UserInput . RDState . EngineBrakePercent ) ;
252- // Locomotive.SetBrakemanBrakePercent(UserInput.RDState.BrakemanBrakePercent); // For Raildriver control not complete for this value?
253- if ( Locomotive . CombinedControlType != MSTSLocomotive . CombinedControl . ThrottleAir )
254- Locomotive . SetDynamicBrakePercentWithSound ( UserInput . RDState . DynamicBrakePercent ) ;
255- if ( UserInput . RDState . DirectionPercent > 50 )
256- Locomotive . SetDirection ( Direction . Forward ) ;
257- else if ( UserInput . RDState . DirectionPercent < - 50 )
258- Locomotive . SetDirection ( Direction . Reverse ) ;
259- else
260- Locomotive . SetDirection ( Direction . N ) ;
261- if ( UserInput . RDState . Emergency )
262- new EmergencyPushButtonCommand ( Viewer . Log , true ) ;
263- else
264- new EmergencyPushButtonCommand ( Viewer . Log , false ) ;
265- if ( UserInput . RDState . Wipers == 1 && Locomotive . Wiper )
266- Locomotive . SignalEvent ( Event . WiperOff ) ;
267- if ( UserInput . RDState . Wipers != 1 && ! Locomotive . Wiper )
268- Locomotive . SignalEvent ( Event . WiperOn ) ;
269- // changing Headlight more than one step at a time doesn't work for some reason
270- if ( Locomotive . Headlight < UserInput . RDState . Lights - 1 )
271- {
272- Locomotive . Headlight ++ ;
273- Locomotive . SignalEvent ( Event . LightSwitchToggle ) ;
274- }
275- if ( Locomotive . Headlight > UserInput . RDState . Lights - 1 )
246+ if ( ! kvp . Value . Changed ) continue ;
247+ float val = kvp . Value . Value ;
248+ switch ( kvp . Key . Item1 . Type )
276249 {
277- Locomotive . Headlight -- ;
278- Locomotive . SignalEvent ( Event . LightSwitchToggle ) ;
250+ // Some cab controls need specific handling for better results
251+ case CABViewControlTypes . THROTTLE :
252+ Locomotive . SetThrottlePercentWithSound ( val * 100 ) ;
253+ break ;
254+ case CABViewControlTypes . DIRECTION :
255+ if ( Locomotive is MSTSSteamLocomotive steam )
256+ {
257+ steam . SetCutoffPercent ( val * 100 ) ;
258+ }
259+ else if ( val > 0.5f )
260+ Locomotive . SetDirection ( Direction . Forward ) ;
261+ else if ( val < - 0.5f )
262+ Locomotive . SetDirection ( Direction . Reverse ) ;
263+ else
264+ Locomotive . SetDirection ( Direction . N ) ;
265+ break ;
266+ case CABViewControlTypes . TRAIN_BRAKE :
267+ Locomotive . SetTrainBrakePercent ( val * 100 ) ;
268+ break ;
269+ case CABViewControlTypes . DYNAMIC_BRAKE :
270+ if ( Locomotive . CombinedControlType != MSTSLocomotive . CombinedControl . ThrottleAir )
271+ Locomotive . SetDynamicBrakePercentWithSound ( val * 100 ) ;
272+ break ;
273+ case CABViewControlTypes . ENGINE_BRAKE :
274+ Locomotive . SetEngineBrakePercent ( val * 100 ) ;
275+ break ;
276+ case CABViewControlTypes . FRONT_HLIGHT :
277+ // changing Headlight more than one step at a time doesn't work for some reason
278+ if ( Locomotive . Headlight < val - 1 )
279+ {
280+ Locomotive . Headlight ++ ;
281+ Locomotive . SignalEvent ( Event . LightSwitchToggle ) ;
282+ }
283+ if ( Locomotive . Headlight > val - 1 )
284+ {
285+ Locomotive . Headlight -- ;
286+ Locomotive . SignalEvent ( Event . LightSwitchToggle ) ;
287+ }
288+ break ;
289+ case CABViewControlTypes . ORTS_SELECTED_SPEED_SELECTOR :
290+ Locomotive . CruiseControl . SelectedSpeedMpS = val ;
291+ break ;
292+ // Other controls can hopefully be controlled faking mouse input
293+ // TODO: refactor HandleUserInput()
294+ default :
295+ var cabRenderer = ThreeDimentionCabRenderer ?? _CabRenderer ;
296+ if ( cabRenderer != null && cabRenderer . ControlMap . TryGetValue ( kvp . Key , out var renderer ) && renderer is CabViewDiscreteRenderer discrete )
297+ {
298+ var oldChanged = discrete . ChangedValue ;
299+ discrete . ChangedValue = ( oldval ) => val ;
300+ discrete . HandleUserInput ( ) ;
301+ discrete . ChangedValue = oldChanged ;
302+ }
303+ break ;
279304 }
280305 }
281306 }
@@ -1982,7 +2007,7 @@ public class CabViewDiscreteRenderer : CabViewControlRenderer, ICabViewMouseCont
19822007 /// <summary>
19832008 /// Function calculating response value for mouse events (movement, left-click), determined by configured style.
19842009 /// </summary>
1985- readonly Func < float , float > ChangedValue ;
2010+ public Func < float , float > ChangedValue ;
19862011
19872012 public CabViewDiscreteRenderer ( Viewer viewer , MSTSLocomotive locomotive , CVCWithFrames control , CabShader shader )
19882013 : base ( viewer , locomotive , control , shader )
0 commit comments