static private ParseRoute ( string FileName, bool IsRW, System Encoding, string TrainPath, string ObjectPath, string SoundPath, bool PreviewOnly ) : void | ||
FileName | string | |
IsRW | bool | |
Encoding | System | |
TrainPath | string | |
ObjectPath | string | |
SoundPath | string | |
PreviewOnly | bool | |
return | void |
private void routeWorkerThread_doWork(object sender, DoWorkEventArgs e) { Game.Reset(false); bool IsRW = string.Equals(System.IO.Path.GetExtension(Result.RouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(Result.RouteFile, IsRW, Result.RouteEncoding, null, null, null, true); }
private static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // --- determine the running environment --- CurrentlyRunningOnMono = Type.GetType("Mono.Runtime") != null; CurrentlyRunningOnWindows = Environment.OSVersion.Platform == PlatformID.Win32S | Environment.OSVersion.Platform == PlatformID.Win32Windows | Environment.OSVersion.Platform == PlatformID.Win32NT; CurrentHost = new Host(); try { FileSystem = FileSystem.FromCommandLineArgs(args); FileSystem.CreateFileSystem(); } catch (Exception ex) { MessageBox.Show("The file system configuration could not be accessed or is invalid due to the following reason:\n\n" + ex.Message, "openBVE", MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } // --- set up packages --- SetPackageLookupDirectories(); // --- load options and controls --- Interface.LoadOptions(); Interface.LoadControls(null, out Interface.CurrentControls); { string folder = Program.FileSystem.GetDataFolder("Controls"); string file = OpenBveApi.Path.CombineFile(folder, "Default keyboard assignment.controls"); Interface.Control[] controls; Interface.LoadControls(file, out controls); Interface.AddControls(ref Interface.CurrentControls, controls); } // --- load language --- { string folder = Program.FileSystem.GetDataFolder("Languages"); string file = OpenBveApi.Path.CombineFile(folder, Interface.CurrentOptions.LanguageCode + ".cfg"); if (!System.IO.File.Exists(file)) { file = OpenBveApi.Path.CombineFile(folder, "en-US.cfg"); } Interface.LoadLanguage(file); } // --- check the command-line arguments for route and train --- formMain.MainDialogResult result = new formMain.MainDialogResult(); for (int i = 0; i < args.Length; i++) { if (args[i].StartsWith("/route=", StringComparison.OrdinalIgnoreCase)) { result.RouteFile = args[i].Substring(7); result.RouteEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.RouteEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.RouteEncodings[j].Value, result.RouteFile, StringComparison.InvariantCultureIgnoreCase) == 0) { result.RouteEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.RouteEncodings[j].Codepage); break; } } } else if (args[i].StartsWith("/train=", StringComparison.OrdinalIgnoreCase)) { result.TrainFolder = args[i].Substring(7); result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } // --- check whether route and train exist --- if (result.RouteFile != null) { if (!System.IO.File.Exists(result.RouteFile)) { result.RouteFile = null; } } if (result.TrainFolder != null) { if (!System.IO.Directory.Exists(result.TrainFolder)) { result.TrainFolder = null; } } // --- if a route was provided but no train, try to use the route default --- if (result.RouteFile != null & result.TrainFolder == null) { bool isRW = string.Equals(System.IO.Path.GetExtension(result.RouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(result.RouteFile, isRW, result.RouteEncoding, null, null, null, true); if (Game.TrainName != null && Game.TrainName.Length != 0) { string folder = System.IO.Path.GetDirectoryName(result.RouteFile); while (true) { string trainFolder = OpenBveApi.Path.CombineDirectory(folder, "Train"); if (System.IO.Directory.Exists(trainFolder)) { folder = OpenBveApi.Path.CombineDirectory(trainFolder, Game.TrainName); if (System.IO.Directory.Exists(folder)) { string file = OpenBveApi.Path.CombineFile(folder, "train.dat"); if (System.IO.File.Exists(file)) { result.TrainFolder = folder; result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } break; } else { System.IO.DirectoryInfo info = System.IO.Directory.GetParent(folder); if (info != null) { folder = info.FullName; } else { break; } } } } Game.Reset(false); } // --- show the main menu if necessary --- if (result.RouteFile == null | result.TrainFolder == null) { // begin HACK // if (!Joysticks.Initialize()) { MessageBox.Show("SDL failed to initialize the joystick subsystem.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } // end HACK // result = formMain.ShowMainDialog(result); } else { result.Start = true; } // --- start the actual program --- if (result.Start) { if (Initialize()) { #if !DEBUG try { #endif MainLoop.StartLoopEx(result); #if !DEBUG } catch (Exception ex) { bool found = false; for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i] != null && TrainManager.Trains[i].Plugin != null) { if (TrainManager.Trains[i].Plugin.LastException != null) { MessageBox.Show("The train plugin " + TrainManager.Trains[i].Plugin.PluginTitle + " caused a runtime exception: " + TrainManager.Trains[i].Plugin.LastException.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); found = true; break; } } } if (!found) { MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); } } #endif } Deinitialize(); } // --- restart the program if necessary --- if (RestartArguments != null) { string arguments; if (FileSystem.RestartArguments.Length != 0 & RestartArguments.Length != 0) { arguments = FileSystem.RestartArguments + " " + RestartArguments; } else { arguments = FileSystem.RestartArguments + RestartArguments; } try { System.Diagnostics.Process.Start(FileSystem.RestartProcess, arguments); } catch (Exception ex) { MessageBox.Show(ex.Message + "\n\nProcess = " + FileSystem.RestartProcess + "\nArguments = " + arguments, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
private static void LoadEverythingThreaded() { Program.AppendToLogFile("Loading route file: " + CurrentRouteFile); string RailwayFolder = GetRailwayFolder(CurrentRouteFile); string ObjectFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Object"); string SoundFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Sound"); // reset Game.Reset(true); Game.MinimalisticSimulation = true; // screen World.CameraTrackFollower = new TrackManager.TrackFollower { Train = null, CarIndex = -1 }; World.CameraMode = World.CameraViewMode.Interior; //First, check the format of the route file //RW routes were written for BVE1 / 2, and have a different command syntax bool IsRW = CsvRwRouteParser.isRWFile(CurrentRouteFile); Program.AppendToLogFile("Route file format is: " + (IsRW ? "RW" : "CSV")); CsvRwRouteParser.ParseRoute(CurrentRouteFile, IsRW, CurrentRouteEncoding, CurrentTrainFolder, ObjectFolder, SoundFolder, false); Thread createIllustrations = new Thread(Game.RouteInformation.LoadInformation) { IsBackground = true }; createIllustrations.Start(); System.Threading.Thread.Sleep(1); if (Cancel) { return; } Game.CalculateSeaLevelConstants(); if (Game.BogusPretrainInstructions.Length != 0) { double t = Game.BogusPretrainInstructions[0].Time; double p = Game.BogusPretrainInstructions[0].TrackPosition; for (int i = 1; i < Game.BogusPretrainInstructions.Length; i++) { if (Game.BogusPretrainInstructions[i].Time > t) { t = Game.BogusPretrainInstructions[i].Time; } else { t += 1.0; Game.BogusPretrainInstructions[i].Time = t; } if (Game.BogusPretrainInstructions[i].TrackPosition > p) { p = Game.BogusPretrainInstructions[i].TrackPosition; } else { p += 1.0; Game.BogusPretrainInstructions[i].TrackPosition = p; } } } if (Game.Stations.Length == 1) { //Log the fact that only a single station is present, as this is probably not right Program.AppendToLogFile("The processed route file only contains a single station."); } Program.AppendToLogFile("Route file loaded successfully."); RouteProgress = 1.0; // initialize trains System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainManager.Trains = new TrainManager.Train[Game.PrecedingTrainTimeDeltas.Length + 1 + (Game.BogusPretrainInstructions.Length != 0 ? 1 : 0)]; for (int k = 0; k < TrainManager.Trains.Length; k++) { TrainManager.Trains[k] = new TrainManager.Train { TrainIndex = k }; if (k == TrainManager.Trains.Length - 1 & Game.BogusPretrainInstructions.Length != 0) { TrainManager.Trains[k].State = TrainManager.TrainState.Bogus; } else { TrainManager.Trains[k].State = TrainManager.TrainState.Pending; } } TrainManager.PlayerTrain = TrainManager.Trains[Game.PrecedingTrainTimeDeltas.Length]; // load trains double TrainProgressMaximum = 0.7 + 0.3 * (double)TrainManager.Trains.Length; for (int k = 0; k < TrainManager.Trains.Length; k++) { //Sleep for 10ms to allow route loading locks to release Thread.Sleep(20); if (TrainManager.Trains[k].State == TrainManager.TrainState.Bogus) { // bogus train string TrainData = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Compatibility", "PreTrain"), "train.dat"); TrainDatParser.ParseTrainData(TrainData, System.Text.Encoding.UTF8, TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainManager.Trains[k].InitializeCarSounds(); System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainProgressCurrentWeight = 0.3 / TrainProgressMaximum; TrainProgressCurrentSum += TrainProgressCurrentWeight; } else { // real train Program.AppendToLogFile("Loading player train: " + CurrentTrainFolder); TrainProgressCurrentWeight = 0.1 / TrainProgressMaximum; string TrainData = OpenBveApi.Path.CombineFile(CurrentTrainFolder, "train.dat"); TrainDatParser.ParseTrainData(TrainData, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainProgressCurrentWeight = 0.2 / TrainProgressMaximum; SoundCfgParser.ParseSoundConfig(CurrentTrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } // door open/close speed for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { if (TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency <= 0.0) { if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer != null & TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer.Duration; double b = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = a > 0.0 ? 1.0 / a : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); double b = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = b > 0.0 ? 1.0 / b : 0.8; } else { TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = 0.8; } } if (TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency <= 0.0) { if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer != null & TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer.Duration; double b = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = a > 0.0 ? 1.0 / a : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); double b = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = b > 0.0 ? 1.0 / b : 0.8; } else { TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = 0.8; } } const double f = 0.015; const double g = 2.75; TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5))); TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5))); TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency /= TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency /= TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch; /* * Remove the following two lines, then the pitch at which doors play * takes their randomized opening and closing times into account. * */ TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch = 1.0; TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch = 1.0; } } for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { TrainManager.Trains[k].Cars[i].FrontAxle.Follower.Train = TrainManager.Trains[k]; TrainManager.Trains[k].Cars[i].RearAxle.Follower.Train = TrainManager.Trains[k]; TrainManager.Trains[k].Cars[i].BeaconReceiver.Train = TrainManager.Trains[k]; } // add panel section if (k == TrainManager.PlayerTrain.TrainIndex) { TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections = new TrainManager.CarSection[1]; TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0].Elements = new ObjectManager.AnimatedObject[] { }; TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0].Overlay = true; TrainProgressCurrentWeight = 0.7 / TrainProgressMaximum; TrainManager.ParsePanelConfig(CurrentTrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } Program.AppendToLogFile("Train panel loaded sucessfully."); } // add exterior section if (TrainManager.Trains[k].State != TrainManager.TrainState.Bogus) { ObjectManager.UnifiedObject[] CarObjects; ObjectManager.UnifiedObject[] BogieObjects; ExtensionsCfgParser.ParseExtensionsConfig(CurrentTrainFolder, CurrentTrainEncoding, out CarObjects, out BogieObjects, TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } //Stores the current array index of the bogie object to add //Required as there are two bogies per car, and we're using a simple linear array.... int currentBogieObject = 0; for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { if (CarObjects[i] == null) { // load default exterior object string file = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Compatibility"), "exterior.csv"); ObjectManager.StaticObject so = ObjectManager.LoadStaticObject(file, System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); if (so == null) { CarObjects[i] = null; } else { double sx = TrainManager.Trains[k].Cars[i].Width; double sy = TrainManager.Trains[k].Cars[i].Height; double sz = TrainManager.Trains[k].Cars[i].Length; CsvB3dObjectParser.ApplyScale(so, sx, sy, sz); CarObjects[i] = so; } } if (CarObjects[i] != null) { // add object int j = TrainManager.Trains[k].Cars[i].CarSections.Length; Array.Resize <TrainManager.CarSection>(ref TrainManager.Trains[k].Cars[i].CarSections, j + 1); if (CarObjects[i] is ObjectManager.StaticObject) { ObjectManager.StaticObject s = (ObjectManager.StaticObject)CarObjects[i]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements = new ObjectManager.AnimatedObject[1]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0] = new ObjectManager.AnimatedObject(); TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States = new ObjectManager.AnimatedObjectState[1]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States[0].Position = new Vector3(0.0, 0.0, 0.0); TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States[0].Object = s; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].CurrentState = 0; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].ObjectIndex = ObjectManager.CreateDynamicObject(); } else if (CarObjects[i] is ObjectManager.AnimatedObjectCollection) { ObjectManager.AnimatedObjectCollection a = (ObjectManager.AnimatedObjectCollection)CarObjects[i]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements = new ObjectManager.AnimatedObject[a.Objects.Length]; for (int h = 0; h < a.Objects.Length; h++) { TrainManager.Trains[k].Cars[i].CarSections[j].Elements[h] = a.Objects[h]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[h].ObjectIndex = ObjectManager.CreateDynamicObject(); } } } //Load bogie objects if (BogieObjects[currentBogieObject] != null) { int j = TrainManager.Trains[k].Cars[i].FrontBogie.CarSections.Length; Array.Resize <TrainManager.CarSection>(ref TrainManager.Trains[k].Cars[i].FrontBogie.CarSections, j + 1); if (BogieObjects[currentBogieObject] is ObjectManager.StaticObject) { ObjectManager.StaticObject s = (ObjectManager.StaticObject)BogieObjects[currentBogieObject]; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements = new ObjectManager.AnimatedObject[1]; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0] = new ObjectManager.AnimatedObject(); TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0].States = new ObjectManager.AnimatedObjectState[1]; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0].States[0].Position = new Vector3(0.0, 0.0, 0.0); TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0].States[0].Object = s; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0].CurrentState = 0; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0].ObjectIndex = ObjectManager.CreateDynamicObject(); } else if (BogieObjects[currentBogieObject] is ObjectManager.AnimatedObjectCollection) { ObjectManager.AnimatedObjectCollection a = (ObjectManager.AnimatedObjectCollection)BogieObjects[currentBogieObject]; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements = new ObjectManager.AnimatedObject[a.Objects.Length]; for (int h = 0; h < a.Objects.Length; h++) { TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[h] = a.Objects[h]; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[h].ObjectIndex = ObjectManager.CreateDynamicObject(); } } } currentBogieObject++; //Can't think of a better way to do this than two functions...... if (BogieObjects[currentBogieObject] != null) { int j = TrainManager.Trains[k].Cars[i].RearBogie.CarSections.Length; Array.Resize <TrainManager.CarSection>(ref TrainManager.Trains[k].Cars[i].RearBogie.CarSections, j + 1); if (BogieObjects[currentBogieObject] is ObjectManager.StaticObject) { ObjectManager.StaticObject s = (ObjectManager.StaticObject)BogieObjects[currentBogieObject]; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements = new ObjectManager.AnimatedObject[1]; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0] = new ObjectManager.AnimatedObject(); TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0].States = new ObjectManager.AnimatedObjectState[1]; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0].States[0].Position = new Vector3(0.0, 0.0, 0.0); TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0].States[0].Object = s; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0].CurrentState = 0; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0].ObjectIndex = ObjectManager.CreateDynamicObject(); } else if (BogieObjects[currentBogieObject] is ObjectManager.AnimatedObjectCollection) { ObjectManager.AnimatedObjectCollection a = (ObjectManager.AnimatedObjectCollection)BogieObjects[currentBogieObject]; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements = new ObjectManager.AnimatedObject[a.Objects.Length]; for (int h = 0; h < a.Objects.Length; h++) { TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[h] = a.Objects[h]; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[h].ObjectIndex = ObjectManager.CreateDynamicObject(); } } } currentBogieObject++; } } // place cars { double z = 0.0; for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { //Front axle track position TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].FrontAxle.Position; //Bogie for front axle TrainManager.Trains[k].Cars[i].FrontBogie.FrontAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].FrontBogie.Length + TrainManager.Trains[k].Cars[i].FrontBogie.FrontAxle.Position; TrainManager.Trains[k].Cars[i].FrontBogie.RearAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].FrontBogie.Length + TrainManager.Trains[k].Cars[i].FrontBogie.RearAxle.Position; //Rear axle track position TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].RearAxle.Position; //Bogie for rear axle TrainManager.Trains[k].Cars[i].RearBogie.FrontAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].RearBogie.Length + TrainManager.Trains[k].Cars[i].RearBogie.FrontAxle.Position; TrainManager.Trains[k].Cars[i].RearBogie.RearAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].RearBogie.Length + TrainManager.Trains[k].Cars[i].RearBogie.RearAxle.Position; //Beacon reciever (AWS, ATC etc.) TrainManager.Trains[k].Cars[i].BeaconReceiver.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].BeaconReceiverPosition; z -= TrainManager.Trains[k].Cars[i].Length; if (i < TrainManager.Trains[k].Cars.Length - 1) { z -= 0.5 * (TrainManager.Trains[k].Couplers[i].MinimumDistanceBetweenCars + TrainManager.Trains[k].Couplers[i].MaximumDistanceBetweenCars); } } } // configure ai / timetable if (TrainManager.Trains[k] == TrainManager.PlayerTrain) { TrainManager.Trains[k].TimetableDelta = 0.0; } else if (TrainManager.Trains[k].State != TrainManager.TrainState.Bogus) { TrainManager.Trains[k].AI = new Game.SimpleHumanDriverAI(TrainManager.Trains[k]); TrainManager.Trains[k].TimetableDelta = Game.PrecedingTrainTimeDeltas[k]; TrainManager.Trains[k].Specs.DoorOpenMode = TrainManager.DoorMode.Manual; TrainManager.Trains[k].Specs.DoorCloseMode = TrainManager.DoorMode.Manual; } } TrainProgress = 1.0; // finished created objects System.Threading.Thread.Sleep(1); if (Cancel) { return; } ObjectManager.FinishCreatingObjects(); // update sections if (Game.Sections.Length > 0) { Game.UpdateSection(Game.Sections.Length - 1); } // load plugin for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i].State != TrainManager.TrainState.Bogus) { if (TrainManager.Trains[i] == TrainManager.PlayerTrain) { if (!PluginManager.LoadCustomPlugin(TrainManager.Trains[i], CurrentTrainFolder, CurrentTrainEncoding)) { PluginManager.LoadDefaultPlugin(TrainManager.Trains[i], CurrentTrainFolder); } } else { PluginManager.LoadDefaultPlugin(TrainManager.Trains[i], CurrentTrainFolder); } } } }
private static void LoadEverythingThreaded() { string RailwayFolder = GetRailwayFolder(CurrentRouteFile); string ObjectFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Object"); string SoundFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Sound"); // string CompatibilityFolder = OpenBveApi.Path.CombineDirectory(Application.StartupPath, "Compatibility"); // reset Game.Reset(); Game.MinimalisticSimulation = true; // screen World.CameraTrackFollower = new TrackManager.TrackFollower(); World.CameraTrackFollower.Train = null; World.CameraTrackFollower.CarIndex = -1; Camera.CurrentMode = CameraViewMode.Track; // load route bool IsRW = string.Equals(System.IO.Path.GetExtension(CurrentRouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(CurrentRouteFile, IsRW, CurrentRouteEncoding, Application.StartupPath, ObjectFolder, SoundFolder, false); System.Threading.Thread.Sleep(1); if (Cancel) { return; } Atmosphere.CalculateSeaLevelConstants(); RouteProgress = 1.0; // camera ObjectManager.InitializeVisibility(); TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, 0.0, true, false); TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, 0.1, true, false); TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, -0.1, true, false); World.CameraTrackFollower.TriggerType = EventTriggerType.Camera; // default starting time Game.SecondsSinceMidnight = 0.0; Game.StartupTime = 0.0; // finished created objects System.Threading.Thread.Sleep(1); if (Cancel) { return; } ObjectManager.FinishCreatingObjects(); // signals System.Threading.Thread.Sleep(1); if (Cancel) { return; } if (CurrentRoute.Sections.Length > 0) { Game.UpdateSection(CurrentRoute.Sections.Length - 1); } // starting track position System.Threading.Thread.Sleep(1); if (Cancel) { return; } // int FirstStationIndex = -1; double FirstStationPosition = 0.0; for (int i = 0; i < CurrentRoute.Stations.Length; i++) { if (CurrentRoute.Stations[i].Stops.Length != 0) { // FirstStationIndex = i; FirstStationPosition = CurrentRoute.Stations[i].Stops[CurrentRoute.Stations[i].Stops.Length - 1].TrackPosition; if (CurrentRoute.Stations[i].ArrivalTime < 0.0) { if (CurrentRoute.Stations[i].DepartureTime < 0.0) { Game.SecondsSinceMidnight = 0.0; } else { Game.SecondsSinceMidnight = CurrentRoute.Stations[i].DepartureTime - CurrentRoute.Stations[i].StopTime; } } else { Game.SecondsSinceMidnight = CurrentRoute.Stations[i].ArrivalTime; } Game.StartupTime = Game.SecondsSinceMidnight; break; } } // initialize camera TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, -1.0, true, false); TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, FirstStationPosition, true, false); Camera.CurrentAlignment = new CameraAlignment(new Vector3(0.0, 2.5, 0.0), 0.0, 0.0, 0.0, FirstStationPosition, 1.0); World.UpdateAbsoluteCamera(0.0); ObjectManager.UpdateVisibility(World.CameraTrackFollower.TrackPosition + Camera.CurrentAlignment.Position.Z); }
private static void LoadEverythingThreaded() { Program.FileSystem.AppendToLogFile("Loading route file: " + CurrentRouteFile); Program.FileSystem.AppendToLogFile("INFO: Route file hash " + CsvRwRouteParser.GetChecksum(CurrentRouteFile)); string RailwayFolder = GetRailwayFolder(CurrentRouteFile); string ObjectFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Object"); string SoundFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Sound"); Game.Reset(true, false); Game.MinimalisticSimulation = true; // screen Program.Renderer.Camera.CurrentMode = CameraViewMode.Interior; //First, check the format of the route file //RW routes were written for BVE1 / 2, and have a different command syntax bool IsRW = CsvRwRouteParser.isRWFile(CurrentRouteFile); Program.FileSystem.AppendToLogFile("Route file format is: " + (IsRW ? "RW" : "CSV")); CsvRwRouteParser.ParseRoute(CurrentRouteFile, IsRW, CurrentRouteEncoding, CurrentTrainFolder, ObjectFolder, SoundFolder, false); Thread createIllustrations = new Thread(Game.RouteInformation.LoadInformation) { IsBackground = true }; createIllustrations.Start(); System.Threading.Thread.Sleep(1); if (Cancel) { return; } Program.CurrentRoute.Atmosphere.CalculateSeaLevelConstants(); if (Program.CurrentRoute.BogusPreTrainInstructions.Length != 0) { double t = Program.CurrentRoute.BogusPreTrainInstructions[0].Time; double p = Program.CurrentRoute.BogusPreTrainInstructions[0].TrackPosition; for (int i = 1; i < Program.CurrentRoute.BogusPreTrainInstructions.Length; i++) { if (Program.CurrentRoute.BogusPreTrainInstructions[i].Time > t) { t = Program.CurrentRoute.BogusPreTrainInstructions[i].Time; } else { t += 1.0; Program.CurrentRoute.BogusPreTrainInstructions[i].Time = t; } if (Program.CurrentRoute.BogusPreTrainInstructions[i].TrackPosition > p) { p = Program.CurrentRoute.BogusPreTrainInstructions[i].TrackPosition; } else { p += 1.0; Program.CurrentRoute.BogusPreTrainInstructions[i].TrackPosition = p; } } } World.CameraTrackFollower = new TrackFollower(Program.CurrentHost) { Train = null, Car = null }; if (Program.CurrentRoute.Stations.Length == 1) { //Log the fact that only a single station is present, as this is probably not right Program.FileSystem.AppendToLogFile("The processed route file only contains a single station."); } Program.FileSystem.AppendToLogFile("Route file loaded successfully."); RouteProgress = 1.0; // initialize trains System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainManager.Trains = new TrainManager.Train[Game.PrecedingTrainTimeDeltas.Length + 1 + (Program.CurrentRoute.BogusPreTrainInstructions.Length != 0 ? 1 : 0)]; for (int k = 0; k < TrainManager.Trains.Length; k++) { if (k == TrainManager.Trains.Length - 1 & Program.CurrentRoute.BogusPreTrainInstructions.Length != 0) { TrainManager.Trains[k] = new TrainManager.Train(TrainState.Bogus); } else { TrainManager.Trains[k] = new TrainManager.Train(TrainState.Pending); } } TrainManager.PlayerTrain = TrainManager.Trains[Game.PrecedingTrainTimeDeltas.Length]; UnifiedObject[] CarObjects = null; UnifiedObject[] BogieObjects = null; UnifiedObject[] CouplerObjects = null; // load trains double TrainProgressMaximum = 0.7 + 0.3 * (double)TrainManager.Trains.Length; for (int k = 0; k < TrainManager.Trains.Length; k++) { //Sleep for 20ms to allow route loading locks to release Thread.Sleep(20); if (TrainManager.Trains[k].State == TrainState.Bogus) { // bogus train string TrainData = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Compatibility", "PreTrain"), "train.dat"); TrainDatParser.ParseTrainData(TrainData, System.Text.Encoding.UTF8, TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainManager.Trains[k].InitializeCarSounds(); System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainProgressCurrentWeight = 0.3 / TrainProgressMaximum; TrainProgressCurrentSum += TrainProgressCurrentWeight; } else { TrainManager.Trains[k].TrainFolder = CurrentTrainFolder; // real train if (TrainManager.Trains[k].IsPlayerTrain) { Program.FileSystem.AppendToLogFile("Loading player train: " + TrainManager.Trains[k].TrainFolder); } else { Program.FileSystem.AppendToLogFile("Loading AI train: " + TrainManager.Trains[k].TrainFolder); } TrainProgressCurrentWeight = 0.1 / TrainProgressMaximum; string TrainData = OpenBveApi.Path.CombineFile(TrainManager.Trains[k].TrainFolder, "train.dat"); TrainDatParser.ParseTrainData(TrainData, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainProgressCurrentWeight = 0.2 / TrainProgressMaximum; SoundCfgParser.ParseSoundConfig(TrainManager.Trains[k].TrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } // door open/close speed for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { if (TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency <= 0.0) { if (TrainManager.Trains[k].Cars[i].Doors[0].OpenSound.Buffer != null & TrainManager.Trains[k].Cars[i].Doors[1].OpenSound.Buffer != null) { Program.Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Doors[0].OpenSound.Buffer); Program.Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Doors[1].OpenSound.Buffer); double a = TrainManager.Trains[k].Cars[i].Doors[0].OpenSound.Buffer.Duration; double b = TrainManager.Trains[k].Cars[i].Doors[1].OpenSound.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8; } else if (TrainManager.Trains[k].Cars[i].Doors[0].OpenSound.Buffer != null) { Program.Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Doors[0].OpenSound.Buffer); double a = TrainManager.Trains[k].Cars[i].Doors[0].OpenSound.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = a > 0.0 ? 1.0 / a : 0.8; } else if (TrainManager.Trains[k].Cars[i].Doors[1].OpenSound.Buffer != null) { Program.Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Doors[0].OpenSound.Buffer); double b = TrainManager.Trains[k].Cars[i].Doors[1].OpenSound.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = b > 0.0 ? 1.0 / b : 0.8; } else { TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = 0.8; } } if (TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency <= 0.0) { if (TrainManager.Trains[k].Cars[i].Doors[0].CloseSound.Buffer != null & TrainManager.Trains[k].Cars[i].Doors[1].CloseSound.Buffer != null) { Program.Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Doors[0].CloseSound.Buffer); Program.Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Doors[1].CloseSound.Buffer); double a = TrainManager.Trains[k].Cars[i].Doors[0].CloseSound.Buffer.Duration; double b = TrainManager.Trains[k].Cars[i].Doors[1].CloseSound.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8; } else if (TrainManager.Trains[k].Cars[i].Doors[0].CloseSound.Buffer != null) { Program.Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Doors[0].CloseSound.Buffer); double a = TrainManager.Trains[k].Cars[i].Doors[0].CloseSound.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = a > 0.0 ? 1.0 / a : 0.8; } else if (TrainManager.Trains[k].Cars[i].Doors[1].CloseSound.Buffer != null) { Program.Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Doors[0].CloseSound.Buffer); double b = TrainManager.Trains[k].Cars[i].Doors[1].CloseSound.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = b > 0.0 ? 1.0 / b : 0.8; } else { TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = 0.8; } } const double f = 0.015; const double g = 2.75; TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5))); TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5))); TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency /= TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency /= TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch; /* * Remove the following two lines, then the pitch at which doors play * takes their randomized opening and closing times into account. * */ TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch = 1.0; TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch = 1.0; } } // add panel section if (TrainManager.Trains[k].IsPlayerTrain) { TrainProgressCurrentWeight = 0.7 / TrainProgressMaximum; TrainManager.ParsePanelConfig(TrainManager.Trains[k].TrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } Program.FileSystem.AppendToLogFile("Train panel loaded sucessfully."); } // add exterior section if (TrainManager.Trains[k].State != TrainState.Bogus) { bool LoadObjects = false; if (CarObjects == null) { CarObjects = new UnifiedObject[TrainManager.Trains[k].Cars.Length]; BogieObjects = new UnifiedObject[TrainManager.Trains[k].Cars.Length * 2]; CouplerObjects = new UnifiedObject[TrainManager.Trains[k].Cars.Length]; LoadObjects = true; } string tXml = OpenBveApi.Path.CombineFile(TrainManager.Trains[k].TrainFolder, "train.xml"); if (System.IO.File.Exists(tXml)) { TrainXmlParser.Parse(tXml, TrainManager.Trains[k], ref CarObjects, ref BogieObjects, ref CouplerObjects); } else { ExtensionsCfgParser.ParseExtensionsConfig(TrainManager.Trains[k].TrainFolder, CurrentTrainEncoding, ref CarObjects, ref BogieObjects, ref CouplerObjects, TrainManager.Trains[k], LoadObjects); } World.CameraCar = TrainManager.Trains[k].DriverCar; System.Threading.Thread.Sleep(1); if (Cancel) { return; } //Stores the current array index of the bogie object to add //Required as there are two bogies per car, and we're using a simple linear array.... int currentBogieObject = 0; for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { if (CarObjects[i] == null) { // load default exterior object string file = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Compatibility"), "exterior.csv"); StaticObject so = ObjectManager.LoadStaticObject(file, System.Text.Encoding.UTF8, false); if (so == null) { CarObjects[i] = null; } else { double sx = TrainManager.Trains[k].Cars[i].Width; double sy = TrainManager.Trains[k].Cars[i].Height; double sz = TrainManager.Trains[k].Cars[i].Length; so.ApplyScale(sx, sy, sz); CarObjects[i] = so; } } if (CarObjects[i] != null) { // add object TrainManager.Trains[k].Cars[i].LoadCarSections(CarObjects[i]); } if (CouplerObjects[i] != null) { TrainManager.Trains[k].Cars[i].Coupler.LoadCarSections(CouplerObjects[i]); } //Load bogie objects if (BogieObjects[currentBogieObject] != null) { TrainManager.Trains[k].Cars[i].FrontBogie.LoadCarSections(BogieObjects[currentBogieObject]); } currentBogieObject++; if (BogieObjects[currentBogieObject] != null) { TrainManager.Trains[k].Cars[i].RearBogie.LoadCarSections(BogieObjects[currentBogieObject]); } currentBogieObject++; } } // place cars TrainManager.Trains[k].PlaceCars(0.0); // configure ai / timetable if (TrainManager.Trains[k].IsPlayerTrain) { TrainManager.Trains[k].TimetableDelta = 0.0; } else if (TrainManager.Trains[k].State != TrainState.Bogus) { TrainManager.Trains[k].AI = new Game.SimpleHumanDriverAI(TrainManager.Trains[k]); TrainManager.Trains[k].TimetableDelta = Game.PrecedingTrainTimeDeltas[k]; TrainManager.Trains[k].Specs.DoorOpenMode = TrainManager.DoorMode.Manual; TrainManager.Trains[k].Specs.DoorCloseMode = TrainManager.DoorMode.Manual; } } /* * HACK: Store the TrainManager.Trains reference in the RouteManager also * Note that this may change when the TrainManager is separated from the lump * Remember not to modify via this ref */ // ReSharper disable once CoVariantArrayConversion Program.CurrentRoute.Trains = TrainManager.Trains; TrainProgress = 1.0; // finished created objects System.Threading.Thread.Sleep(1); if (Cancel) { return; } Array.Resize(ref ObjectManager.AnimatedWorldObjects, ObjectManager.AnimatedWorldObjectsUsed); // update sections if (Program.CurrentRoute.Sections.Length > 0) { Program.CurrentRoute.UpdateAllSections(); } // load plugin for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i].State != TrainState.Bogus) { if (TrainManager.Trains[i].IsPlayerTrain) { if (!TrainManager.Trains[i].LoadCustomPlugin(TrainManager.Trains[i].TrainFolder, CurrentTrainEncoding)) { TrainManager.Trains[i].LoadDefaultPlugin(TrainManager.Trains[i].TrainFolder); } } else { TrainManager.Trains[i].LoadDefaultPlugin(TrainManager.Trains[i].TrainFolder); } } } }
private static void LoadEverythingThreaded() { string RailwayFolder = GetRailwayFolder(CurrentRouteFile); // if (RailwayFolder == null) { // Interface.AddMessage(Interface.MessageType.Critical, false, "The Railway folder could not be found. Please check your folder structure."); // return; // } string ObjectFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Object"); string SoundFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Sound"); // reset Game.Reset(true); Game.MinimalisticSimulation = true; // screen World.CameraTrackFollower = new TrackManager.TrackFollower(); World.CameraTrackFollower.Train = null; World.CameraTrackFollower.CarIndex = -1; World.CameraMode = World.CameraViewMode.Interior; // load route bool IsRW = string.Equals(System.IO.Path.GetExtension(CurrentRouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(CurrentRouteFile, IsRW, CurrentRouteEncoding, CurrentTrainFolder, ObjectFolder, SoundFolder, false); System.Threading.Thread.Sleep(1); if (Cancel) { return; } Game.CalculateSeaLevelConstants(); if (Game.BogusPretrainInstructions.Length != 0) { double t = Game.BogusPretrainInstructions[0].Time; double p = Game.BogusPretrainInstructions[0].TrackPosition; for (int i = 1; i < Game.BogusPretrainInstructions.Length; i++) { if (Game.BogusPretrainInstructions[i].Time > t) { t = Game.BogusPretrainInstructions[i].Time; } else { t += 1.0; Game.BogusPretrainInstructions[i].Time = t; } if (Game.BogusPretrainInstructions[i].TrackPosition > p) { p = Game.BogusPretrainInstructions[i].TrackPosition; } else { p += 1.0; Game.BogusPretrainInstructions[i].TrackPosition = p; } } } RouteProgress = 1.0; // initialize trains System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainManager.Trains = new TrainManager.Train[Game.PrecedingTrainTimeDeltas.Length + 1 + (Game.BogusPretrainInstructions.Length != 0 ? 1 : 0)]; for (int k = 0; k < TrainManager.Trains.Length; k++) { TrainManager.Trains[k] = new TrainManager.Train(); TrainManager.Trains[k].TrainIndex = k; if (k == TrainManager.Trains.Length - 1 & Game.BogusPretrainInstructions.Length != 0) { TrainManager.Trains[k].State = TrainManager.TrainState.Bogus; } else { TrainManager.Trains[k].State = TrainManager.TrainState.Pending; } } TrainManager.PlayerTrain = TrainManager.Trains[Game.PrecedingTrainTimeDeltas.Length]; // load trains double TrainProgressMaximum = 0.7 + 0.3 * (double)TrainManager.Trains.Length; for (int k = 0; k < TrainManager.Trains.Length; k++) { if (TrainManager.Trains[k].State == TrainManager.TrainState.Bogus) { // bogus train string Folder = Program.FileSystem.GetDataFolder("Compatibility", "PreTrain"); TrainDatParser.ParseTrainData(Folder, System.Text.Encoding.UTF8, TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } SoundCfgParser.LoadNoSound(TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainProgressCurrentWeight = 0.3 / TrainProgressMaximum; TrainProgressCurrentSum += TrainProgressCurrentWeight; } else { // real train TrainProgressCurrentWeight = 0.1 / TrainProgressMaximum; TrainDatParser.ParseTrainData(CurrentTrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainProgressCurrentWeight = 0.2 / TrainProgressMaximum; SoundCfgParser.ParseSoundConfig(CurrentTrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } // door open/close speed for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { if (TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency <= 0.0) { if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer != null & TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer.Duration; double b = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = a > 0.0 ? 1.0 / a : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); double b = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = b > 0.0 ? 1.0 / b : 0.8; } else { TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = 0.8; } } if (TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency <= 0.0) { if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer != null & TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer.Duration; double b = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = a > 0.0 ? 1.0 / a : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); double b = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = b > 0.0 ? 1.0 / b : 0.8; } else { TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = 0.8; } } const double f = 0.015; const double g = 2.75; TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5))); TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5))); TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency /= TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency /= TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch; /* * Remove the following two lines, then the pitch at which doors play * takes their randomized opening and closing times into account. * */ TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch = 1.0; TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch = 1.0; } } for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { TrainManager.Trains[k].Cars[i].FrontAxle.Follower.Train = TrainManager.Trains[k]; TrainManager.Trains[k].Cars[i].RearAxle.Follower.Train = TrainManager.Trains[k]; TrainManager.Trains[k].Cars[i].BeaconReceiver.Train = TrainManager.Trains[k]; } // add panel section if (k == TrainManager.PlayerTrain.TrainIndex) { TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections = new TrainManager.CarSection[1]; TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0].Elements = new ObjectManager.AnimatedObject[] { }; TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0].Overlay = true; TrainProgressCurrentWeight = 0.7 / TrainProgressMaximum; TrainManager.ParsePanelConfig(CurrentTrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } } // add exterior section if (TrainManager.Trains[k].State != TrainManager.TrainState.Bogus) { ObjectManager.UnifiedObject[] CarObjects; ExtensionsCfgParser.ParseExtensionsConfig(CurrentTrainFolder, CurrentTrainEncoding, out CarObjects, TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { if (CarObjects[i] == null) { // load default exterior object string file = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Compatibility"), "exterior.csv"); ObjectManager.StaticObject so = ObjectManager.LoadStaticObject(file, System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); if (so == null) { CarObjects[i] = null; } else { double sx = TrainManager.Trains[k].Cars[i].Width; double sy = TrainManager.Trains[k].Cars[i].Height; double sz = TrainManager.Trains[k].Cars[i].Length; CsvB3dObjectParser.ApplyScale(so, sx, sy, sz); CarObjects[i] = so; } } if (CarObjects[i] != null) { // add object int j = TrainManager.Trains[k].Cars[i].CarSections.Length; Array.Resize <TrainManager.CarSection>(ref TrainManager.Trains[k].Cars[i].CarSections, j + 1); if (CarObjects[i] is ObjectManager.StaticObject) { ObjectManager.StaticObject s = (ObjectManager.StaticObject)CarObjects[i]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements = new ObjectManager.AnimatedObject[1]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0] = new ObjectManager.AnimatedObject(); TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States = new ObjectManager.AnimatedObjectState[1]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States[0].Position = new Vector3(0.0, 0.0, 0.0); TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States[0].Object = s; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].CurrentState = 0; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].ObjectIndex = ObjectManager.CreateDynamicObject(); } else if (CarObjects[i] is ObjectManager.AnimatedObjectCollection) { ObjectManager.AnimatedObjectCollection a = (ObjectManager.AnimatedObjectCollection)CarObjects[i]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements = new ObjectManager.AnimatedObject[a.Objects.Length]; for (int h = 0; h < a.Objects.Length; h++) { TrainManager.Trains[k].Cars[i].CarSections[j].Elements[h] = a.Objects[h]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[h].ObjectIndex = ObjectManager.CreateDynamicObject(); } } } } } // place cars { double z = 0.0; for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].FrontAxlePosition; TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].RearAxlePosition; TrainManager.Trains[k].Cars[i].BeaconReceiver.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].BeaconReceiverPosition; z -= TrainManager.Trains[k].Cars[i].Length; if (i < TrainManager.Trains[k].Cars.Length - 1) { z -= 0.5 * (TrainManager.Trains[k].Couplers[i].MinimumDistanceBetweenCars + TrainManager.Trains[k].Couplers[i].MaximumDistanceBetweenCars); } } } // configure ai / timetable if (TrainManager.Trains[k] == TrainManager.PlayerTrain) { TrainManager.Trains[k].TimetableDelta = 0.0; } else if (TrainManager.Trains[k].State != TrainManager.TrainState.Bogus) { TrainManager.Trains[k].AI = new Game.SimpleHumanDriverAI(TrainManager.Trains[k]); TrainManager.Trains[k].TimetableDelta = Game.PrecedingTrainTimeDeltas[k]; TrainManager.Trains[k].Specs.DoorOpenMode = TrainManager.DoorMode.Manual; TrainManager.Trains[k].Specs.DoorCloseMode = TrainManager.DoorMode.Manual; } } TrainProgress = 1.0; // finished created objects System.Threading.Thread.Sleep(1); if (Cancel) { return; } ObjectManager.FinishCreatingObjects(); // update sections if (Game.Sections.Length > 0) { Game.UpdateSection(Game.Sections.Length - 1); } // load plugin for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i].State != TrainManager.TrainState.Bogus) { if (TrainManager.Trains[i] == TrainManager.PlayerTrain) { if (!PluginManager.LoadCustomPlugin(TrainManager.Trains[i], CurrentTrainFolder, CurrentTrainEncoding)) { PluginManager.LoadDefaultPlugin(TrainManager.Trains[i], CurrentTrainFolder); } } else { PluginManager.LoadDefaultPlugin(TrainManager.Trains[i], CurrentTrainFolder); } } } }
private static void Main(string[] args) { #if !DEBUG // Add handler for UI thread exceptions Application.ThreadException += new ThreadExceptionEventHandler(CrashHandler.UIThreadException); // Force all WinForms errors to go through handler Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // This handler is for catching non-UI thread exceptions AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CrashHandler.CurrentDomain_UnhandledException); #endif //Determine the current CPU architecture- //ARM will generally only support OpenGL-ES PortableExecutableKinds peKind; typeof(object).Module.GetPEKind(out peKind, out CurrentCPUArchitecture); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //--- determine the running environment --- //I wonder if disabling this hack will stop the craashing on Linux.... CurrentlyRunningOnMono = Type.GetType("Mono.Runtime") != null; //Doesn't appear to, but Mono have fixed the button appearance bug CurrentlyRunningOnWindows = Environment.OSVersion.Platform == PlatformID.Win32S | Environment.OSVersion.Platform == PlatformID.Win32Windows | Environment.OSVersion.Platform == PlatformID.Win32NT; Joysticks = new JoystickManager(); CurrentHost = new Host(); try { FileSystem = FileSystem.FromCommandLineArgs(args); FileSystem.CreateFileSystem(); } catch (Exception ex) { MessageBox.Show(Interface.GetInterfaceString("errors_filesystem_invalid") + Environment.NewLine + Environment.NewLine + ex.Message, Interface.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } //Platform specific startup checks if (CurrentlyRunningOnMono && !CurrentlyRunningOnWindows) { // --- Check if we're running as root, and prompt not to --- if (getuid() == 0) { MessageBox.Show( "You are currently running as the root user." + System.Environment.NewLine + "This is a bad idea, please dont!", Interface.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); } } else { if (!System.IO.File.Exists(System.IO.Path.Combine(Environment.SystemDirectory, "OpenAL32.dll"))) { MessageBox.Show( "OpenAL was not found on your system, and will now be installed." + System.Environment.NewLine + System.Environment.NewLine + "Please follow the install prompts.", Interface.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); ProcessStartInfo info = new ProcessStartInfo(System.IO.Path.Combine(FileSystem.DataFolder, "Dependencies\\Win32\\oalinst.exe")); info.UseShellExecute = true; if (Environment.OSVersion.Version.Major >= 6) { info.Verb = "runas"; } try { System.Diagnostics.Process p = System.Diagnostics.Process.Start(info); p.WaitForExit(); } catch (Win32Exception) { MessageBox.Show( "An error occured during OpenAL installation....", Interface.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); } } } // --- load options and controls --- Interface.LoadOptions(); //Switch between SDL2 and native backends; use native backend by default var options = new ToolkitOptions(); if (Interface.CurrentOptions.PreferNativeBackend) { options.Backend = PlatformBackend.PreferNative; } Toolkit.Init(options); // --- load language --- { string folder = Program.FileSystem.GetDataFolder("Languages"); try { string[] LanguageFiles = Directory.GetFiles(folder, "*.cfg"); foreach (var File in LanguageFiles) { Interface.AddLanguage(File); } } catch { MessageBox.Show(@"An error occured whilst attempting to load the default language files."); //Environment.Exit(0); } } Interface.LoadControls(null, out Interface.CurrentControls); { string folder = Program.FileSystem.GetDataFolder("Controls"); string file = OpenBveApi.Path.CombineFile(folder, "Default keyboard assignment.controls"); Interface.Control[] controls; Interface.LoadControls(file, out controls); Interface.AddControls(ref Interface.CurrentControls, controls); } // --- check the command-line arguments for route and train --- formMain.MainDialogResult result = new formMain.MainDialogResult(); CommandLine.ParseArguments(args, ref result); // --- check whether route and train exist --- if (result.RouteFile != null) { if (!System.IO.File.Exists(result.RouteFile)) { result.RouteFile = null; } } if (result.TrainFolder != null) { if (!System.IO.Directory.Exists(result.TrainFolder)) { result.TrainFolder = null; } } // --- if a route was provided but no train, try to use the route default --- if (result.RouteFile != null & result.TrainFolder == null) { bool isRW = string.Equals(System.IO.Path.GetExtension(result.RouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(result.RouteFile, isRW, result.RouteEncoding, null, null, null, true); if (!string.IsNullOrEmpty(Game.TrainName)) { string folder = System.IO.Path.GetDirectoryName(result.RouteFile); while (true) { string trainFolder = OpenBveApi.Path.CombineDirectory(folder, "Train"); if (System.IO.Directory.Exists(trainFolder)) { folder = OpenBveApi.Path.CombineDirectory(trainFolder, Game.TrainName); if (System.IO.Directory.Exists(folder)) { string file = OpenBveApi.Path.CombineFile(folder, "train.dat"); if (System.IO.File.Exists(file)) { result.TrainFolder = folder; result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } break; } if (folder == null) { continue; } System.IO.DirectoryInfo info = System.IO.Directory.GetParent(folder); if (info != null) { folder = info.FullName; } else { break; } } } Game.Reset(false); } // --- show the main menu if necessary --- if (result.RouteFile == null | result.TrainFolder == null) { Joysticks.RefreshJoysticks(); // end HACK // result = formMain.ShowMainDialog(result); } else { result.Start = true; //Apply translations Interface.SetInGameLanguage(Interface.CurrentLanguageCode); } // --- start the actual program --- if (result.Start) { if (Initialize()) { #if !DEBUG try { #endif MainLoop.StartLoopEx(result); #if !DEBUG } catch (Exception ex) { bool found = false; //Thread.Sleep(20); for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i] != null && TrainManager.Trains[i].Plugin != null) { if (TrainManager.Trains[i].Plugin.LastException != null) { CrashHandler.LoadingCrash(ex.Message, true); MessageBox.Show("The train plugin " + TrainManager.Trains[i].Plugin.PluginTitle + " caused a runtime exception: " + TrainManager.Trains[i].Plugin.LastException.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); found = true; RestartArguments = ""; break; } } } if (!found) { MessageBox.Show("The route and train loader encountered the following critical error: " + Environment.NewLine + ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); CrashHandler.LoadingCrash(ex.ToString(), false); RestartArguments = ""; } } #endif } Deinitialize(); } // --- restart the program if necessary --- if (RestartArguments != null) { string arguments; if (FileSystem.RestartArguments.Length != 0 & RestartArguments.Length != 0) { arguments = FileSystem.RestartArguments + " " + RestartArguments; } else { arguments = FileSystem.RestartArguments + RestartArguments; } try { System.Diagnostics.Process.Start(System.IO.File.Exists(FileSystem.RestartProcess) ? FileSystem.RestartProcess : Application.ExecutablePath, arguments); } catch (Exception ex) { MessageBox.Show(ex.Message + "\n\nProcess = " + FileSystem.RestartProcess + "\nArguments = " + arguments, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
// start private static void Start(string[] Args) { // initialize sdl video if (Sdl.SDL_Init(Sdl.SDL_INIT_VIDEO) != 0) { MessageBox.Show("SDL failed to initialize the video subsystem.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } if (Sdl.SDL_Init(Sdl.SDL_INIT_JOYSTICK) != 0) { MessageBox.Show("SDL failed to initialize the joystick subsystem.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } // initialize sdl joysticks { int n = Sdl.SDL_NumJoysticks(); Interface.CurrentJoysticks = new Interface.Joystick[n]; for (int i = 0; i < n; i++) { Interface.CurrentJoysticks[i].SdlHandle = Sdl.SDL_JoystickOpen(i); if (CurrentPlatform == Platform.Windows) { string s = Sdl.SDL_JoystickName(i); /* string returned is ascii packed in utf-16 (2 chars per codepoint) */ System.Text.StringBuilder t = new System.Text.StringBuilder(s.Length << 1); for (int k = 0; k < s.Length; k++) { int a = (int)s[k]; t.Append(char.ConvertFromUtf32(a & 0xFF) + char.ConvertFromUtf32(a >> 8)); } Interface.CurrentJoysticks[i].Name = t.ToString(); } else { Interface.CurrentJoysticks[i].Name = Sdl.SDL_JoystickName(i); } } } // load options and controls Interface.LoadOptions(); Interface.LoadControls(null, out Interface.CurrentControls); { string f = Interface.GetCombinedFileName(Program.FileSystem.GetDataFolder("Controls"), "Default keyboard assignment.controls"); Interface.Control[] c; Interface.LoadControls(f, out c); Interface.AddControls(ref Interface.CurrentControls, c); } // command line arguments formMain.MainDialogResult Result = new formMain.MainDialogResult(); for (int i = 0; i < Args.Length; i++) { if (Args[i].StartsWith("/route=", StringComparison.OrdinalIgnoreCase)) { Result.RouteFile = Args[i].Substring(7); Result.RouteEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.RouteEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.RouteEncodings[j].Value, Result.RouteFile, StringComparison.InvariantCultureIgnoreCase) == 0) { Result.RouteEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.RouteEncodings[j].Codepage); break; } } } else if (Args[i].StartsWith("/train=", StringComparison.OrdinalIgnoreCase)) { Result.TrainFolder = Args[i].Substring(7); Result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, Result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { Result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } // train provided if (Result.TrainFolder != null) { if (System.IO.Directory.Exists(Result.TrainFolder)) { string File = Interface.GetCombinedFileName(Result.TrainFolder, "train.dat"); if (System.IO.File.Exists(File)) { Result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, Result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { Result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); } } } else { Result.TrainFolder = null; } } else { Result.TrainFolder = null; } } // route provided if (Result.RouteFile != null) { if (!System.IO.File.Exists(Result.RouteFile)) { Result.RouteFile = null; } } // route provided but no train if (Result.RouteFile != null & Result.TrainFolder == null) { bool IsRW = string.Equals(System.IO.Path.GetExtension(Result.RouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(Result.RouteFile, IsRW, Result.RouteEncoding, null, null, null, true); if (Game.TrainName != null && Game.TrainName.Length != 0) { string Folder = System.IO.Path.GetDirectoryName(Result.RouteFile); while (true) { string TrainFolder = Interface.GetCombinedFolderName(Folder, "Train"); if (System.IO.Directory.Exists(TrainFolder)) { Folder = Interface.GetCombinedFolderName(TrainFolder, Game.TrainName); if (System.IO.Directory.Exists(Folder)) { string File = Interface.GetCombinedFileName(Folder, "train.dat"); if (System.IO.File.Exists(File)) { // associated train found Result.TrainFolder = Folder; Result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, Result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { Result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } break; } else { System.IO.DirectoryInfo Info = System.IO.Directory.GetParent(Folder); if (Info != null) { Folder = Info.FullName; } else { break; } } } } Game.Reset(false); } // show main menu if applicable if (Result.RouteFile == null | Result.TrainFolder == null) { Result = formMain.ShowMainDialog(); if (!Result.Start) { return; } } // screen int Width = Interface.CurrentOptions.FullscreenMode ? Interface.CurrentOptions.FullscreenWidth : Interface.CurrentOptions.WindowWidth; int Height = Interface.CurrentOptions.FullscreenMode ? Interface.CurrentOptions.FullscreenHeight : Interface.CurrentOptions.WindowHeight; if (Width < 16) { Width = 16; } if (Height < 16) { Height = 16; } Renderer.ScreenWidth = Width; Renderer.ScreenHeight = Height; World.AspectRatio = (double)Renderer.ScreenWidth / (double)Renderer.ScreenHeight; const double degree = 0.0174532925199433; World.VerticalViewingAngle = 45.0 * degree; World.HorizontalViewingAngle = 2.0 * Math.Atan(Math.Tan(0.5 * World.VerticalViewingAngle) * World.AspectRatio); World.OriginalVerticalViewingAngle = World.VerticalViewingAngle; World.ExtraViewingDistance = 50.0; World.ForwardViewingDistance = (double)Interface.CurrentOptions.ViewingDistance; World.BackwardViewingDistance = 0.0; World.BackgroundImageDistance = (double)Interface.CurrentOptions.ViewingDistance; // load route and train SoundManager.Initialize(); if (!Loading.Load(Result.RouteFile, Result.RouteEncoding, Result.TrainFolder, Result.TrainEncoding)) { return; } Game.LogRouteName = System.IO.Path.GetFileName(Result.RouteFile); Game.LogTrainName = System.IO.Path.GetFileName(Result.TrainFolder); Game.LogDateTime = DateTime.Now; // initialize sdl window Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_DOUBLEBUFFER, 1); Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_DEPTH_SIZE, 24); Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_RED_SIZE, 8); Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_GREEN_SIZE, 8); Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_BLUE_SIZE, 8); Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_SWAP_CONTROL, Interface.CurrentOptions.VerticalSynchronization ? 1 : 0); Sdl.SDL_ShowCursor(Sdl.SDL_DISABLE); SdlWindowCreated = true; int Bits = Interface.CurrentOptions.FullscreenMode ? Interface.CurrentOptions.FullscreenBits : 32; // --- window caption and icon --- Sdl.SDL_WM_SetCaption(Application.ProductName, null); { string bitmapFile = OpenBveApi.Path.CombineFile(Program.FileSystem.DataFolder, "icon.bmp"); IntPtr bitmap = Sdl.SDL_LoadBMP(bitmapFile); if (bitmap != null) { string maskFile = OpenBveApi.Path.CombineFile(Program.FileSystem.DataFolder, "mask.bin"); byte[] mask = System.IO.File.ReadAllBytes(maskFile); Sdl.SDL_WM_SetIcon(bitmap, mask); } } // create window int fullscreen = Interface.CurrentOptions.FullscreenMode ? Sdl.SDL_FULLSCREEN : 0; IntPtr video = Sdl.SDL_SetVideoMode(Width, Height, Bits, Sdl.SDL_OPENGL | Sdl.SDL_DOUBLEBUF | fullscreen); if (video != IntPtr.Zero) { // anisotropic filtering string[] Extensions = Gl.glGetString(Gl.GL_EXTENSIONS).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); Interface.CurrentOptions.AnisotropicFilteringMaximum = 0; for (int i = 0; i < Extensions.Length; i++) { if (string.Compare(Extensions[i], "GL_EXT_texture_filter_anisotropic", StringComparison.OrdinalIgnoreCase) == 0) { float n; Gl.glGetFloatv(Gl.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, out n); Interface.CurrentOptions.AnisotropicFilteringMaximum = (int)Math.Round((double)n); break; } } if (Interface.CurrentOptions.AnisotropicFilteringMaximum <= 0) { Interface.CurrentOptions.AnisotropicFilteringMaximum = 0; Interface.CurrentOptions.AnisotropicFilteringLevel = 0; } else if (Interface.CurrentOptions.AnisotropicFilteringLevel == 0 & Interface.CurrentOptions.AnisotropicFilteringMaximum > 0) { Interface.CurrentOptions.AnisotropicFilteringLevel = Interface.CurrentOptions.AnisotropicFilteringMaximum; } else if (Interface.CurrentOptions.AnisotropicFilteringLevel > Interface.CurrentOptions.AnisotropicFilteringMaximum) { Interface.CurrentOptions.AnisotropicFilteringLevel = Interface.CurrentOptions.AnisotropicFilteringMaximum; } // module initialization Fonts.Initialize(); Renderer.Initialize(); Renderer.InitializeLighting(); Sdl.SDL_GL_SwapBuffers(); Timetable.CreateTimetable(); // camera MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); MainLoop.InitializeMotionBlur(); // start loop MainLoop.StartLoop(); } else { // failed MessageBox.Show("SDL failed to create the window.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); } }
private static void LoadEverythingThreaded() { string RailwayFolder = GetRailwayFolder(CurrentRouteFile); string ObjectFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Object"); string SoundFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Sound"); // string CompatibilityFolder = OpenBveApi.Path.CombineDirectory(Application.StartupPath, "Compatibility"); Program.Renderer.Camera.CurrentMode = CameraViewMode.Track; // load route bool IsRW = string.Equals(System.IO.Path.GetExtension(CurrentRouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(CurrentRouteFile, IsRW, CurrentRouteEncoding, Application.StartupPath, ObjectFolder, SoundFolder, false); Program.Renderer.CameraTrackFollower = new TrackFollower(Program.CurrentHost); System.Threading.Thread.Sleep(1); if (Cancel) { return; } Program.CurrentRoute.Atmosphere.CalculateSeaLevelConstants(); RouteProgress = 1.0; // camera Program.Renderer.CameraTrackFollower.UpdateAbsolute(0.0, true, false); Program.Renderer.CameraTrackFollower.UpdateAbsolute(0.1, true, false); Program.Renderer.CameraTrackFollower.UpdateAbsolute(-0.1, true, false); Program.Renderer.CameraTrackFollower.TriggerType = EventTriggerType.Camera; // default starting time Game.SecondsSinceMidnight = 0.0; Game.StartupTime = 0.0; // finished created objects System.Threading.Thread.Sleep(1); if (Cancel) { return; } // signals System.Threading.Thread.Sleep(1); if (Cancel) { return; } // ReSharper disable once CoVariantArrayConversion Program.CurrentRoute.Trains = TrainManager.Trains; Program.CurrentRoute.UpdateAllSections(); // starting track position System.Threading.Thread.Sleep(1); if (Cancel) { return; } // int FirstStationIndex = -1; double FirstStationPosition = 0.0; for (int i = 0; i < Program.CurrentRoute.Stations.Length; i++) { if (Program.CurrentRoute.Stations[i].Stops.Length != 0) { // FirstStationIndex = i; FirstStationPosition = Program.CurrentRoute.Stations[i].Stops[Program.CurrentRoute.Stations[i].Stops.Length - 1].TrackPosition; if (Program.CurrentRoute.Stations[i].ArrivalTime < 0.0) { if (Program.CurrentRoute.Stations[i].DepartureTime < 0.0) { Game.SecondsSinceMidnight = 0.0; } else { Game.SecondsSinceMidnight = Program.CurrentRoute.Stations[i].DepartureTime - Program.CurrentRoute.Stations[i].StopTime; } } else { Game.SecondsSinceMidnight = Program.CurrentRoute.Stations[i].ArrivalTime; } Game.StartupTime = Game.SecondsSinceMidnight; break; } } // initialize camera Program.Renderer.CameraTrackFollower.UpdateAbsolute(-1.0, true, false); Program.Renderer.CameraTrackFollower.UpdateAbsolute(FirstStationPosition, true, false); Program.Renderer.Camera.Alignment = new CameraAlignment(new Vector3(0.0, 2.5, 0.0), 0.0, 0.0, 0.0, FirstStationPosition, 1.0); World.UpdateAbsoluteCamera(0.0); Complete = true; }
private void BtnProcessRouteClick(object sender, EventArgs e) { // Start wait cursor. this.Cursor = Cursors.WaitCursor; ListViewItem item1 = new ListViewItem("Type", 0); ListViewItem item2 = new ListViewItem("Description", 1); lvMessages.Clear(); lvMessages.Columns.Add("Type", 90, HorizontalAlignment.Left); lvMessages.Columns.Add("Description", 700, HorizontalAlignment.Left); bool bDike = cbDikeReport.Checked; bool bPole = cbPoleReport.Checked; bool bRail = cbRailReport.Checked; bool bWall = cbWallReport.Checked; try{ Game.Reset(); bool IsRW = string.Equals(System.IO.Path.GetExtension(strFilePath), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(strFilePath, IsRW, System.Text.Encoding.UTF8, Application.StartupPath, this.ObjectFolder, this.SoundFolder, false, bDike, bPole, bRail, bWall); }catch (Exception ex) { switch (ex.GetType().ToString()) { case "System.TypeLoadException": //Normally caused by attempting to use this in an older openBVE version var ec = ex as System.TypeLoadException; if (ec.TypeName.StartsWith("OpenBveApi")) { MessageBox.Show("Route Checker has failed to load the openBVE API. \n\nPlease make sure that your openBVE version is 1.5.0 or above.", "Route Checker Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show("Route Checker has failed to load the following library: \n\n" + ec.TypeName, "Route Checker Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } break; default: MessageBox.Show("Route Checker has experienced the following error:\n\n" + ex.Message + "\n\nPlease make sure you are running Route Checker in the OpenBVE directory.", "Route Checker Error", MessageBoxButtons.OK, MessageBoxIcon.Error); break; } } lvMessages.SmallImageList = new ImageList(); try { lvMessages.SmallImageList.Images.Add("information", Image.FromFile(OpenBveApi.Path.CombineDirectory(this.DataFolder, "icon_information.png"))); } catch { } try { lvMessages.SmallImageList.Images.Add("warning", Image.FromFile(OpenBveApi.Path.CombineDirectory(this.DataFolder, "icon_warning.png"))); } catch { } try { lvMessages.SmallImageList.Images.Add("error", Image.FromFile(OpenBveApi.Path.CombineDirectory(this.DataFolder, "icon_error.png"))); } catch { } try { lvMessages.SmallImageList.Images.Add("critical", Image.FromFile(OpenBveApi.Path.CombineDirectory(this.DataFolder, "icon_critical.png"))); } catch { } Trace.WriteLine(Interface.MessageCount); for (int i = 0; i < Interface.MessageCount; i++) { string t = "Unknown"; string g = "information"; switch (Interface.Messages[i].Type) { case Interface.MessageType.Information: t = "Information"; g = "information"; break; case Interface.MessageType.Warning: t = "Warning"; g = "warning"; break; case Interface.MessageType.Error: t = "Error"; g = "error"; break; case Interface.MessageType.Critical: t = "Critical"; g = "critical"; break; } ListViewItem a = lvMessages.Items.Add(t, g); a.SubItems.Add(Interface.Messages[i].Text); } // Avoid column resizing when no text is present. if (Interface.MessageCount > 0) { lvMessages.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); btnClipboard.Enabled = true; } else { ListViewItem a = lvMessages.Items.Add("Information", "Information"); a.SubItems.Add("Nothing to report."); } int j = 0; Color shaded = Color.FromArgb(240, 240, 240); foreach (ListViewItem item in lvMessages.Items) { if (j++ % 2 == 1) { item.BackColor = shaded; item.UseItemStyleForSubItems = true; } } // Toggle the CSV export button. if (Path.GetExtension(strFilePath).ToLower() == ".rw") { btnExportCsv.Enabled = true; } // Stop wait cursor. this.Cursor = Cursors.Default; }