Skip to content

Commit 8745029

Browse files
committed
Improve compatibility with existing cab views
1 parent b7485e5 commit 8745029

File tree

2 files changed

+67
-36
lines changed

2 files changed

+67
-36
lines changed

Source/Orts.Formats.Msts/CabViewFile.cs

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,14 +1116,25 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
11161116
Positions[i] = i;
11171117
}
11181118

1119-
// Check if eligible for filling
1119+
// Possible that positions were defined in reverse, eg: 3DTrains Surfliner trains
1120+
// Ensure positions are sorted from least to greatest before proceeding
1121+
if (Positions.Count > 0 && Positions[0] > Positions[Positions.Count - 1])
1122+
{
1123+
Reversed ^= true;
1124+
// Recalculate positions in reverse
1125+
for (int i = 0; i < Positions.Count; i++)
1126+
Positions[i] = (FramesCount - 1) - Positions[i];
1127+
}
11201128

1121-
if (Positions.Count > 1 && Positions[0] != 0) CanFill = false;
1129+
// Check if eligible for filling
1130+
if (Positions.Count > 1 && Positions[0] != 0)
1131+
CanFill = false;
11221132
else
11231133
{
11241134
for (var iPos = 1; iPos <= Positions.Count - 1; iPos++)
11251135
{
1126-
if (Positions[iPos] > Positions[iPos-1]) continue;
1136+
if (Positions[iPos] > Positions[iPos-1])
1137+
continue;
11271138
CanFill = false;
11281139
break;
11291140
}
@@ -1258,42 +1269,47 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
12581269
// Fill empty Values
12591270
for (int i = 0; i < (FramesCount - 1); i++)
12601271
Values.Add(0);
1272+
// Offset for min and max values to achieve equal frame spacing
1273+
double offset = 1.0 / (2.0 * FramesCount);
12611274
// Some dummy controls will have only one frame
12621275
if (Values.Count > 0)
1263-
Values[0] = MinValue;
1276+
Values[0] = MinValue + offset;
12641277
else
1265-
Values.Add(MinValue);
1278+
Values.Add(MinValue + offset);
12661279

12671280
// Add maximum value to the end
1268-
Values.Add(MaxValue);
1281+
Values.Add(MaxValue - offset);
12691282
}
12701283
else if (Values.Count == 2 && Values[0] == 0 && Values[1] < MaxValue && Positions[0] == 0 && Positions[1] == 1 && Values.Count < FramesCount)
12711284
{
12721285
//This if clause covers among others following cases:
12731286
// Case 1 (e.g. engine brake lever of gp38):
1274-
//NumFrames ( 18 2 9 )
1275-
//NumPositions ( 2 0 1 )
1276-
//NumValues ( 2 0 0.3 )
1277-
//Orientation ( 0 )
1278-
//DirIncrease ( 0 )
1279-
//ScaleRange ( 0 1 )
1287+
//NumFrames ( 18 2 9 )
1288+
//NumPositions ( 2 0 1 )
1289+
//NumValues ( 2 0 0.3 )
1290+
//Orientation ( 0 )
1291+
//DirIncrease ( 0 )
1292+
//ScaleRange ( 0 1 )
1293+
// Add missing positions
12801294
Positions.Add(FramesCount - 1);
12811295
// Fill empty Values
12821296
for (int i = Values.Count; i < (FramesCount - 1); i++)
1283-
Values.Add(Values[1]);
1297+
Values.Add(0);
1298+
// Offset for min and max values to achieve equal frame spacing
1299+
double offset = 1.0 / (2.0 * FramesCount);
12841300
// Add maximum value to the end
1285-
Values.Add(MaxValue);
1301+
Values.Add(MaxValue - offset);
12861302
}
12871303
else
12881304
{
12891305
//This if clause covers among others following cases:
12901306
// Case 1 (e.g. train brake lever of Acela):
1291-
//NumFrames ( 12 4 3 )
1292-
//NumPositions ( 5 0 1 9 10 11 )
1293-
//NumValues ( 5 0 0.2 0.85 0.9 0.95 )
1294-
//Orientation ( 1 )
1295-
//DirIncrease ( 1 )
1296-
//ScaleRange ( 0 1 )
1307+
//NumFrames ( 12 4 3 )
1308+
//NumPositions ( 5 0 1 9 10 11 )
1309+
//NumValues ( 5 0 0.2 0.85 0.9 0.95 )
1310+
//Orientation ( 1 )
1311+
//DirIncrease ( 1 )
1312+
//ScaleRange ( 0 1 )
12971313
//
12981314
// Fill empty Values
12991315
int iValues = 1;
@@ -1369,7 +1385,7 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
13691385
// Ensure resulting set of values has the correct format (sorted least to greatest) and resort
13701386
// Assume values have been entered in reverse order if final value is less than initial value
13711387
if (Values.Count > 0 && Values[0] > Values[Values.Count - 1])
1372-
Reversed = true;
1388+
Reversed ^= true;
13731389
// Force sort values from least to greatest
13741390
Values.Sort();
13751391

@@ -1424,9 +1440,8 @@ public CVCMultiStateDisplay(STFReader stf, string basepath)
14241440
; }),
14251441
});}),
14261442
});
1427-
if (Values.Count > 0) MaxValue = Values.Last();
1428-
for (int i = Values.Count; i < FramesCount; i++)
1429-
Values.Add(-10000);
1443+
if (Values.Count > 0)
1444+
MaxValue = Values.Max();
14301445
}),
14311446
new STFReader.TokenProcessor("ortsdisplay", ()=>{ParseDisplay(stf); }),
14321447
new STFReader.TokenProcessor("ortsscreenpage", () => {ParseScreen(stf); }),
@@ -1436,7 +1451,10 @@ public CVCMultiStateDisplay(STFReader stf, string basepath)
14361451
// Ensure resulting set of values has the correct format (sorted least to greatest) and resort
14371452
// Assume values have been entered in reverse order if final value is less than initial value
14381453
if (Values.Count > 0 && Values[0] > Values[Values.Count - 1])
1439-
Reversed = true;
1454+
Reversed ^= true;
1455+
// Fill in missing values
1456+
for (int i = Values.Count; i < FramesCount; i++)
1457+
Values.Add(Values[Values.Count - 1]);
14401458
// Force sort values from least to greatest
14411459
Values.Sort();
14421460
}
@@ -1481,9 +1499,8 @@ public CVCAnimatedDisplay(STFReader stf, string basepath)
14811499
; }),
14821500
});}),
14831501
});
1484-
if (Values.Count > 0) MaxValue = Values.Last();
1485-
for (int i = Values.Count; i < FramesCount; i++)
1486-
Values.Add(-10000);
1502+
if (Values.Count > 0)
1503+
MaxValue = Values.Max();
14871504
}),
14881505
new STFReader.TokenProcessor("ortsdisplay", ()=>{ParseDisplay(stf); }),
14891506
new STFReader.TokenProcessor("ortsscreenpage", () => {ParseScreen(stf); }),
@@ -1493,7 +1510,10 @@ public CVCAnimatedDisplay(STFReader stf, string basepath)
14931510
// Ensure resulting set of values has the correct format (sorted least to greatest) and resort
14941511
// Assume values have been entered in reverse order if final value is less than initial value
14951512
if (Values.Count > 0 && Values[0] > Values[Values.Count - 1])
1496-
Reversed = true;
1513+
Reversed ^= true;
1514+
// Fill in missing values
1515+
for (int i = Values.Count; i < FramesCount; i++)
1516+
Values.Add(Values[Values.Count - 1]);
14971517
// Force sort values from least to greatest
14981518
Values.Sort();
14991519
}

Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,8 +2041,18 @@ public CabViewDiscreteRenderer(Viewer viewer, MSTSLocomotive locomotive, CVCWith
20412041
break;
20422042
default: ChangedValue = (value) => value + NormalizedMouseMovement(); break;
20432043
}
2044-
// The cab view control index shown when combined control is at the split position
2045-
SplitIndex = PercentToIndex(Locomotive.CombinedControlSplitPosition);
2044+
// Determine the cab view control index shown when combined control is at the split position
2045+
// Find the index of the next value LARGER than the split value
2046+
int splitIndex = ControlDiscrete.Values.BinarySearch(Locomotive.CombinedControlSplitPosition);
2047+
// Account for any edge cases
2048+
if (splitIndex < 0)
2049+
splitIndex = ~splitIndex;
2050+
if (splitIndex > ControlDiscrete.Values.Count - 1)
2051+
splitIndex = ControlDiscrete.Values.Count - 1;
2052+
if (ControlDiscrete.Reversed)
2053+
splitIndex = (ControlDiscrete.Values.Count - 1) - splitIndex;
2054+
2055+
SplitIndex = splitIndex;
20462056
}
20472057

20482058
public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
@@ -2151,13 +2161,14 @@ public virtual int GetDrawIndex()
21512161
case CABViewControlTypes.CP_HANDLE:
21522162
var combinedHandlePosition = Locomotive.GetCombinedHandleValue(false);
21532163
index = PercentToIndex(combinedHandlePosition);
2154-
// Make sure power indications are not shown when locomotive is in braking range
2155-
if (combinedHandlePosition > Locomotive.CombinedControlSplitPosition)
2164+
// Make sure any deviation from the split position gives a different index
2165+
int handleRelativePos = combinedHandlePosition.CompareTo(Locomotive.CombinedControlSplitPosition);
2166+
if (handleRelativePos != 0)
21562167
{
2157-
if (ControlDiscrete.Reversed)
2158-
index = Math.Min(index, SplitIndex - 1);
2159-
else
2168+
if (handleRelativePos == (ControlDiscrete.Reversed ? - 1 : 1))
21602169
index = Math.Max(index, SplitIndex + 1);
2170+
else
2171+
index = Math.Min(index, SplitIndex - 1);
21612172
}
21622173
break;
21632174
case CABViewControlTypes.ORTS_SELECTED_SPEED_DISPLAY:

0 commit comments

Comments
 (0)