示例#1
0
文件: Writer.cs 项目: zbx1425/OpenBVE
        internal static void Write(string fileName, Train train)
        {
            StringBuilder builder = new StringBuilder();
            CultureInfo   culture = CultureInfo.InvariantCulture;
            const int     n       = 15;

            MotorCar   firstMotorCar   = train.Cars.OfType <MotorCar>().First();
            TrailerCar firstTrailerCar = train.Cars.OfType <TrailerCar>().FirstOrDefault();

            builder.AppendLine("OPENBVE" + currentVersion);

            builder.AppendLine("#ACCELERATION");

            for (int i = firstMotorCar.Acceleration.Entries.Count - 1; i >= train.Handle.PowerNotches; i--)
            {
                firstMotorCar.Acceleration.Entries.RemoveAt(i);
            }

            foreach (Acceleration.Entry entry in firstMotorCar.Acceleration.Entries)
            {
                builder.Append(entry.A0.ToString(culture) + ",");
                builder.Append(entry.A1.ToString(culture) + ",");
                builder.Append(entry.V1.ToString(culture) + ",");
                builder.Append(entry.V2.ToString(culture) + ",");
                builder.AppendLine(entry.E.ToString(culture));
            }

            builder.AppendLine("#PERFORMANCE");
            builder.AppendLine($"{firstMotorCar.Performance.Deceleration.ToString(culture).PadRight(n, ' ')}; Deceleration");
            builder.AppendLine($"{firstMotorCar.Performance.CoefficientOfStaticFriction.ToString(culture).PadRight(n, ' ')}; CoefficientOfStaticFriction");
            builder.AppendLine($"{"0".PadRight(n, ' ')}; Reserved (not used)");
            builder.AppendLine($"{firstMotorCar.Performance.CoefficientOfRollingResistance.ToString(culture).PadRight(n, ' ')}; CoefficientOfRollingResistance");
            builder.AppendLine($"{firstMotorCar.Performance.AerodynamicDragCoefficient.ToString(culture).PadRight(n, ' ')}; AerodynamicDragCoefficient");

            builder.AppendLine("#DELAY");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayPower.Select(d => d.Up.ToString(culture))).PadRight(n, ' ')}; DelayPowerUp");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayPower.Select(d => d.Down.ToString(culture))).PadRight(n, ' ')}; DelayPowerDown");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayBrake.Select(d => d.Up.ToString(culture))).PadRight(n, ' ')}; DelayBrakeUp");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayBrake.Select(d => d.Down.ToString(culture))).PadRight(n, ' ')}; DelayBrakeDown");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayLocoBrake.Select(d => d.Up.ToString(culture))).PadRight(n, ' ')}; DelayLocoBrakeUp (1.5.3.4+)");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayLocoBrake.Select(d => d.Down.ToString(culture))).PadRight(n, ' ')}; DelayLocoBrakeDown (1.5.3.4+)");

            builder.AppendLine("#MOVE");
            builder.AppendLine($"{firstMotorCar.Move.JerkPowerUp.ToString(culture).PadRight(n, ' ')}; JerkPowerUp");
            builder.AppendLine($"{firstMotorCar.Move.JerkPowerDown.ToString(culture).PadRight(n, ' ')}; JerkPowerDown");
            builder.AppendLine($"{firstMotorCar.Move.JerkBrakeUp.ToString(culture).PadRight(n, ' ')}; JerkBrakeUp");
            builder.AppendLine($"{firstMotorCar.Move.JerkBrakeDown.ToString(culture).PadRight(n, ' ')}; JerkBrakeDown");
            builder.AppendLine($"{firstMotorCar.Move.BrakeCylinderUp.ToString(culture).PadRight(n, ' ')}; BrakeCylinderUp");
            builder.AppendLine($"{firstMotorCar.Move.BrakeCylinderDown.ToString(culture).PadRight(n, ' ')}; BrakeCylinderDown");

            builder.AppendLine("#BRAKE");
            builder.AppendLine($"{((int)firstMotorCar.Brake.BrakeType).ToString(culture).PadRight(n, ' ')}; BrakeType");
            builder.AppendLine($"{((int)firstMotorCar.Brake.BrakeControlSystem).ToString(culture).PadRight(n, ' ')}; BrakeControlSystem");
            builder.AppendLine($"{firstMotorCar.Brake.BrakeControlSpeed.ToString(culture).PadRight(n, ' ')}; BrakeControlSpeed");
            builder.AppendLine($"{((int)firstMotorCar.Brake.LocoBrakeType).ToString(culture).PadRight(n, ' ')}; LocoBrakeType (1.5.3.4+)");

            builder.AppendLine("#PRESSURE");
            builder.AppendLine($"{firstMotorCar.Pressure.BrakeCylinderServiceMaximumPressure.ToString(culture).PadRight(n, ' ')}; BrakeCylinderServiceMaximumPressure");
            builder.AppendLine($"{firstMotorCar.Pressure.BrakeCylinderEmergencyMaximumPressure.ToString(culture).PadRight(n, ' ')}; BrakeCylinderEmergencyMaximumPressure");
            builder.AppendLine($"{firstMotorCar.Pressure.MainReservoirMinimumPressure.ToString(culture).PadRight(n, ' ')}; MainReservoirMinimumPressure");
            builder.AppendLine($"{firstMotorCar.Pressure.MainReservoirMaximumPressure.ToString(culture).PadRight(n, ' ')}; MainReservoirMaximumPressure");
            builder.AppendLine($"{firstMotorCar.Pressure.BrakePipeNormalPressure.ToString(culture).PadRight(n, ' ')}; BrakePipeNormalPressure");

            builder.AppendLine("#HANDLE");
            builder.AppendLine($"{((int)train.Handle.HandleType).ToString(culture).PadRight(n, ' ')}; HandleType");
            builder.AppendLine($"{train.Handle.PowerNotches.ToString(culture).PadRight(n, ' ')}; PowerNotches");
            builder.AppendLine($"{train.Handle.BrakeNotches.ToString(culture).PadRight(n, ' ')}; BrakeNotches");
            builder.AppendLine($"{train.Handle.PowerNotchReduceSteps.ToString(culture).PadRight(n, ' ')}; PowerNotchReduceSteps");
            builder.AppendLine($"{((int)train.Handle.HandleBehaviour).ToString(culture).PadRight(n, ' ')}; EbHandleBehaviour (1.5.3.3+)");
            builder.AppendLine($"{train.Handle.LocoBrakeNotches.ToString(culture).PadRight(n, ' ')}; LocoBrakeNotches (1.5.3.4+)");
            builder.AppendLine($"{((int)train.Handle.LocoBrake).ToString(culture).PadRight(n, ' ')}; LocoBrakeType (1.5.3.4+)");
            builder.AppendLine($"{train.Handle.DriverPowerNotches.ToString(culture).PadRight(n, ' ')}; DriverPowerNotches (1.5.3.11+)");
            builder.AppendLine($"{train.Handle.DriverBrakeNotches.ToString(culture).PadRight(n, ' ')}; DriverBrakeNotches (1.5.3.11+)");

            builder.AppendLine("#CAB");
            builder.AppendLine($"{train.Cab.PositionX.ToString(culture).PadRight(n, ' ')}; X");
            builder.AppendLine($"{train.Cab.PositionY.ToString(culture).PadRight(n, ' ')}; Y");
            builder.AppendLine($"{train.Cab.PositionZ.ToString(culture).PadRight(n, ' ')}; Z");
            builder.AppendLine($"{train.Cab.DriverCar.ToString(culture).PadRight(n, ' ')}; DriverCar");

            builder.AppendLine("#CAR");
            builder.AppendLine($"{firstMotorCar.Mass.ToString(culture).PadRight(n, ' ')}; MotorCarMass");
            builder.AppendLine($"{train.Cars.Count(c => c is MotorCar).ToString(culture).PadRight(n, ' ')}; NumberOfMotorCars");
            builder.AppendLine($"{(firstTrailerCar ?? new TrailerCar()).Mass.ToString(culture).PadRight(n, ' ')}; TrailerCarMass");
            builder.AppendLine($"{train.Cars.Count(c => c is TrailerCar).ToString(culture).PadRight(n, ' ')}; NumberOfTrailerCars");
            builder.AppendLine($"{firstMotorCar.Length.ToString(culture).PadRight(n, ' ')}; LengthOfACar");
            builder.AppendLine($"{(train.Cars.First() is MotorCar ? "1" : "0").PadRight(n, ' ')}; FrontCarIsAMotorCar");
            builder.AppendLine($"{firstMotorCar.Width.ToString(culture).PadRight(n, ' ')}; WidthOfACar");
            builder.AppendLine($"{firstMotorCar.Height.ToString(culture).PadRight(n, ' ')}; HeightOfACar");
            builder.AppendLine($"{firstMotorCar.CenterOfGravityHeight.ToString(culture).PadRight(n, ' ')}; CenterOfGravityHeight");
            builder.AppendLine($"{firstMotorCar.ExposedFrontalArea.ToString(culture).PadRight(n, ' ')}; ExposedFrontalArea");
            builder.AppendLine($"{firstMotorCar.UnexposedFrontalArea.ToString(culture).PadRight(n, ' ')}; UnexposedFrontalArea");

            builder.AppendLine("#DEVICE");
            builder.AppendLine($"{((int)train.Device.Ats).ToString(culture).PadRight(n, ' ')}; Ats");
            builder.AppendLine($"{((int)train.Device.Atc).ToString(culture).PadRight(n, ' ')}; Atc");
            builder.AppendLine($"{(train.Device.Eb ? "1" : "0").PadRight(n, ' ')}; Eb");
            builder.AppendLine($"{(train.Device.ConstSpeed ? "1" : "0").PadRight(n, ' ')}; ConstSpeed");
            builder.AppendLine($"{(train.Device.HoldBrake ? "1" : "0").PadRight(n, ' ')}; HoldBrake");
            builder.AppendLine($"{((int)train.Device.ReAdhesionDevice).ToString(culture).PadRight(n, ' ')}; ReAdhesionDevice");
            builder.AppendLine($"{train.Device.LoadCompensatingDevice.ToString(culture).PadRight(n, ' ')}; Reserved (not used)");
            builder.AppendLine($"{((int)train.Device.PassAlarm).ToString(culture).PadRight(n, ' ')}; PassAlarm");
            builder.AppendLine($"{((int)train.Device.DoorOpenMode).ToString(culture).PadRight(n, ' ')}; DoorOpenMode");
            builder.AppendLine($"{((int)train.Device.DoorCloseMode).ToString(culture).PadRight(n, ' ')}; DoorCloseMode");
            builder.AppendLine($"{train.Device.DoorWidth.ToString(culture).PadRight(n, ' ')}; DoorWidth");
            builder.AppendLine($"{train.Device.DoorMaxTolerance.ToString(culture).PadRight(n, ' ')}; DoorMaxTolerance");

            for (int i = 0; i < 4; i++)
            {
                BVEMotorSoundTableEntry[] entries = new BVEMotorSoundTableEntry[0];

                switch (i)
                {
                case 0:
                    builder.AppendLine("#MOTOR_P1");
                    entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Power1]);
                    break;

                case 1:
                    builder.AppendLine("#MOTOR_P2");
                    entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Power2]);
                    break;

                case 2:
                    builder.AppendLine("#MOTOR_B1");
                    entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Brake1]);
                    break;

                case 3:
                    builder.AppendLine("#MOTOR_B2");
                    entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Brake2]);
                    break;
                }

                int k;

                for (k = entries.Length - 1; k >= 0; k--)
                {
                    if (entries[k].SoundIndex >= 0)
                    {
                        break;
                    }
                }

                k = Math.Min(k + 2, entries.Length);
                Array.Resize(ref entries, k);

                for (int j = 0; j < entries.Length; j++)
                {
                    builder.Append(entries[j].SoundIndex.ToString(culture) + ",");
                    builder.Append(entries[j].Pitch.ToString(culture) + ",");
                    builder.AppendLine(entries[j].Gain.ToString(culture));
                }
            }

            File.WriteAllText(fileName, builder.ToString(), new UTF8Encoding(true));
        }
示例#2
0
        internal static void Parse(string fileName, out Train train)
        {
            train = new Train();

            CultureInfo culture = CultureInfo.InvariantCulture;

            string[] lines = File.ReadAllLines(fileName, TextEncoding.GetSystemEncodingFromFile(fileName));

            for (int i = 0; i < lines.Length; i++)
            {
                int j = lines[i].IndexOf(';');

                if (j >= 0)
                {
                    lines[i] = lines[i].Substring(0, j).Trim();
                }
                else
                {
                    lines[i] = lines[i].Trim();
                }
            }

            bool ver1220000 = false;

            foreach (string line in lines)
            {
                if (line.Length != 0)
                {
                    string s = line.ToLowerInvariant();

                    switch (s)
                    {
                    case "bve1200000":
                    case "bve1210000":
                    case "bve1220000":
                        ver1220000 = true;
                        break;

                    case "bve2000000":
                    case "openbve":
                        //No action
                        break;

                    default:
                        if (s.ToLowerInvariant().StartsWith("openbve"))
                        {
                            string tt = s.Substring(7, s.Length - 7);
                            int    v;

                            if (int.TryParse(tt, NumberStyles.Float, culture, out v))
                            {
                                if (v > currentVersion)
                                {
                                    Interface.AddMessage(MessageType.Warning, false, $"The train.dat {fileName} was created with a newer version of openBVE. Please check for an update.");
                                }
                            }
                            else
                            {
                                Interface.AddMessage(MessageType.Error, false, $"The train.dat version {lines[0].ToLowerInvariant()} is invalid in {fileName}");
                            }
                        }

                        break;
                    }

                    break;
                }
            }

            Acceleration acceleration = new Acceleration();
            Performance  performance  = new Performance();
            Delay        delay        = new Delay();
            Move         move         = new Move();
            Brake        brake        = new Brake();
            Pressure     pressure     = new Pressure();
            Motor        motor        = new Motor();

            double motorCarMass          = 40.0;
            int    numberOfMotorCars     = 1;
            double trailerCarMass        = 40.0;
            int    numberOfTrailerCars   = 1;
            double lengthOfACar          = 20.0;
            bool   frontCarIsAMotorCar   = false;
            double widthOfACar           = 2.6;
            double heightOfACar          = 3.2;
            double centerOfGravityHeight = 1.5;
            double exposedFrontalArea    = 5.0;
            double unexposedFrontalArea  = 1.6;

            for (int i = 0; i < lines.Length; i++)
            {
                int n = 0;

                switch (lines[i].ToLowerInvariant())
                {
                case "#acceleration":
                    i++;

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (n == acceleration.Entries.Count)
                        {
                            acceleration.Entries.Add(new Acceleration.Entry());
                        }

                        string u = lines[i] + ",";
                        int    m = 0;

                        while (true)
                        {
                            int j = u.IndexOf(',');

                            if (j == -1)
                            {
                                break;
                            }

                            string s = u.Substring(0, j).Trim();
                            u = u.Substring(j + 1);
                            double a;

                            if (double.TryParse(s, NumberStyles.Float, culture, out a))
                            {
                                switch (m)
                                {
                                case 0:
                                    acceleration.Entries[n].A0 = Math.Max(a, 0.0);
                                    break;

                                case 1:
                                    acceleration.Entries[n].A1 = Math.Max(a, 0.0);
                                    break;

                                case 2:
                                    acceleration.Entries[n].V1 = Math.Max(a, 0.0);
                                    break;

                                case 3:
                                    acceleration.Entries[n].V2 = Math.Max(a, 0.0);

                                    if (acceleration.Entries[n].V2 < acceleration.Entries[n].V1)
                                    {
                                        double x = acceleration.Entries[n].V1;
                                        acceleration.Entries[n].V1 = acceleration.Entries[n].V2;
                                        acceleration.Entries[n].V2 = x;
                                    }

                                    break;

                                case 4:
                                    if (ver1220000)
                                    {
                                        if (a <= 0.0)
                                        {
                                            acceleration.Entries[n].E = 1.0;
                                        }
                                        else
                                        {
                                            const double c = 1.23315173118822;
                                            acceleration.Entries[n].E = 1.0 - Math.Log(a) * acceleration.Entries[n].V2 * c;

                                            if (acceleration.Entries[n].E > 4.0)
                                            {
                                                acceleration.Entries[n].E = 4.0;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        acceleration.Entries[n].E = a;
                                    }

                                    break;
                                }
                            }

                            m++;
                        }

                        i++;
                        n++;
                    }

                    i--;
                    break;

                case "#performance":
                case "#deceleration":
                    i++;

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        double a;

                        if (double.TryParse(lines[i], NumberStyles.Float, culture, out a))
                        {
                            switch (n)
                            {
                            case 0:
                                if (a >= 0.0)
                                {
                                    performance.Deceleration = a;
                                }

                                break;

                            case 1:
                                if (a >= 0.0)
                                {
                                    performance.CoefficientOfStaticFriction = a;
                                }

                                break;

                            case 3:
                                if (a >= 0.0)
                                {
                                    performance.CoefficientOfRollingResistance = a;
                                }

                                break;

                            case 4:
                                if (a >= 0.0)
                                {
                                    performance.AerodynamicDragCoefficient = a;
                                }

                                break;
                            }
                        }

                        i++;
                        n++;
                    }

                    i--;
                    break;

                case "#delay":
                    i++;

                    double[] delayPowerUp       = delay.DelayPower.Select(x => x.Up).ToArray();
                    double[] delayPowerDown     = delay.DelayPower.Select(x => x.Down).ToArray();
                    double[] delayBrakeUp       = delay.DelayBrake.Select(x => x.Up).ToArray();
                    double[] delayBrakeDown     = delay.DelayBrake.Select(x => x.Down).ToArray();
                    double[] delayLocoBrakeUp   = delay.DelayLocoBrake.Select(x => x.Up).ToArray();
                    double[] delayLocoBrakeDown = delay.DelayLocoBrake.Select(x => x.Down).ToArray();

                    delay.DelayPower.Clear();
                    delay.DelayBrake.Clear();
                    delay.DelayLocoBrake.Clear();

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        double a;

                        if (double.TryParse(lines[i], NumberStyles.Float, culture, out a))
                        {
                            switch (n)
                            {
                            case 0:
                                if (a >= 0.0)
                                {
                                    delayPowerUp = new[] { a };
                                }

                                break;

                            case 1:
                                if (a >= 0.0)
                                {
                                    delayPowerDown = new[] { a };
                                }

                                break;

                            case 2:
                                if (a >= 0.0)
                                {
                                    delayBrakeUp = new[] { a };
                                }

                                break;

                            case 3:
                                if (a >= 0.0)
                                {
                                    delayBrakeDown = new[] { a };
                                }

                                break;
                            }
                        }
                        else if (lines[i].IndexOf(',') != -1)
                        {
                            switch (n)
                            {
                            case 0:
                                delayPowerUp = lines[i].Split(',').Select(x => double.Parse(x, culture)).ToArray();
                                break;

                            case 1:
                                delayPowerDown = lines[i].Split(',').Select(x => double.Parse(x, culture)).ToArray();
                                break;

                            case 2:
                                delayBrakeUp = lines[i].Split(',').Select(x => double.Parse(x, culture)).ToArray();
                                break;

                            case 3:
                                delayBrakeDown = lines[i].Split(',').Select(x => double.Parse(x, culture)).ToArray();
                                break;

                            case 4:
                                delayLocoBrakeUp = lines[i].Split(',').Select(x => double.Parse(x, culture)).ToArray();
                                break;

                            case 5:
                                delayLocoBrakeDown = lines[i].Split(',').Select(x => double.Parse(x, culture)).ToArray();
                                break;
                            }
                        }

                        i++;
                        n++;
                    }

                    for (int j = 0; j < Math.Max(delayPowerUp.Length, delayPowerDown.Length); j++)
                    {
                        Delay.Entry entry = new Delay.Entry();

                        if (j < delayPowerUp.Length)
                        {
                            entry.Up = delayPowerUp[j];
                        }

                        if (j < delayPowerDown.Length)
                        {
                            entry.Down = delayPowerDown[j];
                        }

                        delay.DelayPower.Add(entry);
                    }

                    for (int j = 0; j < Math.Max(delayBrakeUp.Length, delayBrakeDown.Length); j++)
                    {
                        Delay.Entry entry = new Delay.Entry();

                        if (j < delayBrakeUp.Length)
                        {
                            entry.Up = delayBrakeUp[j];
                        }

                        if (j < delayBrakeDown.Length)
                        {
                            entry.Down = delayBrakeDown[j];
                        }

                        delay.DelayBrake.Add(entry);
                    }

                    for (int j = 0; j < Math.Max(delayLocoBrakeUp.Length, delayLocoBrakeDown.Length); j++)
                    {
                        Delay.Entry entry = new Delay.Entry();

                        if (j < delayLocoBrakeUp.Length)
                        {
                            entry.Up = delayLocoBrakeUp[j];
                        }

                        if (j < delayLocoBrakeDown.Length)
                        {
                            entry.Down = delayLocoBrakeDown[j];
                        }

                        delay.DelayLocoBrake.Add(entry);
                    }

                    i--;
                    break;

                case "#move":
                    i++;

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        double a;

                        if (double.TryParse(lines[i], NumberStyles.Float, culture, out a))
                        {
                            switch (n)
                            {
                            case 0:
                                if (a >= 0.0)
                                {
                                    move.JerkPowerUp = a;
                                }

                                break;

                            case 1:
                                if (a >= 0.0)
                                {
                                    move.JerkPowerDown = a;
                                }

                                break;

                            case 2:
                                if (a >= 0.0)
                                {
                                    move.JerkBrakeUp = a;
                                }

                                break;

                            case 3:
                                if (a >= 0.0)
                                {
                                    move.JerkBrakeDown = a;
                                }

                                break;

                            case 4:
                                if (a >= 0.0)
                                {
                                    move.BrakeCylinderUp = a;
                                }

                                break;

                            case 5:
                                if (a >= 0.0)
                                {
                                    move.BrakeCylinderDown = a;
                                }

                                break;
                            }
                        }

                        i++;
                        n++;
                    }

                    i--;
                    break;

                case "#brake":
                    i++;

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        double a;

                        if (double.TryParse(lines[i], NumberStyles.Float, culture, out a))
                        {
                            int b = (int)Math.Round(a);

                            switch (n)
                            {
                            case 0:
                                if (b >= 0 & b <= 2)
                                {
                                    brake.BrakeType = (BrakeSystemType)b;
                                }

                                break;

                            case 1:
                                if (b >= 0 & b <= 2)
                                {
                                    brake.BrakeControlSystem = (EletropneumaticBrakeType)b;
                                }

                                break;

                            case 2:
                                if (a >= 0.0)
                                {
                                    brake.BrakeControlSpeed = a;
                                }

                                break;

                            case 3:
                                if (a <= 0 && a > 3)
                                {
                                    brake.LocoBrakeType = (Brake.LocoBrakeTypes)b;
                                }

                                break;
                            }
                        }

                        i++;
                        n++;
                    }

                    i--;
                    break;

                case "#pressure":
                    i++;

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        double a;

                        if (double.TryParse(lines[i], NumberStyles.Float, culture, out a))
                        {
                            switch (n)
                            {
                            case 0:
                                if (a > 0.0)
                                {
                                    pressure.BrakeCylinderServiceMaximumPressure = a;
                                }

                                break;

                            case 1:
                                if (a > 0.0)
                                {
                                    pressure.BrakeCylinderEmergencyMaximumPressure = a;
                                }

                                break;

                            case 2:
                                if (a > 0.0)
                                {
                                    pressure.MainReservoirMinimumPressure = a;
                                }

                                break;

                            case 3:
                                if (a > 0.0)
                                {
                                    pressure.MainReservoirMaximumPressure = a;
                                }

                                break;

                            case 4:
                                if (a > 0.0)
                                {
                                    pressure.BrakePipeNormalPressure = a;
                                }

                                break;
                            }
                        }

                        i++;
                        n++;
                    }

                    i--;
                    break;

                case "#handle":
                    i++;

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        double a;

                        if (double.TryParse(lines[i], NumberStyles.Float, culture, out a))
                        {
                            int b = (int)Math.Round(a);

                            switch (n)
                            {
                            case 0:
                                if (b == 0 | b == 1)
                                {
                                    train.Handle.HandleType = (Handle.HandleTypes)b;
                                }

                                break;

                            case 1:
                                if (b > 0)
                                {
                                    train.Handle.PowerNotches = b;
                                }

                                break;

                            case 2:
                                if (b > 0)
                                {
                                    train.Handle.BrakeNotches = b;
                                }

                                break;

                            case 3:
                                if (b >= 0)
                                {
                                    train.Handle.PowerNotchReduceSteps = b;
                                }

                                break;

                            case 4:
                                if (a >= 0 && a < 4)
                                {
                                    train.Handle.HandleBehaviour = (EbHandleBehaviour)b;
                                }

                                break;

                            case 5:
                                if (b > 0)
                                {
                                    train.Handle.LocoBrakeNotches = b;
                                }

                                break;

                            case 6:
                                if (a <= 0 && a > 3)
                                {
                                    train.Handle.LocoBrake = (LocoBrakeType)b;
                                }

                                break;

                            case 7:
                                if (b > 0)
                                {
                                    train.Handle.DriverPowerNotches = b;
                                }

                                break;

                            case 8:
                                if (b > 0)
                                {
                                    train.Handle.DriverBrakeNotches = b;
                                }

                                break;
                            }
                        }

                        i++;
                        n++;
                    }

                    i--;
                    break;

                case "#cockpit":
                case "#cab":
                    i++;

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        double a;

                        if (double.TryParse(lines[i], NumberStyles.Float, culture, out a))
                        {
                            switch (n)
                            {
                            case 0:
                                train.Cab.PositionX = a;
                                break;

                            case 1:
                                train.Cab.PositionY = a;
                                break;

                            case 2:
                                train.Cab.PositionZ = a;
                                break;

                            case 3:
                                train.Cab.DriverCar = (int)Math.Round(a);
                                break;
                            }
                        }

                        i++;
                        n++;
                    }

                    i--;
                    break;

                case "#car":
                    i++;

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        double a;

                        if (double.TryParse(lines[i], NumberStyles.Float, culture, out a))
                        {
                            int b = (int)Math.Round(a);

                            switch (n)
                            {
                            case 0:
                                if (a > 0.0)
                                {
                                    motorCarMass = a;
                                }

                                break;

                            case 1:
                                if (b >= 1)
                                {
                                    numberOfMotorCars = b;
                                }

                                break;

                            case 2:
                                if (a > 0.0)
                                {
                                    trailerCarMass = a;
                                }

                                break;

                            case 3:
                                if (b >= 0)
                                {
                                    numberOfTrailerCars = b;
                                }

                                break;

                            case 4:
                                if (b > 0.0)
                                {
                                    lengthOfACar = a;
                                }

                                break;

                            case 5:
                                frontCarIsAMotorCar = a == 1.0;
                                break;

                            case 6:
                                if (a > 0.0)
                                {
                                    widthOfACar = a;
                                }

                                break;

                            case 7:
                                if (a > 0.0)
                                {
                                    heightOfACar = a;
                                }

                                break;

                            case 8:
                                centerOfGravityHeight = a;
                                break;

                            case 9:
                                if (a > 0.0)
                                {
                                    exposedFrontalArea = a;
                                }

                                break;

                            case 10:
                                if (a > 0.0)
                                {
                                    unexposedFrontalArea = a;
                                }

                                break;
                            }
                        }

                        i++;
                        n++;
                    }

                    i--;
                    break;

                case "#device":
                    i++;

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        double a;

                        if (double.TryParse(lines[i], NumberStyles.Float, culture, out a))
                        {
                            int b = (int)Math.Round(a);

                            switch (n)
                            {
                            case 0:
                                if (b >= -1 & b <= 1)
                                {
                                    train.Device.Ats = (AtsModes)b;
                                }

                                break;

                            case 1:
                                if (b >= 0 & b <= 2)
                                {
                                    train.Device.Atc = (AtcModes)b;
                                }

                                break;

                            case 2:
                                train.Device.Eb = a == 1.0;
                                break;

                            case 3:
                                train.Device.ConstSpeed = a == 1.0;
                                break;

                            case 4:
                                train.Device.HoldBrake = a == 1.0;
                                break;

                            case 5:
                                if (b >= -1 & b <= 3)
                                {
                                    train.Device.ReAdhesionDevice = (ReadhesionDeviceType)b;
                                }

                                break;

                            case 6:
                                train.Device.LoadCompensatingDevice = a;
                                break;

                            case 7:
                                if (b >= 0 & b <= 2)
                                {
                                    train.Device.PassAlarm = (PassAlarmType)b;
                                }

                                break;

                            case 8:
                                if (b >= 0 & b <= 2)
                                {
                                    train.Device.DoorOpenMode = (DoorMode)b;
                                }

                                break;

                            case 9:
                                if (b >= 0 & b <= 2)
                                {
                                    train.Device.DoorCloseMode = (DoorMode)b;
                                }

                                break;

                            case 10:
                                if (a >= 0.0)
                                {
                                    train.Device.DoorWidth = a;
                                }

                                break;

                            case 11:
                                if (a >= 0.0)
                                {
                                    train.Device.DoorMaxTolerance = a;
                                }

                                break;
                            }
                        }

                        i++;
                        n++;
                    }

                    i--;
                    break;

                case "#motor_p1":
                case "#motor_p2":
                case "#motor_b1":
                case "#motor_b2":
                {
                    string section = lines[i].ToLowerInvariant();
                    i++;
                    BVEMotorSoundTableEntry[] entries = new BVEMotorSoundTableEntry[800];

                    while (i < lines.Length && !lines[i].StartsWith("#", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (n == entries.Length)
                        {
                            Array.Resize(ref entries, entries.Length << 1);
                        }

                        string u = lines[i] + ",";
                        int    k = 0;

                        while (true)
                        {
                            int j = u.IndexOf(',');

                            if (j == -1)
                            {
                                break;
                            }

                            string s = u.Substring(0, j).Trim();
                            u = u.Substring(j + 1);
                            double a;

                            if (double.TryParse(s, NumberStyles.Float, culture, out a))
                            {
                                int b = (int)Math.Round(a);

                                switch (k)
                                {
                                case 0:
                                    entries[n].SoundIndex = b >= 0 ? b : -1;
                                    break;

                                case 1:
                                    entries[n].Pitch = (float)Math.Max(a, 0.0);
                                    break;

                                case 2:
                                    entries[n].Gain = (float)Math.Max(a, 0.0);
                                    break;
                                }
                            }

                            k++;
                        }

                        i++;
                        n++;
                    }

                    Array.Resize(ref entries, n);
                    i--;

                    switch (section)
                    {
                    case "#motor_p1":
                        motor.Tracks[(int)Motor.TrackInfo.Power1] = Motor.Track.EntriesToTrack(entries);
                        break;

                    case "#motor_p2":
                        motor.Tracks[(int)Motor.TrackInfo.Power2] = Motor.Track.EntriesToTrack(entries);
                        break;

                    case "#motor_b1":
                        motor.Tracks[(int)Motor.TrackInfo.Brake1] = Motor.Track.EntriesToTrack(entries);
                        break;

                    case "#motor_b2":
                        motor.Tracks[(int)Motor.TrackInfo.Brake2] = Motor.Track.EntriesToTrack(entries);
                        break;
                    }
                }
                break;
                }
            }

            int numberOfCars = numberOfMotorCars + numberOfTrailerCars;

            bool[] isMotorCars = new bool[numberOfCars];
            if (numberOfMotorCars == 1)
            {
                if (frontCarIsAMotorCar | numberOfTrailerCars == 0)
                {
                    isMotorCars[0] = true;
                }
                else
                {
                    isMotorCars[numberOfCars - 1] = true;
                }
            }
            else if (numberOfMotorCars == 2)
            {
                if (frontCarIsAMotorCar | numberOfTrailerCars == 0)
                {
                    isMotorCars[0] = true;
                    isMotorCars[numberOfCars - 1] = true;
                }
                else if (numberOfTrailerCars == 1)
                {
                    isMotorCars[1] = true;
                    isMotorCars[2] = true;
                }
                else
                {
                    int i = (int)Math.Ceiling(0.25 * (numberOfCars - 1));
                    int j = (int)Math.Floor(0.75 * (numberOfCars - 1));
                    isMotorCars[i] = true;
                    isMotorCars[j] = true;
                }
            }
            else if (numberOfMotorCars > 0)
            {
                if (frontCarIsAMotorCar)
                {
                    isMotorCars[0] = true;
                    double t = 1.0 + numberOfTrailerCars / (double)(numberOfMotorCars - 1);
                    double r = 0.0;
                    double x = 0.0;

                    while (true)
                    {
                        double y = x + t - r;
                        x = Math.Ceiling(y);
                        r = x - y;
                        int i = (int)x;

                        if (i >= numberOfCars)
                        {
                            break;
                        }

                        isMotorCars[i] = true;
                    }
                }
                else
                {
                    isMotorCars[1] = true;
                    double t = 1.0 + (numberOfTrailerCars - 1) / (double)(numberOfMotorCars - 1);
                    double r = 0.0;
                    double x = 1.0;

                    while (true)
                    {
                        double y = x + t - r;
                        x = Math.Ceiling(y);
                        r = x - y;
                        int i = (int)x;

                        if (i >= numberOfCars)
                        {
                            break;
                        }

                        isMotorCars[i] = true;
                    }
                }
            }

            foreach (bool isMotorCar in isMotorCars)
            {
                Car car = isMotorCar ? (Car) new MotorCar() : new TrailerCar();

                car.Mass   = isMotorCar ? motorCarMass : trailerCarMass;
                car.Length = lengthOfACar;
                car.Width  = widthOfACar;
                car.Height = heightOfACar;
                car.CenterOfGravityHeight = centerOfGravityHeight;
                car.ExposedFrontalArea    = exposedFrontalArea;
                car.UnexposedFrontalArea  = unexposedFrontalArea;
                car.Performance           = (Performance)performance.Clone();
                car.Delay    = (Delay)delay.Clone();
                car.Move     = (Move)move.Clone();
                car.Brake    = (Brake)brake.Clone();
                car.Pressure = (Pressure)pressure.Clone();

                if (isMotorCar)
                {
                    ((MotorCar)car).Acceleration = (Acceleration)acceleration.Clone();
                    ((MotorCar)car).Motor        = (Motor)motor.Clone();
                }

                train.Cars.Add(car);
            }

            for (int i = 0; i < numberOfCars - 1; i++)
            {
                train.Couplers.Add(new Models.Trains.Coupler());
            }
        }