// load route internal static bool LoadRoute() { CurrentStation = -1; Game.Reset(); Renderer.Initialize(); UpdateViewport(); bool result; try { Loading.Load(CurrentRoute, System.Text.Encoding.UTF8); result = true; } catch (Exception ex) { MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); Game.Reset(); CurrentRoute = null; result = false; } Renderer.InitializeLighting(); ObjectManager.InitializeVisibility(); Textures.UnloadAllTextures(); return(result); }
protected override void OnClosing(CancelEventArgs e) { // Minor hack: // If we are currently loading, catch the first close event, and terminate the loader threads // before actually closing the game-window. if (Loading.Cancel == true) { return; } if (!Loading.Complete) { e.Cancel = true; Loading.Cancel = true; } for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i].State != TrainManager.TrainState.Bogus) { PluginManager.UnloadPlugin(TrainManager.Trains[i]); } } Textures.UnloadAllTextures(); for (int i = 0; i < InputDevicePlugin.AvailablePluginInfos.Count; i++) { InputDevicePlugin.CallPluginUnload(i); } if (MainLoop.Quit == MainLoop.QuitMode.ContinueGame && Program.CurrentlyRunningOnMono) { //More forcefully close under Mono, stuff *still* hanging around.... Environment.Exit(0); } base.OnClosing(e); }
internal static void DragFile(object sender, FileDropEventArgs e) { int n = Files.Length; Array.Resize <string>(ref Files, n + 1); Files[n] = e.FileName; // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); Textures.UnloadAllTextures(); //Fonts.Initialize(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif if (String.Compare(System.IO.Path.GetFileName(Files[i]), "extensions.cfg", StringComparison.OrdinalIgnoreCase) == 0) { UnifiedObject[] carObjects; UnifiedObject[] bogieObjects; TrainManager.Train train; ExtensionsCfgParser.ParseExtensionsConfig(Files[i], System.Text.Encoding.UTF8, out carObjects, out bogieObjects, out train, true); double z = 0.0; for (int j = 0; j < carObjects.Length; j++) { ObjectManager.CreateObject(carObjects[j], new Vector3(0.0, 0.0, z), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); if (j < train.Cars.Length - 1) { z -= (train.Cars[j].Length + train.Cars[j + 1].Length) / 2; } } } else { UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, false, false, false); ObjectManager.CreateObject(o, Vector3.Zero, new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); } #if !DEBUG } catch (Exception ex) { Interface.AddMessage(MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); }
/// <summary>Changes to or from fullscreen mode.</summary> internal static void ToggleFullscreen() { Fullscreen = !Fullscreen; // begin HACK // Renderer.ClearDisplayLists(); if (World.MouseGrabEnabled) { SDL.SDL_SetRelativeMouseMode(SDL.SDL_bool.SDL_FALSE); } GL.Disable(EnableCap.Fog); Renderer.FogEnabled = false; GL.Disable(EnableCap.Lighting); Renderer.LightingEnabled = false; Textures.UnloadAllTextures(); if (Fullscreen) { SDL.SDL_SetWindowSize(Window, Options.Current.FullscreenWidth, Options.Current.FullscreenHeight); SDL.SDL_SetWindowFullscreen(Window, (uint)SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN); Width = Options.Current.FullscreenWidth; Height = Options.Current.FullscreenHeight; } else { SDL.SDL_SetWindowSize(Window, Options.Current.WindowWidth, Options.Current.WindowHeight); SDL.SDL_SetWindowFullscreen(Window, 0); Width = Options.Current.WindowWidth; Height = Options.Current.WindowHeight; } Renderer.InitializeLighting(); MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); MainLoop.InitializeMotionBlur(); Timetable.CreateTimetable(); Timetable.UpdateCustomTimetable(null, null); if (World.MouseGrabEnabled) { SDL.SDL_SetRelativeMouseMode(SDL.SDL_bool.SDL_TRUE); } World.MouseGrabTarget = new OpenBveApi.Math.Vector2D(0.0, 0.0); World.MouseGrabIgnoreOnce = true; World.InitializeCameraRestriction(); if (Renderer.OptionBackfaceCulling) { GL.Enable(EnableCap.CullFace); } else { GL.Disable(EnableCap.CullFace); } Renderer.ReAddObjects(); // end HACK // }
/// <summary>Changes to or from fullscreen mode.</summary> internal static void ToggleFullscreen() { Fullscreen = !Fullscreen; // begin HACK // Renderer.ClearDisplayLists(); if (World.MouseGrabEnabled) { Sdl.SDL_WM_GrabInput(Sdl.SDL_GRAB_OFF); } Gl.glDisable(Gl.GL_FOG); Renderer.FogEnabled = false; Gl.glDisable(Gl.GL_LIGHTING); Renderer.LightingEnabled = false; Textures.UnloadAllTextures(); if (Fullscreen) { Sdl.SDL_SetVideoMode(Interface.CurrentOptions.FullscreenWidth, Interface.CurrentOptions.FullscreenHeight, Interface.CurrentOptions.FullscreenBits, Sdl.SDL_OPENGL | Sdl.SDL_DOUBLEBUF | Sdl.SDL_FULLSCREEN); Width = Interface.CurrentOptions.FullscreenWidth; Height = Interface.CurrentOptions.FullscreenHeight; } else { Sdl.SDL_SetVideoMode(Interface.CurrentOptions.WindowWidth, Interface.CurrentOptions.WindowHeight, 32, Sdl.SDL_OPENGL | Sdl.SDL_DOUBLEBUF); Width = Interface.CurrentOptions.WindowWidth; Height = Interface.CurrentOptions.WindowHeight; } Renderer.InitializeLighting(); MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); MainLoop.InitializeMotionBlur(); Timetable.CreateTimetable(); Timetable.UpdateCustomTimetable(null, null); if (World.MouseGrabEnabled) { Sdl.SDL_WM_GrabInput(Sdl.SDL_GRAB_ON); } World.MouseGrabTarget = new World.Vector2D(0.0, 0.0); World.MouseGrabIgnoreOnce = true; World.InitializeCameraRestriction(); if (Renderer.OptionBackfaceCulling) { Gl.glEnable(Gl.GL_CULL_FACE); } else { Gl.glDisable(Gl.GL_CULL_FACE); } Renderer.ReAddObjects(); // end HACK // }
internal static void DragFile(object sender, FileDropEventArgs e) { int n = Files.Length; Array.Resize <string>(ref Files, n + 1); Files[n] = e.FileName; // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); Textures.UnloadAllTextures(); //Fonts.Initialize(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); }
internal static void UpdateGraphicsSettings() { if (Program.CurrentRoute != null) { Program.CurrentlyLoading = true; Renderer.RenderScene(0.0); Program.currentGameWindow.SwapBuffers(); World.CameraAlignment a = World.CameraCurrentAlignment; Textures.UnloadAllTextures(); if (Program.LoadRoute()) { World.CameraCurrentAlignment = a; TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, -1.0, true, false); TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, a.TrackPosition, true, false); World.CameraAlignmentDirection = new World.CameraAlignment(); World.CameraAlignmentSpeed = new World.CameraAlignment(); ObjectManager.UpdateVisibility(a.TrackPosition, true); ObjectManager.UpdateAnimatedWorldObjects(0.0, true); } Program.CurrentlyLoading = false; } }
internal static void Main(string[] args) { CurrentlyRunOnMono = Type.GetType("Mono.Runtime") != null; CurrentHost = new Host(); // file system FileSystem = FileSystem.FromCommandLineArgs(args); FileSystem.CreateFileSystem(); Plugins.LoadPlugins(); // command line arguments SkipArgs = new bool[args.Length]; if (args.Length != 0) { string File = System.IO.Path.Combine(Application.StartupPath, "RouteViewer.exe"); if (System.IO.File.Exists(File)) { int Skips = 0; System.Text.StringBuilder NewArgs = new System.Text.StringBuilder(); for (int i = 0; i < args.Length; i++) { if (args[i] != null && System.IO.File.Exists(args[i])) { if (System.IO.Path.GetExtension(args[i]).Equals(".csv", StringComparison.OrdinalIgnoreCase)) { string Text = System.IO.File.ReadAllText(args[i], System.Text.Encoding.UTF8); if (Text.Length != -1 && Text.IndexOf("CreateMeshBuilder", StringComparison.OrdinalIgnoreCase) == -1) { if (NewArgs.Length != 0) { NewArgs.Append(" "); } NewArgs.Append("\"" + args[i] + "\""); SkipArgs[i] = true; Skips++; } } } else { SkipArgs[i] = true; Skips++; } } if (NewArgs.Length != 0) { System.Diagnostics.Process.Start(File, NewArgs.ToString()); } if (Skips == args.Length) { return; } } } Options.LoadOptions(); Interface.CurrentOptions.ObjectOptimizationBasicThreshold = 1000; Interface.CurrentOptions.ObjectOptimizationFullThreshold = 250; Interface.CurrentOptions.AntialiasingLevel = 16; Interface.CurrentOptions.AnisotropicFilteringLevel = 16; // initialize camera currentGraphicsMode = new GraphicsMode(new ColorFormat(8, 8, 8, 8), 24, 8, Interface.CurrentOptions.AntialiasingLevel); currentGameWindow = new ObjectViewer(Renderer.ScreenWidth, Renderer.ScreenHeight, currentGraphicsMode, "Object Viewer", GameWindowFlags.Default); currentGameWindow.Visible = true; currentGameWindow.TargetUpdateFrequency = 0; currentGameWindow.TargetRenderFrequency = 0; currentGameWindow.Title = "Object Viewer"; currentGameWindow.Run(); // quit Textures.UnloadAllTextures(); }
// process events internal static void KeyDown(object sender, KeyboardKeyEventArgs e) { switch (e.Key) { case Key.LShift: case Key.RShift: ShiftPressed = true; break; case Key.F5: // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); Textures.UnloadAllTextures(); //Fonts.Initialize(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif if (String.Compare(System.IO.Path.GetFileName(Files[i]), "extensions.cfg", StringComparison.OrdinalIgnoreCase) == 0) { UnifiedObject[] carObjects; UnifiedObject[] bogieObjects; double[] axleLocations; TrainManager.Train train; ExtensionsCfgParser.ParseExtensionsConfig(Files[i], System.Text.Encoding.UTF8, out carObjects, out bogieObjects, out axleLocations, out train, true); if (axleLocations.Length == 0) { axleLocations = new double[train.Cars.Length * 2]; for (int j = 0; j < train.Cars.Length; j++) { double ap = train.Cars.Length * 0.4; axleLocations[j] = ap; j++; axleLocations[j] = -ap; } } double z = 0.0; for (int j = 0; j < carObjects.Length; j++) { ObjectManager.CreateObject(carObjects[j], new Vector3(0.0, 0.0, z), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); if (j < train.Cars.Length - 1) { z -= (train.Cars[j].Length + train.Cars[j + 1].Length) / 2; } } z = 0.0; for (int j = 0; j < bogieObjects.Length; j++) { ObjectManager.CreateObject(bogieObjects[j], new Vector3(0.0, 0.0, z + axleLocations[j]), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); j++; ObjectManager.CreateObject(bogieObjects[j], new Vector3(0.0, 0.0, z - axleLocations[j]), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); if (j < train.Cars.Length - 1) { z -= (train.Cars[j].Length + train.Cars[j + 1].Length) / 2; } } } else { UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, false, false, false); ObjectManager.CreateObject(o, Vector3.Zero, new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); } #if !DEBUG } catch (Exception ex) { Interface.AddMessage(MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); break; case Key.F7: { OpenFileDialog Dialog = new OpenFileDialog { CheckFileExists = true, Multiselect = true, Filter = @"All supported object files|*.csv;*.b3d;*.x;*.animated;extensions.cfg;*.l3dobj;*.l3dgrp;*.obj;*.s|openBVE Objects|*.csv;*.b3d;*.x;*.animated;extensions.cfg|LokSim 3D Objects|*.l3dobj;*.l3dgrp|Wavefront Objects|*.obj|Microsoft Train Simulator Objects|*.s|All files|*" }; if (Dialog.ShowDialog() == DialogResult.OK) { Application.DoEvents(); string[] f = Dialog.FileNames; int n = Files.Length; Array.Resize <string>(ref Files, n + f.Length); for (int i = 0; i < f.Length; i++) { Files[n + i] = f[i]; } // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); Textures.UnloadAllTextures(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif if (String.Compare(System.IO.Path.GetFileName(Files[i]), "extensions.cfg", StringComparison.OrdinalIgnoreCase) == 0) { UnifiedObject[] carObjects; UnifiedObject[] bogieObjects; double[] axleLocations; TrainManager.Train train; ExtensionsCfgParser.ParseExtensionsConfig(Files[i], System.Text.Encoding.UTF8, out carObjects, out bogieObjects, out axleLocations, out train, true); if (axleLocations.Length == 0) { axleLocations = new double[train.Cars.Length * 2]; for (int j = 0; j < train.Cars.Length; j++) { double ap = train.Cars.Length * 0.4; axleLocations[j] = ap; j++; axleLocations[j] = -ap; } } double z = 0.0; for (int j = 0; j < carObjects.Length; j++) { ObjectManager.CreateObject(carObjects[j], new Vector3(0.0, 0.0, z), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); if (j < train.Cars.Length - 1) { z -= (train.Cars[j].Length + train.Cars[j + 1].Length) / 2; } } z = 0.0; for (int j = 0; j < bogieObjects.Length; j++) { ObjectManager.CreateObject(bogieObjects[j], new Vector3(0.0, 0.0, z + axleLocations[j]), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); j++; ObjectManager.CreateObject(bogieObjects[j], new Vector3(0.0, 0.0, z - axleLocations[j]), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); if (j < train.Cars.Length - 1) { z -= (train.Cars[j].Length + train.Cars[j + 1].Length) / 2; } } } else { UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, false, false, false); ObjectManager.CreateObject(o, Vector3.Zero, new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); } #if !DEBUG } catch (Exception ex) { Interface.AddMessage(MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); } else { if (Program.CurrentlyRunOnMono) { //HACK: Dialog doesn't close properly when pressing the ESC key under Mono //Avoid calling Application.DoEvents() unless absolutely necessary though! Application.DoEvents(); } } Dialog.Dispose(); } break; case Key.F9: if (Interface.MessageCount != 0) { formMessages.ShowMessages(); Application.DoEvents(); } break; case Key.Delete: ReducedMode = false; LightingRelative = -1.0; Game.Reset(); Textures.UnloadAllTextures(); //Fonts.Initialize(); Interface.ClearMessages(); Files = new string[] { }; break; case Key.Left: RotateX = -1; ReducedMode = false; break; case Key.Right: RotateX = 1; ReducedMode = false; break; case Key.Up: RotateY = -1; ReducedMode = false; break; case Key.Down: RotateY = 1; ReducedMode = false; break; case Key.A: case Key.Keypad4: MoveX = -1; ReducedMode = false; break; case Key.D: case Key.Keypad6: MoveX = 1; ReducedMode = false; break; case Key.Keypad8: MoveY = 1; ReducedMode = false; break; case Key.Keypad2: MoveY = -1; ReducedMode = false; break; case Key.W: case Key.Keypad9: MoveZ = 1; ReducedMode = false; break; case Key.S: case Key.Keypad3: MoveZ = -1; ReducedMode = false; break; case Key.Keypad5: ResetCamera(); break; case Key.F: case Key.F1: Renderer.OptionWireframe = !Renderer.OptionWireframe; if (Renderer.OptionWireframe) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } else { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } break; case Key.N: case Key.F2: Renderer.OptionNormals = !Renderer.OptionNormals; break; case Key.L: case Key.F3: LightingTarget = 1 - LightingTarget; ReducedMode = false; break; case Key.I: case Key.F4: Renderer.OptionInterface = !Renderer.OptionInterface; ReducedMode = false; break; case Key.F8: formOptions.ShowOptions(); Application.DoEvents(); break; case Key.F10: formTrain.ShowTrainSettings(); break; case Key.G: case Key.C: Renderer.OptionCoordinateSystem = !Renderer.OptionCoordinateSystem; ReducedMode = false; break; case Key.B: if (ShiftPressed) { ColorDialog dialog = new ColorDialog(); dialog.FullOpen = true; if (dialog.ShowDialog() == DialogResult.OK) { Renderer.BackgroundColor = -1; Renderer.ApplyBackgroundColor(dialog.Color.R, dialog.Color.G, dialog.Color.B); } } else { Renderer.BackgroundColor++; if (Renderer.BackgroundColor >= Renderer.MaxBackgroundColor) { Renderer.BackgroundColor = 0; } Renderer.ApplyBackgroundColor(); } ReducedMode = false; break; } }
/// <summary>This method is called once the route and train data have been preprocessed, in order to physically setup the simulation</summary> private void SetupSimulation() { if (Loading.Cancel) { Close(); } Timetable.CreateTimetable(); //Check if any critical errors have occured during the route or train loading for (int i = 0; i < Interface.MessageCount; i++) { if (Interface.Messages[i].Type == Interface.MessageType.Critical) { MessageBox.Show("A critical error has occured:\n\n" + Interface.Messages[i].Text + "\n\nPlease inspect the error log file for further information.", "Load", MessageBoxButtons.OK, MessageBoxIcon.Hand); Close(); } } Renderer.InitializeLighting(); Game.LogRouteName = System.IO.Path.GetFileName(MainLoop.currentResult.RouteFile); Game.LogTrainName = System.IO.Path.GetFileName(MainLoop.currentResult.TrainFolder); Game.LogDateTime = DateTime.Now; if (Interface.CurrentOptions.LoadInAdvance) { Textures.LoadAllTextures(); } else { Textures.UnloadAllTextures(); } // camera ObjectManager.InitializeVisibility(); World.CameraTrackFollower.Update(0.0, true, false); World.CameraTrackFollower.Update(-0.1, true, false); World.CameraTrackFollower.Update(0.1, true, false); World.CameraTrackFollower.TriggerType = TrackManager.EventTriggerType.Camera; // starting time and track position Game.SecondsSinceMidnight = 0.0; Game.StartupTime = 0.0; int PlayerFirstStationIndex = -1; double PlayerFirstStationPosition; int os = -1; bool f = false; for (int i = 0; i < Game.Stations.Length; i++) { if (!String.IsNullOrEmpty(Game.InitialStationName)) { if (Game.InitialStationName.ToLowerInvariant() == Game.Stations[i].Name.ToLowerInvariant()) { PlayerFirstStationIndex = i; } } if (Game.Stations[i].StopMode == StationStopMode.AllStop | Game.Stations[i].StopMode == StationStopMode.PlayerStop & Game.Stations[i].Stops.Length != 0) { if (f == false) { os = i; f = true; } } } if (PlayerFirstStationIndex == -1) { PlayerFirstStationIndex = os; } { int s = Game.GetStopIndex(PlayerFirstStationIndex, TrainManager.PlayerTrain.Cars.Length); if (s >= 0) { PlayerFirstStationPosition = Game.Stations[PlayerFirstStationIndex].Stops[s].TrackPosition; double TrainLength = 0.0; for (int c = 0; c < TrainManager.Trains[TrainManager.PlayerTrain.TrainIndex].Cars.Length; c++) { TrainLength += TrainManager.Trains[TrainManager.PlayerTrain.TrainIndex].Cars[c].Length; } for (int j = 0; j < Game.BufferTrackPositions.Length; j++) { if (PlayerFirstStationPosition > Game.BufferTrackPositions[j] && PlayerFirstStationPosition - TrainLength < Game.BufferTrackPositions[j]) { /* * HACK: The initial start position for the player train is stuck on a set of buffers * This means we have to make some one the fly adjustments to the first station stop position */ //Set the start position to be the buffer position plus the train length plus 1m PlayerFirstStationPosition = Game.BufferTrackPositions[j] + TrainLength + 1; //Update the station stop location if (s >= 0) { Game.Stations[PlayerFirstStationIndex].Stops[s].TrackPosition = PlayerFirstStationPosition; } else { Game.Stations[PlayerFirstStationIndex].DefaultTrackPosition = PlayerFirstStationPosition; } break; } } } else { PlayerFirstStationPosition = Game.Stations[PlayerFirstStationIndex].DefaultTrackPosition; } if (Game.InitialStationTime != -1) { Game.SecondsSinceMidnight = Game.InitialStationTime; Game.StartupTime = Game.InitialStationTime; } else { if (Game.Stations[PlayerFirstStationIndex].ArrivalTime < 0.0) { if (Game.Stations[PlayerFirstStationIndex].DepartureTime < 0.0) { Game.SecondsSinceMidnight = 0.0; Game.StartupTime = 0.0; } else { Game.SecondsSinceMidnight = Game.Stations[PlayerFirstStationIndex].DepartureTime - Game.Stations[PlayerFirstStationIndex].StopTime; Game.StartupTime = Game.Stations[PlayerFirstStationIndex].DepartureTime - Game.Stations[PlayerFirstStationIndex].StopTime; } } else { Game.SecondsSinceMidnight = Game.Stations[PlayerFirstStationIndex].ArrivalTime; Game.StartupTime = Game.Stations[PlayerFirstStationIndex].ArrivalTime; } } } int OtherFirstStationIndex = -1; double OtherFirstStationPosition = 0.0; double OtherFirstStationTime = 0.0; for (int i = 0; i < Game.Stations.Length; i++) { if (Game.Stations[i].StopMode == StationStopMode.AllStop | Game.Stations[i].StopMode == StationStopMode.PlayerPass & Game.Stations[i].Stops.Length != 0) { OtherFirstStationIndex = i; int s = Game.GetStopIndex(i, TrainManager.PlayerTrain.Cars.Length); if (s >= 0) { OtherFirstStationPosition = Game.Stations[i].Stops[s].TrackPosition; } else { OtherFirstStationPosition = Game.Stations[i].DefaultTrackPosition; } if (Game.Stations[i].ArrivalTime < 0.0) { if (Game.Stations[i].DepartureTime < 0.0) { OtherFirstStationTime = 0.0; } else { OtherFirstStationTime = Game.Stations[i].DepartureTime - Game.Stations[i].StopTime; } } else { OtherFirstStationTime = Game.Stations[i].ArrivalTime; } break; } } if (Game.PrecedingTrainTimeDeltas.Length != 0) { OtherFirstStationTime -= Game.PrecedingTrainTimeDeltas[Game.PrecedingTrainTimeDeltas.Length - 1]; if (OtherFirstStationTime < Game.SecondsSinceMidnight) { Game.SecondsSinceMidnight = OtherFirstStationTime; } } // initialize trains for (int i = 0; i < TrainManager.Trains.Length; i++) { TrainManager.Trains[i].Initialize(); int s = i == TrainManager.PlayerTrain.TrainIndex ? PlayerFirstStationIndex : OtherFirstStationIndex; if (s >= 0) { if (Game.Stations[s].OpenLeftDoors) { for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++) { TrainManager.Trains[i].Cars[j].Doors[0].AnticipatedOpen = true; } } if (Game.Stations[s].OpenRightDoors) { for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++) { TrainManager.Trains[i].Cars[j].Doors[1].AnticipatedOpen = true; } } } if (Game.Sections.Length != 0) { Game.Sections[0].Enter(TrainManager.Trains[i]); } for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++) { double length = TrainManager.Trains[i].Cars[0].Length; TrainManager.Trains[i].Cars[j].Move(-length, 0.01); TrainManager.Trains[i].Cars[j].Move(length, 0.01); } } // score Game.CurrentScore.ArrivalStation = PlayerFirstStationIndex + 1; Game.CurrentScore.DepartureStation = PlayerFirstStationIndex; Game.CurrentScore.Maximum = 0; for (int i = 0; i < Game.Stations.Length; i++) { if (i != PlayerFirstStationIndex & Game.PlayerStopsAtStation(i)) { if (i == 0 || Game.Stations[i - 1].Type != StationType.ChangeEnds) { Game.CurrentScore.Maximum += Game.ScoreValueStationArrival; } } } if (Game.CurrentScore.Maximum <= 0) { Game.CurrentScore.Maximum = Game.ScoreValueStationArrival; } // signals if (Game.Sections.Length > 0) { Game.UpdateSection(Game.Sections.Length - 1); } // move train in position for (int i = 0; i < TrainManager.Trains.Length; i++) { double p; if (i == TrainManager.PlayerTrain.TrainIndex) { p = PlayerFirstStationPosition; } else if (TrainManager.Trains[i].State == TrainManager.TrainState.Bogus) { p = Game.BogusPretrainInstructions[0].TrackPosition; TrainManager.Trains[i].AI = new Game.BogusPretrainAI(TrainManager.Trains[i]); } else { p = OtherFirstStationPosition; } for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++) { TrainManager.Trains[i].Cars[j].Move(p, 0.01); } } // timetable if (Timetable.DefaultTimetableDescription.Length == 0) { Timetable.DefaultTimetableDescription = Game.LogTrainName; } // initialize camera if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) { World.CameraMode = World.CameraViewMode.InteriorLookAhead; } //Place the initial camera in the driver car TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].UpdateCamera(); World.CameraTrackFollower.Update(-1.0, true, false); ObjectManager.UpdateVisibility(World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z); World.CameraSavedExterior = new World.CameraAlignment(new OpenBveApi.Math.Vector3(-2.5, 1.5, -15.0), 0.3, -0.2, 0.0, PlayerFirstStationPosition, 1.0); World.CameraSavedTrack = new World.CameraAlignment(new OpenBveApi.Math.Vector3(-3.0, 2.5, 0.0), 0.3, 0.0, 0.0, TrainManager.PlayerTrain.Cars[0].FrontAxle.Follower.TrackPosition - 10.0, 1.0); // signalling sections for (int i = 0; i < TrainManager.Trains.Length; i++) { int s = TrainManager.Trains[i].CurrentSectionIndex; Game.Sections[s].Enter(TrainManager.Trains[i]); } if (Game.Sections.Length > 0) { Game.UpdateSection(Game.Sections.Length - 1); } // fast-forward until start time { Game.MinimalisticSimulation = true; const double w = 0.25; double u = Game.StartupTime - Game.SecondsSinceMidnight; if (u > 0) { while (true) { double v = u < w ? u : w; u -= v; Game.SecondsSinceMidnight += v; TrainManager.UpdateTrains(v); if (u <= 0.0) { break; } TotalTimeElapsedForSectionUpdate += v; if (TotalTimeElapsedForSectionUpdate >= 1.0) { if (Game.Sections.Length > 0) { Game.UpdateSection(Game.Sections.Length - 1); } TotalTimeElapsedForSectionUpdate = 0.0; } } } Game.MinimalisticSimulation = false; } // animated objects ObjectManager.UpdateAnimatedWorldObjects(0.0, true); TrainManager.UpdateTrainObjects(0.0, true); //HACK: This function calls a single update on all objects attached to the player's train // but ignores any specified damping so that all needles etc. are in the correct place // for the first frame, rather than spinning wildly to get to the starting point. TrainManager.PlayerTrain.UpdateCabObjects(); // timetable if (TrainManager.PlayerTrain.Station >= 0) { Timetable.UpdateCustomTimetable(Game.Stations[TrainManager.PlayerTrain.Station].TimetableDaytimeTexture, Game.Stations[TrainManager.PlayerTrain.Station].TimetableNighttimeTexture); if (Timetable.CustomObjectsUsed != 0 & Timetable.CustomTimetableAvailable && Interface.CurrentOptions.TimeTableStyle != Interface.TimeTableMode.AutoGenerated && Interface.CurrentOptions.TimeTableStyle != Interface.TimeTableMode.None) { Timetable.CurrentTimetable = Timetable.TimetableState.Custom; } } //Create AI driver for the player train if specified via the commmand line if (Game.InitialAIDriver == true) { TrainManager.PlayerTrain.AI = new Game.SimpleHumanDriverAI(TrainManager.PlayerTrain); if (TrainManager.PlayerTrain.Plugin != null && !TrainManager.PlayerTrain.Plugin.SupportsAI) { Game.AddMessage(Interface.GetInterfaceString("notification_aiunable"), MessageManager.MessageDependency.None, Interface.GameMode.Expert, OpenBveApi.Colors.MessageColor.White, Game.SecondsSinceMidnight + 10.0, null); } } // warnings / errors if (Interface.MessageCount != 0) { int filesNotFound = 0; int errors = 0; int warnings = 0; for (int i = 0; i < Interface.MessageCount; i++) { if (Interface.Messages[i].FileNotFound) { filesNotFound++; } else if (Interface.Messages[i].Type == Interface.MessageType.Error) { errors++; } else if (Interface.Messages[i].Type == Interface.MessageType.Warning) { warnings++; } } string NotFound = null; string Messages = null; if (filesNotFound != 0) { NotFound = filesNotFound.ToString() + " file(s) not found"; Game.AddMessage(NotFound, MessageManager.MessageDependency.None, Interface.GameMode.Expert, MessageColor.Magenta, Game.SecondsSinceMidnight + 10.0, null); } if (errors != 0 & warnings != 0) { Messages = errors.ToString() + " error(s), " + warnings.ToString() + " warning(s)"; Game.AddMessage(Messages, MessageManager.MessageDependency.None, Interface.GameMode.Expert, MessageColor.Magenta, Game.SecondsSinceMidnight + 10.0, null); } else if (errors != 0) { Messages = errors.ToString() + " error(s)"; Game.AddMessage(Messages, MessageManager.MessageDependency.None, Interface.GameMode.Expert, MessageColor.Magenta, Game.SecondsSinceMidnight + 10.0, null); } else { Messages = warnings.ToString() + " warning(s)"; Game.AddMessage(Messages, MessageManager.MessageDependency.None, Interface.GameMode.Expert, MessageColor.Magenta, Game.SecondsSinceMidnight + 10.0, null); } Game.RouteInformation.FilesNotFound = NotFound; Game.RouteInformation.ErrorsAndWarnings = Messages; //Print the plugin error encountered (If any) for 10s //This must be done after the simulation has init, as otherwise the timeout doesn't work if (Loading.PluginError != null) { Game.AddMessage(Loading.PluginError, MessageManager.MessageDependency.None, Interface.GameMode.Expert, OpenBveApi.Colors.MessageColor.Red, Game.SecondsSinceMidnight + 5.0, null); Game.AddMessage(Interface.GetInterfaceString("errors_plugin_failure2"), MessageManager.MessageDependency.None, Interface.GameMode.Expert, OpenBveApi.Colors.MessageColor.Red, Game.SecondsSinceMidnight + 5.0, null); } } loadComplete = true; RenderRealTimeElapsed = 0.0; RenderTimeElapsed = 0.0; World.InitializeCameraRestriction(); Loading.SimulationSetup = true; switch (Game.InitialViewpoint) { case 1: //Switch camera to exterior MainLoop.SaveCameraSettings(); World.CameraMode = World.CameraViewMode.Exterior; MainLoop.RestoreCameraSettings(); for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) { TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior); } //Make bogies visible for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) { TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0); TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0); } World.CameraAlignmentDirection = new World.CameraAlignment(); World.CameraAlignmentSpeed = new World.CameraAlignment(); MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); World.UpdateAbsoluteCamera(0.0); World.UpdateViewingDistances(); break; case 2: //Switch camera to track MainLoop.SaveCameraSettings(); World.CameraMode = World.CameraViewMode.Track; MainLoop.RestoreCameraSettings(); for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) { TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior); } for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) { TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0); TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0); } World.CameraAlignmentDirection = new World.CameraAlignment(); World.CameraAlignmentSpeed = new World.CameraAlignment(); MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); World.UpdateAbsoluteCamera(0.0); World.UpdateViewingDistances(); break; case 3: //Switch camera to flyby MainLoop.SaveCameraSettings(); World.CameraMode = World.CameraViewMode.FlyBy; MainLoop.RestoreCameraSettings(); for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) { TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior); } for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) { TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0); TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0); } World.CameraAlignmentDirection = new World.CameraAlignment(); World.CameraAlignmentSpeed = new World.CameraAlignment(); MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); World.UpdateAbsoluteCamera(0.0); World.UpdateViewingDistances(); break; case 4: //Switch camera to flyby MainLoop.SaveCameraSettings(); World.CameraMode = World.CameraViewMode.FlyByZooming; MainLoop.RestoreCameraSettings(); for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) { TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior); } for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++) { TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0); TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0); } World.CameraAlignmentDirection = new World.CameraAlignment(); World.CameraAlignmentSpeed = new World.CameraAlignment(); MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); World.UpdateAbsoluteCamera(0.0); World.UpdateViewingDistances(); break; } }
private void button1_Click(object sender, EventArgs e) { Interface.InterpolationMode previousInterpolationMode = Interface.CurrentOptions.Interpolation; int previousAntialasingLevel = Interface.CurrentOptions.AntialiasingLevel; int previousAnsiotropicLevel = Interface.CurrentOptions.AnisotropicFilteringLevel; //Interpolation mode switch (InterpolationMode.SelectedIndex) { case 0: Interface.CurrentOptions.Interpolation = Interface.InterpolationMode.NearestNeighbor; break; case 1: Interface.CurrentOptions.Interpolation = Interface.InterpolationMode.Bilinear; break; case 2: Interface.CurrentOptions.Interpolation = Interface.InterpolationMode.NearestNeighborMipmapped; break; case 3: Interface.CurrentOptions.Interpolation = Interface.InterpolationMode.BilinearMipmapped; break; case 4: Interface.CurrentOptions.Interpolation = Interface.InterpolationMode.TrilinearMipmapped; break; case 5: Interface.CurrentOptions.Interpolation = Interface.InterpolationMode.AnisotropicFiltering; break; } //Ansiotropic filtering level Interface.CurrentOptions.AnisotropicFilteringLevel = (int)AnsiotropicLevel.Value; //Antialiasing level Interface.CurrentOptions.AntialiasingLevel = (int)AntialiasingLevel.Value; if (Interface.CurrentOptions.AntialiasingLevel != previousAntialasingLevel) { Program.currentGraphicsMode = new GraphicsMode(new ColorFormat(8, 8, 8, 8), 24, 8, Interface.CurrentOptions.AntialiasingLevel); } //Transparency quality switch (TransparencyQuality.SelectedIndex) { case 0: Interface.CurrentOptions.TransparencyMode = Renderer.TransparencyMode.Sharp; break; default: Interface.CurrentOptions.TransparencyMode = Renderer.TransparencyMode.Smooth; break; } //Set width and height if (Renderer.ScreenWidth != width.Value || Renderer.ScreenHeight != height.Value) { Renderer.ScreenWidth = (int)width.Value; Renderer.ScreenHeight = (int)height.Value; Program.currentGameWindow.Width = (int)width.Value; Program.currentGameWindow.Height = (int)height.Value; Program.UpdateViewport(); } //Check if interpolation mode or ansiotropic filtering level has changed, and trigger a reload if (previousInterpolationMode != Interface.CurrentOptions.Interpolation || previousAnsiotropicLevel != Interface.CurrentOptions.AnisotropicFilteringLevel) { Program.ReducedMode = false; Program.LightingRelative = -1.0; Game.Reset(); Textures.UnloadAllTextures(); Interface.ClearMessages(); for (int i = 0; i < Program.Files.Length; i++) { #if !DEBUG try { #endif ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Program.Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Program.Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); } Renderer.TransparentColorDepthSorting = Interface.CurrentOptions.TransparencyMode == Renderer.TransparencyMode.Smooth & Interface.CurrentOptions.Interpolation != Interface.InterpolationMode.NearestNeighbor & Interface.CurrentOptions.Interpolation != Interface.InterpolationMode.Bilinear; Options.SaveOptions(); this.Close(); }
/// <summary>Changes to or from fullscreen mode.</summary> internal static void ToggleFullscreen() { Fullscreen = !Fullscreen; // begin HACK // Renderer.ClearDisplayLists(); GL.Disable(EnableCap.Fog); GL.Disable(EnableCap.Lighting); Renderer.LightingEnabled = false; Textures.UnloadAllTextures(); if (Fullscreen) { IList <DisplayResolution> resolutions = OpenTK.DisplayDevice.Default.AvailableResolutions; for (int i = 0; i < resolutions.Count; i++) { //Test each resolution if (resolutions[i].Width == Interface.CurrentOptions.FullscreenWidth && resolutions[i].Height == Interface.CurrentOptions.FullscreenHeight && resolutions[i].BitsPerPixel == Interface.CurrentOptions.FullscreenBits) { OpenTK.DisplayDevice.Default.ChangeResolution(resolutions[i]); Program.currentGameWindow.Width = resolutions[i].Width; Program.currentGameWindow.Height = resolutions[i].Height; Screen.Width = Interface.CurrentOptions.FullscreenWidth; Screen.Height = Interface.CurrentOptions.FullscreenHeight; Program.currentGameWindow.WindowState = WindowState.Fullscreen; break; } } if (Program.currentGameWindow.WindowState != WindowState.Fullscreen) { MessageBox.Show(Interface.GetInterfaceString("errors_fullscreen_switch1") + System.Environment.NewLine + Interface.GetInterfaceString("errors_fullscreen_switch2"), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); Fullscreen = false; } } else { OpenTK.DisplayDevice.Default.RestoreResolution(); Program.currentGameWindow.WindowState = WindowState.Normal; Program.currentGameWindow.Width = Interface.CurrentOptions.WindowWidth; Program.currentGameWindow.Height = Interface.CurrentOptions.WindowHeight; Screen.Width = Interface.CurrentOptions.WindowWidth; Screen.Height = Interface.CurrentOptions.WindowHeight; } Renderer.InitializeLighting(); MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); MainLoop.InitializeMotionBlur(); Timetable.CreateTimetable(); Timetable.UpdateCustomTimetable(null, null); World.InitializeCameraRestriction(); if (Renderer.OptionBackfaceCulling) { GL.Enable(EnableCap.CullFace); } else { GL.Disable(EnableCap.CullFace); } Renderer.ReAddObjects(); // end HACK // //Reset the camera when switching between fullscreen and windowed mode //Otherwise, if the aspect ratio changes distortion will occur until the view is changed or the camera reset if (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead) { World.CameraCurrentAlignment.Position = new OpenBveApi.Math.Vector3(0.0, 0.0, 0.0); } World.CameraCurrentAlignment.Yaw = 0.0; World.CameraCurrentAlignment.Pitch = 0.0; World.CameraCurrentAlignment.Roll = 0.0; if (World.CameraMode == World.CameraViewMode.Track) { TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, TrainManager.PlayerTrain.Cars[0].FrontAxle.Follower.TrackPosition, true, false); } }
/// <summary>This method is called once the route and train data have been preprocessed, in order to physically setup the simulation</summary> private void SetupSimulation() { if (Loading.Cancel) { Close(); } Timetable.CreateTimetable(); //Check if any critical errors have occured during the route or train loading for (int i = 0; i < Interface.MessageCount; i++) { if (Interface.Messages[i].Type == Interface.MessageType.Critical) { MessageBox.Show("A critical error has occured:\n\n" + Interface.Messages[i].Text + "\n\nPlease inspect the error log file for further information.", "Load", MessageBoxButtons.OK, MessageBoxIcon.Hand); Close(); } } Renderer.InitializeLighting(); Game.LogRouteName = System.IO.Path.GetFileName(MainLoop.currentResult.RouteFile); Game.LogTrainName = System.IO.Path.GetFileName(MainLoop.currentResult.TrainFolder); Game.LogDateTime = DateTime.Now; if (Interface.CurrentOptions.LoadInAdvance) { Textures.LoadAllTextures(); } else { Textures.UnloadAllTextures(); } // 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 = TrackManager.EventTriggerType.Camera; // starting time and track position Game.SecondsSinceMidnight = 0.0; Game.StartupTime = 0.0; int PlayerFirstStationIndex = -1; double PlayerFirstStationPosition = 0.0; for (int i = 0; i < Game.Stations.Length; i++) { if (Game.Stations[i].StopMode == Game.StationStopMode.AllStop | Game.Stations[i].StopMode == Game.StationStopMode.PlayerStop & Game.Stations[i].Stops.Length != 0) { PlayerFirstStationIndex = i; int s = Game.GetStopIndex(i, TrainManager.PlayerTrain.Cars.Length); if (s >= 0) { PlayerFirstStationPosition = Game.Stations[i].Stops[s].TrackPosition; double TrainLength = 0.0; for (int c = 0; c < TrainManager.Trains[TrainManager.PlayerTrain.TrainIndex].Cars.Length; c++) { TrainLength += TrainManager.Trains[TrainManager.PlayerTrain.TrainIndex].Cars[c].Length; } for (int j = 0; j < Game.BufferTrackPositions.Length; j++) { if (PlayerFirstStationPosition > Game.BufferTrackPositions[j] && PlayerFirstStationPosition - TrainLength < Game.BufferTrackPositions[j]) { /* * HACK: The initial start position for the player train is stuck on a set of buffers * This means we have to make some one the fly adjustments to the first station stop position */ //Set the start position to be the buffer position plus the train length plus 1m PlayerFirstStationPosition = Game.BufferTrackPositions[j] + TrainLength + 1; //Update the station stop location if (s >= 0) { Game.Stations[PlayerFirstStationIndex].Stops[s].TrackPosition = PlayerFirstStationPosition; } else { Game.Stations[PlayerFirstStationIndex].DefaultTrackPosition = PlayerFirstStationPosition; } break; } } } else { PlayerFirstStationPosition = Game.Stations[i].DefaultTrackPosition; } if (Game.Stations[i].ArrivalTime < 0.0) { if (Game.Stations[i].DepartureTime < 0.0) { Game.SecondsSinceMidnight = 0.0; Game.StartupTime = 0.0; } else { Game.SecondsSinceMidnight = Game.Stations[i].DepartureTime - Game.Stations[i].StopTime; Game.StartupTime = Game.Stations[i].DepartureTime - Game.Stations[i].StopTime; } } else { Game.SecondsSinceMidnight = Game.Stations[i].ArrivalTime; Game.StartupTime = Game.Stations[i].ArrivalTime; } break; } } int OtherFirstStationIndex = -1; double OtherFirstStationPosition = 0.0; double OtherFirstStationTime = 0.0; for (int i = 0; i < Game.Stations.Length; i++) { if (Game.Stations[i].StopMode == Game.StationStopMode.AllStop | Game.Stations[i].StopMode == Game.StationStopMode.PlayerPass & Game.Stations[i].Stops.Length != 0) { OtherFirstStationIndex = i; int s = Game.GetStopIndex(i, TrainManager.PlayerTrain.Cars.Length); if (s >= 0) { OtherFirstStationPosition = Game.Stations[i].Stops[s].TrackPosition; } else { OtherFirstStationPosition = Game.Stations[i].DefaultTrackPosition; } if (Game.Stations[i].ArrivalTime < 0.0) { if (Game.Stations[i].DepartureTime < 0.0) { OtherFirstStationTime = 0.0; } else { OtherFirstStationTime = Game.Stations[i].DepartureTime - Game.Stations[i].StopTime; } } else { OtherFirstStationTime = Game.Stations[i].ArrivalTime; } break; } } if (Game.PrecedingTrainTimeDeltas.Length != 0) { OtherFirstStationTime -= Game.PrecedingTrainTimeDeltas[Game.PrecedingTrainTimeDeltas.Length - 1]; if (OtherFirstStationTime < Game.SecondsSinceMidnight) { Game.SecondsSinceMidnight = OtherFirstStationTime; } } // initialize trains for (int i = 0; i < TrainManager.Trains.Length; i++) { TrainManager.InitializeTrain(TrainManager.Trains[i]); int s = i == TrainManager.PlayerTrain.TrainIndex ? PlayerFirstStationIndex : OtherFirstStationIndex; if (s >= 0) { if (Game.Stations[s].OpenLeftDoors) { for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++) { TrainManager.Trains[i].Cars[j].Specs.AnticipatedLeftDoorsOpened = true; } } if (Game.Stations[s].OpenRightDoors) { for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++) { TrainManager.Trains[i].Cars[j].Specs.AnticipatedRightDoorsOpened = true; } } } if (Game.Sections.Length != 0) { Game.Sections[0].Enter(TrainManager.Trains[i]); } for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++) { double length = TrainManager.Trains[i].Cars[0].Length; TrainManager.MoveCar(TrainManager.Trains[i], j, -length, 0.01); TrainManager.MoveCar(TrainManager.Trains[i], j, length, 0.01); } } // score Game.CurrentScore.ArrivalStation = PlayerFirstStationIndex + 1; Game.CurrentScore.DepartureStation = PlayerFirstStationIndex; Game.CurrentScore.Maximum = 0; for (int i = 0; i < Game.Stations.Length; i++) { if (i != PlayerFirstStationIndex & Game.PlayerStopsAtStation(i)) { if (i == 0 || Game.Stations[i - 1].StationType != Game.StationType.ChangeEnds) { Game.CurrentScore.Maximum += Game.ScoreValueStationArrival; } } } if (Game.CurrentScore.Maximum <= 0) { Game.CurrentScore.Maximum = Game.ScoreValueStationArrival; } // signals if (Game.Sections.Length > 0) { Game.UpdateSection(Game.Sections.Length - 1); } // move train in position for (int i = 0; i < TrainManager.Trains.Length; i++) { double p; if (i == TrainManager.PlayerTrain.TrainIndex) { p = PlayerFirstStationPosition; } else if (TrainManager.Trains[i].State == TrainManager.TrainState.Bogus) { p = Game.BogusPretrainInstructions[0].TrackPosition; TrainManager.Trains[i].AI = new Game.BogusPretrainAI(TrainManager.Trains[i]); } else { p = OtherFirstStationPosition; } for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++) { TrainManager.MoveCar(TrainManager.Trains[i], j, p, 0.01); } } // timetable if (Timetable.DefaultTimetableDescription.Length == 0) { Timetable.DefaultTimetableDescription = Game.LogTrainName; } // initialize camera if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) { World.CameraMode = World.CameraViewMode.InteriorLookAhead; } //Place the initial camera in the driver car TrainManager.UpdateCamera(TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar); TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, -1.0, true, false); ObjectManager.UpdateVisibility(World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z); World.CameraSavedInterior = new World.CameraAlignment(); World.CameraSavedExterior = new World.CameraAlignment(new OpenBveApi.Math.Vector3(-2.5, 1.5, -15.0), 0.3, -0.2, 0.0, PlayerFirstStationPosition, 1.0); World.CameraSavedTrack = new World.CameraAlignment(new OpenBveApi.Math.Vector3(-3.0, 2.5, 0.0), 0.3, 0.0, 0.0, TrainManager.PlayerTrain.Cars[0].FrontAxle.Follower.TrackPosition - 10.0, 1.0); // signalling sections for (int i = 0; i < TrainManager.Trains.Length; i++) { int s = TrainManager.Trains[i].CurrentSectionIndex; Game.Sections[s].Enter(TrainManager.Trains[i]); } if (Game.Sections.Length > 0) { Game.UpdateSection(Game.Sections.Length - 1); } // fast-forward until start time { Game.MinimalisticSimulation = true; const double w = 0.25; double u = Game.StartupTime - Game.SecondsSinceMidnight; if (u > 0) { while (true) { double v = u < w ? u : w; u -= v; Game.SecondsSinceMidnight += v; TrainManager.UpdateTrains(v); if (u <= 0.0) { break; } TotalTimeElapsedForSectionUpdate += v; if (TotalTimeElapsedForSectionUpdate >= 1.0) { if (Game.Sections.Length > 0) { Game.UpdateSection(Game.Sections.Length - 1); } TotalTimeElapsedForSectionUpdate = 0.0; } } } Game.MinimalisticSimulation = false; } // animated objects ObjectManager.UpdateAnimatedWorldObjects(0.0, true); TrainManager.UpdateTrainObjects(0.0, true); // timetable if (TrainManager.PlayerTrain.Station >= 0) { Timetable.UpdateCustomTimetable(Game.Stations[TrainManager.PlayerTrain.Station].TimetableDaytimeTexture, Game.Stations[TrainManager.PlayerTrain.Station].TimetableNighttimeTexture); if (Timetable.CustomObjectsUsed != 0 & Timetable.CustomTimetableAvailable && Interface.CurrentOptions.TimeTableStyle != Interface.TimeTableMode.AutoGenerated && Interface.CurrentOptions.TimeTableStyle != Interface.TimeTableMode.None) { Timetable.CurrentTimetable = Timetable.TimetableState.Custom; } } // warnings / errors if (Interface.MessageCount != 0) { int filesNotFound = 0; int errors = 0; int warnings = 0; for (int i = 0; i < Interface.MessageCount; i++) { if (Interface.Messages[i].FileNotFound) { filesNotFound++; } else if (Interface.Messages[i].Type == Interface.MessageType.Error) { errors++; } else if (Interface.Messages[i].Type == Interface.MessageType.Warning) { warnings++; } } string NotFound = null; string Messages = null; if (filesNotFound != 0) { NotFound = filesNotFound.ToString() + " file(s) not found"; Game.AddDebugMessage(NotFound, 10.0); } if (errors != 0 & warnings != 0) { Messages = errors.ToString() + " error(s), " + warnings.ToString() + " warning(s)"; Game.AddDebugMessage(Messages, 10.0); } else if (errors != 0) { Messages = errors.ToString() + " error(s)"; Game.AddDebugMessage(Messages, 10.0); } else { Messages = warnings.ToString() + " warning(s)"; Game.AddDebugMessage(Messages, 10.0); } Game.RouteInformation.FilesNotFound = NotFound; Game.RouteInformation.ErrorsAndWarnings = Messages; //Print the plugin error encountered (If any) for 10s //This must be done after the simulation has init, as otherwise the timeout doesn't work if (Loading.PluginError != null) { Game.AddMessage(Loading.PluginError, Game.MessageDependency.None, Interface.GameMode.Expert, OpenBveApi.Colors.MessageColor.Red, Game.SecondsSinceMidnight + 5.0); Game.AddMessage(Interface.GetInterfaceString("errors_plugin_failure2"), Game.MessageDependency.None, Interface.GameMode.Expert, OpenBveApi.Colors.MessageColor.Red, Game.SecondsSinceMidnight + 5.0); } } loadComplete = true; RenderRealTimeElapsed = 0.0; RenderTimeElapsed = 0.0; World.InitializeCameraRestriction(); }