private void PreRender() { objectStates.Clear(); touchFaces.Clear(); if (!Loading.SimulationSetup) { return; } if (renderer.Camera.CurrentMode != CameraViewMode.Interior && renderer.Camera.CurrentMode != CameraViewMode.InteriorLookAhead) { return; } TrainManager.Car Car = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar]; int add = Car.CarSections[0].CurrentAdditionalGroup + 1; if (add >= Car.CarSections[0].Groups.Length) { return; } TrainManager.TouchElement[] TouchElements = Car.CarSections[0].Groups[add].TouchElements; if (TouchElements == null) { return; } foreach (TrainManager.TouchElement element in TouchElements) { ShowObject(element.Element.internalObject); } }
/// <summary>Loads the sound set for a BVE2 based train</summary> /// <param name="trainFolder">The absolute on-disk path to the train's folder</param> /// <param name="car">The car</param> internal static void Parse(string trainFolder, TrainManager.Car car) { // set sound positions and radii Vector3 center = Vector3.Zero; // load sounds for all cars car.Sounds.Run = SoundCfgParser.TryLoadSoundArray(trainFolder, "Run", ".wav", center, SoundCfgParser.mediumRadius); car.Sounds.RunVolume = new double[car.Sounds.Run.Length]; // motor sound CultureInfo Culture = CultureInfo.InvariantCulture; car.Sounds.Motor.Position = center; for (int j = 0; j < car.Sounds.Motor.Tables.Length; j++) { for (int k = 0; k < car.Sounds.Motor.Tables[j].Entries.Length; k++) { int idx = car.Sounds.Motor.Tables[j].Entries[k].SoundIndex; if (idx >= 0) { CarSound snd = new CarSound(Program.Sounds.RegisterBuffer(OpenBveApi.Path.CombineFile(trainFolder, "Motor" + idx.ToString(Culture) + ".wav"), SoundCfgParser.mediumRadius), center); car.Sounds.Motor.Tables[j].Entries[k].Buffer = snd.Buffer; } } } }
internal bool MoveCheck(Vector2 Point, out Cursor.Status Status) { if (!Loading.SimulationSetup) { Status = Cursor.Status.Default; return(false); } if (renderer.Camera.CurrentMode != CameraViewMode.Interior && renderer.Camera.CurrentMode != CameraViewMode.InteriorLookAhead) { Status = Cursor.Status.Default; return(false); } Status = Cursor.Status.Default; TrainManager.Car Car = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar]; int add = Car.CarSections[0].CurrentAdditionalGroup + 1; if (add >= Car.CarSections[0].Groups.Length) { return(false); } TrainManager.TouchElement[] TouchElements = Car.CarSections[0].Groups[add].TouchElements; if (TouchElements == null) { return(false); } ObjectState pickedObject = ParseFBO(Point, 5, 5); foreach (TrainManager.TouchElement TouchElement in TouchElements) { if (TouchElement.Element.internalObject != pickedObject) { continue; } switch (TouchElement.Command) { case Translations.Command.PowerIncrease: case Translations.Command.BrakeIncrease: case Translations.Command.ReverserForward: Status = Cursor.Status.Plus; break; case Translations.Command.PowerDecrease: case Translations.Command.BrakeDecrease: case Translations.Command.ReverserBackward: Status = Cursor.Status.Minus; break; } } return(pickedObject != null); }
internal void LeaveCheck(Vector2 Point) { if (!Loading.SimulationSetup) { return; } if (renderer.Camera.CurrentMode != CameraViewMode.Interior && renderer.Camera.CurrentMode != CameraViewMode.InteriorLookAhead) { return; } TrainManager.Car Car = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar]; int add = Car.CarSections[0].CurrentAdditionalGroup + 1; if (add >= Car.CarSections[0].Groups.Length) { return; } TrainManager.TouchElement[] TouchElements = Car.CarSections[0].Groups[add].TouchElements; if (TouchElements == null) { return; } ObjectState pickedObject = ParseFBO(Point, 5, 5); foreach (TrainManager.TouchElement TouchElement in TouchElements) { if (TouchElement.Element.internalObject == pickedObject) { Car.CarSections[0].CurrentAdditionalGroup = TouchElement.JumpScreenIndex; Car.ChangeCarSection(TrainManager.CarSectionType.Interior); foreach (var index in TouchElement.SoundIndices.Where(x => x >= 0 && x < Car.Sounds.Touch.Length)) { SoundBuffer Buffer = Car.Sounds.Touch[index].Buffer; OpenBveApi.Math.Vector3 Position = Car.Sounds.Touch[index].Position; Program.Sounds.PlaySound(Buffer, 1.0, 1.0, Position, TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar], false); } } // HACK: Normally terminate the command issued once. if (TouchElement.Element.internalObject == pickedObject || (pickedObject != prePickedObject && TouchElement.Element.internalObject == prePickedObject)) { foreach (int index in TouchElement.ControlIndices) { Interface.CurrentControls[index].AnalogState = 0.0; Interface.CurrentControls[index].DigitalState = Interface.DigitalControlState.Released; MainLoop.RemoveControlRepeat(index); } } } }
internal bool MoveCheck(Vector2 Point, out Cursor.Status Status) { if (!Loading.SimulationSetup) { Status = Cursor.Status.Default; return(false); } if (renderer.Camera.CurrentMode != CameraViewMode.Interior && renderer.Camera.CurrentMode != CameraViewMode.InteriorLookAhead) { Status = Cursor.Status.Default; return(false); } Status = Cursor.Status.Default; TrainManager.Car Car = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar]; int add = Car.CarSections[0].CurrentAdditionalGroup + 1; if (add >= Car.CarSections[0].Groups.Length) { return(false); } TouchElement[] TouchElements = Car.CarSections[0].Groups[add].TouchElements; if (TouchElements == null) { return(false); } ObjectState pickedObject = renderer.AvailableNewRenderer ? ParseFBO(Point, 5, 5) : RenderSceneSelection(Point, new Vector2(5.0f)); foreach (TouchElement TouchElement in TouchElements.Where(x => x.Element.internalObject == pickedObject)) { foreach (int index in TouchElement.ControlIndices) { switch (Interface.CurrentControls[index].Command) { case Translations.Command.PowerIncrease: case Translations.Command.BrakeIncrease: case Translations.Command.ReverserForward: Status = Cursor.Status.Plus; break; case Translations.Command.PowerDecrease: case Translations.Command.BrakeDecrease: case Translations.Command.ReverserBackward: Status = Cursor.Status.Minus; break; } } } return(pickedObject != null); }
internal static bool ParseTrain(string fileName, TrainManager.Car car) { try { Parse(fileName, car); } catch { return(false); } return(true); }
internal static void Parse(string fileName, TrainManager.Car car) { //3D center of the car Vector3 center = Vector3.Zero; //The current XML file to load XmlDocument currentXML = new XmlDocument(); //Load the marker's XML file currentXML.Load(fileName); currentPath = Path.GetDirectoryName(fileName); if (currentXML.DocumentElement != null) { XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/CarSounds"); if (DocumentNodes == null || DocumentNodes.Count == 0) { //If we have no appropriate nodes specified, return false and fallback to loading the legacy Sound.cfg file throw new Exception("Empty sound.xml file"); } foreach (XmlNode n in DocumentNodes) { if (n.ChildNodes.OfType <XmlElement>().Any()) { foreach (XmlNode c in n.ChildNodes) { switch (c.Name.ToLowerInvariant()) { case "motor": ParseMotorSoundTableNode(c, ref car.Sounds.Motor.Tables, center, SoundCfgParser.mediumRadius); break; case "run": if (!c.ChildNodes.OfType <XmlElement>().Any()) { break; } ParseArrayNode(c, out car.Sounds.Run, center, SoundCfgParser.mediumRadius); break; } } } } car.Sounds.RunVolume = new double[car.Sounds.Run.Length]; } }
internal void TouchCheck(Vector2 Point) { if (!Loading.SimulationSetup) { return; } if (renderer.Camera.CurrentMode != CameraViewMode.Interior && renderer.Camera.CurrentMode != CameraViewMode.InteriorLookAhead) { return; } TrainManager.Car Car = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar]; int add = Car.CarSections[0].CurrentAdditionalGroup + 1; if (add >= Car.CarSections[0].Groups.Length) { return; } TrainManager.TouchElement[] TouchElements = Car.CarSections[0].Groups[add].TouchElements; if (TouchElements == null) { return; } ObjectState pickedObject = ParseFBO(Point, 5, 5); foreach (TrainManager.TouchElement TouchElement in TouchElements.Where(x => x.Element.internalObject == pickedObject)) { foreach (int index in TouchElement.ControlIndices) { Interface.CurrentControls[index].AnalogState = 1.0; Interface.CurrentControls[index].DigitalState = Interface.DigitalControlState.Pressed; MainLoop.AddControlRepeat(index); } } prePickedObject = pickedObject; }
/// <summary>Parses the sound configuration file for a train</summary> /// <param name="TrainPath">The absolute on-disk path to the train's folder</param> /// <param name="Encoding">The train's text encoding</param> /// <param name="Car">The car to which to apply the new sound configuration</param> internal static void ParseSoundConfig(string TrainPath, Encoding Encoding, TrainManager.Car Car) { Car.InitializeCarSounds(); string FileName = OpenBveApi.Path.CombineFile(TrainPath, "sound.xml"); if (File.Exists(FileName)) { if (SoundXmlParser.ParseTrain(FileName, Car)) { return; } } FileName = OpenBveApi.Path.CombineFile(TrainPath, "sound.cfg"); if (File.Exists(FileName)) { BVE4SoundParser.Parse(FileName, TrainPath, Encoding, Car); } else { BVE2SoundParser.Parse(TrainPath, Car); } }
/// <summary>Loads the sound set for a BVE4 or openBVE sound.cfg based train</summary> /// <param name="FileName">The absolute on-disk path to the sound.cfg file</param> /// <param name="trainFolder">The absolute on-disk path to the train's folder</param> /// <param name="Encoding">The text encoding for the sound.cfg file</param> /// <param name="car">The car</param> internal static void Parse(string FileName, string trainFolder, Encoding Encoding, TrainManager.Car car) { //Default sound positions and radii //3D center of the car Vector3 center = Vector3.Zero; // parse configuration file CultureInfo Culture = CultureInfo.InvariantCulture; List <string> Lines = File.ReadAllLines(FileName, Encoding).ToList(); for (int i = Lines.Count - 1; i >= 0; i--) { /* * Strip comments and remove empty resulting lines etc. * * This fixes an error with some NYCTA content, which has * a copyright notice instead of the file header specified.... */ int j = Lines[i].IndexOf(';'); if (j >= 0) { Lines[i] = Lines[i].Substring(0, j).Trim(); } else { Lines[i] = Lines[i].Trim(); } if (string.IsNullOrEmpty(Lines[i])) { Lines.RemoveAt(i); } } string[] MotorFiles = new string[] { }; for (int i = 0; i < Lines.Count; i++) { switch (Lines[i].ToLowerInvariant()) { case "[run]": i++; while (i < Lines.Count && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); int k; if (int.TryParse(a, NumberStyles.Integer, Culture, out k)) { if (b.Length != 0 && !OpenBveApi.Path.ContainsInvalidChars(b)) { if (k >= 0) { int n = car.Sounds.Run.Length; if (k >= n) { Array.Resize(ref car.Sounds.Run, k + 1); for (int h = n; h < k; h++) { car.Sounds.Run[h] = new CarSound(); } } car.Sounds.Run[k] = new CarSound(Program.Sounds.RegisterBuffer(OpenBveApi.Path.CombineFile(trainFolder, b), SoundCfgParser.mediumRadius), center); } } } } i++; } i--; break; case "[motor]": i++; while (i < Lines.Count && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); int k; if (int.TryParse(a, NumberStyles.Integer, Culture, out k)) { if (b.Length != 0 && !OpenBveApi.Path.ContainsInvalidChars(b)) { if (k >= 0) { if (k >= MotorFiles.Length) { Array.Resize(ref MotorFiles, k + 1); } MotorFiles[k] = OpenBveApi.Path.CombineFile(trainFolder, b); if (!File.Exists(MotorFiles[k])) { MotorFiles[k] = null; } } } } } i++; } i--; break; } } car.Sounds.RunVolume = new double[car.Sounds.Run.Length]; // motor sound car.Sounds.Motor.Position = center; for (int i = 0; i < car.Sounds.Motor.Tables.Length; i++) { car.Sounds.Motor.Tables[i].Buffer = null; car.Sounds.Motor.Tables[i].Source = null; for (int j = 0; j < car.Sounds.Motor.Tables[i].Entries.Length; j++) { int index = car.Sounds.Motor.Tables[i].Entries[j].SoundIndex; if (index >= 0 && index < MotorFiles.Length && MotorFiles[index] != null) { car.Sounds.Motor.Tables[i].Entries[j].Buffer = Program.Sounds.RegisterBuffer(MotorFiles[index], SoundCfgParser.mediumRadius); } } } }
internal void LeaveCheck(Vector2 Point) { if (!Loading.SimulationSetup) { return; } if (renderer.Camera.CurrentMode != CameraViewMode.Interior && renderer.Camera.CurrentMode != CameraViewMode.InteriorLookAhead) { return; } TrainManager.Car Car = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar]; int add = Car.CarSections[0].CurrentAdditionalGroup + 1; if (add >= Car.CarSections[0].Groups.Length) { return; } TrainManager.TouchElement[] TouchElements = Car.CarSections[0].Groups[add].TouchElements; if (TouchElements == null) { return; } ObjectState pickedObject = ParseFBO(Point, 5, 5); foreach (TrainManager.TouchElement TouchElement in TouchElements) { if (TouchElement.Element.internalObject == pickedObject) { Car.CarSections[0].CurrentAdditionalGroup = TouchElement.JumpScreenIndex; Car.ChangeCarSection(TrainManager.CarSectionType.Interior); if (TouchElement.SoundIndex >= 0 && TouchElement.SoundIndex < Car.Sounds.Touch.Length) { SoundBuffer Buffer = Car.Sounds.Touch[TouchElement.SoundIndex].Buffer; OpenBveApi.Math.Vector3 Position = Car.Sounds.Touch[TouchElement.SoundIndex].Position; Program.Sounds.PlaySound(Buffer, 1.0, 1.0, Position, TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar], false); } } // HACK: Normally terminate the command issued once. if (TouchElement.Element.internalObject == pickedObject || (pickedObject != prePickedObject && TouchElement.Element.internalObject == prePickedObject)) { for (int i = 0; i < Interface.CurrentControls.Length; i++) { if (Interface.CurrentControls[i].Method != Interface.ControlMethod.Touch) { continue; } bool EnableOption = false; for (int j = 0; j < Translations.CommandInfos.Length; j++) { if (Interface.CurrentControls[i].Command == Translations.CommandInfos[j].Command) { EnableOption = Translations.CommandInfos[j].EnableOption; break; } } if (TouchElement.Command == Interface.CurrentControls[i].Command) { if (EnableOption && TouchElement.CommandOption != Interface.CurrentControls[i].Option) { continue; } Interface.CurrentControls[i].AnalogState = 0.0; Interface.CurrentControls[i].DigitalState = Interface.DigitalControlState.Released; MainLoop.RemoveControlRepeat(i); } } } } }
internal void TouchCheck(Vector2 Point) { if (!Loading.SimulationSetup) { return; } if (renderer.Camera.CurrentMode != CameraViewMode.Interior && renderer.Camera.CurrentMode != CameraViewMode.InteriorLookAhead) { return; } TrainManager.Car Car = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar]; int add = Car.CarSections[0].CurrentAdditionalGroup + 1; if (add >= Car.CarSections[0].Groups.Length) { return; } TrainManager.TouchElement[] TouchElements = Car.CarSections[0].Groups[add].TouchElements; if (TouchElements == null) { return; } ObjectState pickedObject = ParseFBO(Point, 5, 5); foreach (TrainManager.TouchElement TouchElement in TouchElements) { if (TouchElement.Element.internalObject != pickedObject) { continue; } for (int i = 0; i < Interface.CurrentControls.Length; i++) { if (Interface.CurrentControls[i].Method != Interface.ControlMethod.Touch) { continue; } bool EnableOption = false; for (int j = 0; j < Translations.CommandInfos.Length; j++) { if (Interface.CurrentControls[i].Command == Translations.CommandInfos[j].Command) { EnableOption = Translations.CommandInfos[j].EnableOption; break; } } if (TouchElement.Command == Interface.CurrentControls[i].Command) { if (EnableOption && TouchElement.CommandOption != Interface.CurrentControls[i].Option) { continue; } Interface.CurrentControls[i].AnalogState = 1.0; Interface.CurrentControls[i].DigitalState = Interface.DigitalControlState.Pressed; MainLoop.AddControlRepeat(i); } } } prePickedObject = pickedObject; }