internal static void Main(string[] args) { Interface.CurrentOptions.UseSound = true; Interface.CurrentOptions.ObjectOptimizationBasicThreshold = 1000; Interface.CurrentOptions.ObjectOptimizationFullThreshold = 250; // platform and mono int p = (int)Environment.OSVersion.Platform; if (p == 4 | p == 128) { // general Unix CurrentPlatform = Platform.Linux; } else if (p == 6) { // Mac CurrentPlatform = Platform.Mac; } else { // non-Unix CurrentPlatform = Platform.Windows; } CurrentlyRunOnMono = Type.GetType("Mono.Runtime") != null; // file system FileSystem = FileSystem.FromCommandLineArgs(args); FileSystem.CreateFileSystem(); SetPackageLookupDirectories(); // command line arguments bool[] SkipArgs = new bool[args.Length]; if (args.Length != 0) { string File = System.IO.Path.Combine(Application.StartupPath, "ObjectViewer.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 (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 == 0 || Text.IndexOf("CreateMeshBuilder", StringComparison.OrdinalIgnoreCase) >= 0) { 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; } } } // application Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); 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; } // initialize sdl window SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DOUBLEBUFFER, 1); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, 16); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_RED_SIZE, 8); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_GREEN_SIZE, 8); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_BLUE_SIZE, 8); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_ALPHA_SIZE, 8); SDL.SDL_ShowCursor(1); // initialize camera ResetCamera(); World.BackgroundImageDistance = 600.0; World.ForwardViewingDistance = 600.0; World.BackwardViewingDistance = 0.0; World.ExtraViewingDistance = 50.0; // create window Renderer.ScreenWidth = 960; Renderer.ScreenHeight = 600; //int Bits = 32; //IntPtr video = Sdl.SDL_SetVideoMode(Renderer.ScreenWidth, Renderer.ScreenHeight, Bits, Sdl.SDL_OPENGL | Sdl.SDL_DOUBLEBUF); Window = SDL.SDL_CreateWindow(Application.ProductName, SDL.SDL_WINDOWPOS_UNDEFINED, SDL.SDL_WINDOWPOS_UNDEFINED, Renderer.ScreenWidth, Renderer.ScreenHeight, SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE); if (Window == IntPtr.Zero) { MessageBox.Show("SDL failed to create the window.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } // icon string iconFile = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder(), "icon.png"); if (System.IO.File.Exists(iconFile)) { iconBmp = new Bitmap(iconFile); // load file iconData = iconBmp.LockBits(new Rectangle(0, 0, iconBmp.Width, iconBmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); // lock data iconSurface = SDL.SDL_CreateRGBSurfaceFrom(iconData.Scan0, iconBmp.Width, iconBmp.Height, 32, iconData.Stride, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); // upload to sdl SDL.SDL_SetWindowIcon(Window, iconSurface); // use icon } GLContext = SDL.SDL_GL_CreateContext(Window); tkContext = new GraphicsContext(new ContextHandle(GLContext), SDL.SDL_GL_GetProcAddress, SDLGetCurrentContext); // anisotropic filtering string[] extensions = GL.GetString(StringName.Extensions).Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); Interface.CurrentOptions.AnisotropicFilteringMaximum = 0; for (int i = 0; i < extensions.Length; i++) { if (extensions[i] == "GL_EXT_texture_filter_anisotropic") { float n; GL.GetFloat((GetPName)ExtTextureFilterAnisotropic.MaxTextureMaxAnisotropyExt, out n); Interface.CurrentOptions.AnisotropicFilteringMaximum = (int)Math.Round((double)n); break; } } if (Interface.CurrentOptions.AnisotropicFilteringMaximum <= 0) { Interface.CurrentOptions.AnisotropicFilteringMaximum = 0; Interface.CurrentOptions.AnisotropicFilteringLevel = 0; Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.AnisotropicFiltering; } else { Interface.CurrentOptions.AnisotropicFilteringLevel = Interface.CurrentOptions.AnisotropicFilteringMaximum; Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.TrilinearMipmapped; } Interface.CurrentOptions.TransparencyMode = Renderer.TransparencyMode.Sharp; // module initialization Renderer.Initialize(); Renderer.InitializeLighting(); SoundManager.Initialize(); GL.ClearColor(0.75f, 0.75f, 0.75f, 1.0f); SwapBuffers(); Fonts.Initialize(); UpdateViewport(); // loop bool processCommandLineArgs = true; timer = new System.Diagnostics.Stopwatch(); timer.Start(); while (!Quit) { ProcessEvents(); int a = (int)timer.ElapsedMilliseconds; double TimeElapsed = 0.001 * (double)(a - LastTicks); if (CpuReducedMode) { System.Threading.Thread.Sleep(250); } else { System.Threading.Thread.Sleep(1); if (ReducedModeEnteringTime == 0) { ReducedModeEnteringTime = a + 2500; } if (World.CameraAlignmentDirection.Position.X != 0.0 | World.CameraAlignmentDirection.Position.Y != 0.0 | World.CameraAlignmentDirection.Position.Z != 0.0 | World.CameraAlignmentDirection.Pitch != 0.0 | World.CameraAlignmentDirection.Yaw != 0.0 | World.CameraAlignmentDirection.Roll != 0.0 | World.CameraAlignmentDirection.TrackPosition != 0.0 | World.CameraAlignmentDirection.Zoom != 0.0) { ReducedModeEnteringTime = a + 2500; } else if (a > ReducedModeEnteringTime & CpuAutomaticMode) { ReducedModeEnteringTime = 0; CpuReducedMode = true; } } DateTime d = DateTime.Now; Game.SecondsSinceMidnight = (double)(3600 * d.Hour + 60 * d.Minute + d.Second) + 0.001 * (double)d.Millisecond; ObjectManager.UpdateAnimatedWorldObjects(TimeElapsed, false); World.UpdateAbsoluteCamera(TimeElapsed); ObjectManager.UpdateVisibility(World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z); TextureManager.Update(TimeElapsed); SoundManager.Update(TimeElapsed); Renderer.RenderScene(TimeElapsed); SwapBuffers(); LastTicks = a; // command line arguments if (processCommandLineArgs) { processCommandLineArgs = false; for (int i = 0; i < args.Length; i++) { if (!SkipArgs[i] && System.IO.File.Exists(args[i])) { CurrentlyLoading = true; Renderer.RenderScene(0.0); SwapBuffers(); CurrentRoute = args[i]; LoadRoute(); CurrentlyLoading = false; UpdateCaption(); break; } } } } // quit TextureManager.UnuseAllTextures(); SoundManager.Deinitialize(); if (iconSurface != IntPtr.Zero) { SDL.SDL_FreeSurface(iconSurface); // free surface } if (iconBmp != null && iconData != null) { iconBmp.UnlockBits(iconData); // free pixels iconBmp.Dispose(); } SDL.SDL_GL_DeleteContext(GLContext); SDL.SDL_DestroyWindow(Window); SDL.SDL_Quit(); }
/// <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(); } lock (Illustrations.Locker) { 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.LogMessages[i].Type == MessageType.Critical) { MessageBox.Show("A critical error has occured:\n\n" + Interface.LogMessages[i].Text + "\n\nPlease inspect the error log file for further information.", "Load", MessageBoxButtons.OK, MessageBoxIcon.Hand); Close(); } } LibRender.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 { TextureManager.UnloadAllTextures(); } // camera ObjectManager.InitializeVisibility(); TrainManager.PlayerTrain.DriverBody = new DriverBody(TrainManager.PlayerTrain); World.CameraTrackFollower.Update(0.0, true, false); World.CameraTrackFollower.Update(-0.1, true, false); World.CameraTrackFollower.Update(0.1, true, false); World.CameraTrackFollower.TriggerType = 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.Stations[PlayerFirstStationIndex].GetStopIndex(TrainManager.PlayerTrain.Cars.Length); if (s >= 0) { PlayerFirstStationPosition = Game.Stations[PlayerFirstStationIndex].Stops[s].TrackPosition; double TrainLength = 0.0; for (int c = 0; c < TrainManager.PlayerTrain.Cars.Length; c++) { TrainLength += TrainManager.PlayerTrain.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.Stations[i].GetStopIndex(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 = TrainManager.Trains[i] == TrainManager.PlayerTrain ? 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 (CurrentRoute.Sections.Length != 0) { CurrentRoute.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); TrainManager.Trains[i].Cars[j].Move(length); } } foreach (var Train in TrainManager.TFOs) { Train.Initialize(); foreach (var Car in Train.Cars) { double length = Train.Cars[0].Length; Car.Move(-length); Car.Move(length); } } // 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.Stations[i].PlayerStops()) { 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 (CurrentRoute.Sections.Length > 0) { Game.UpdateSection(CurrentRoute.Sections.Length - 1); } // move train in position for (int i = 0; i < TrainManager.Trains.Length; i++) { double p; if (TrainManager.Trains[i] == TrainManager.PlayerTrain) { p = PlayerFirstStationPosition; } else if (TrainManager.Trains[i].State == TrainState.Bogus) { p = CurrentRoute.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); } } // timetable if (Timetable.DefaultTimetableDescription.Length == 0) { Timetable.DefaultTimetableDescription = Game.LogTrainName; } // initialize camera if (Camera.CurrentRestriction == CameraRestrictionMode.NotAvailable) { Camera.CurrentMode = 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 + Camera.CurrentAlignment.Position.Z); World.CameraSavedExterior = new CameraAlignment(new OpenBveApi.Math.Vector3(-2.5, 1.5, -15.0), 0.3, -0.2, 0.0, PlayerFirstStationPosition, 1.0); World.CameraSavedTrack = new 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; CurrentRoute.Sections[s].Enter(TrainManager.Trains[i]); } if (CurrentRoute.Sections.Length > 0) { Game.UpdateSection(CurrentRoute.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 (CurrentRoute.Sections.Length > 0) { Game.UpdateSection(CurrentRoute.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(Translations.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.LogMessages[i].FileNotFound) { filesNotFound++; } else if (Interface.LogMessages[i].Type == MessageType.Error) { errors++; } else if (Interface.LogMessages[i].Type == MessageType.Warning) { warnings++; } } string NotFound = null; string Messages; 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(Translations.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(); Camera.CurrentMode = 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); } Camera.AlignmentDirection = new CameraAlignment(); Camera.AlignmentSpeed = new CameraAlignment(); Renderer.UpdateViewport(ViewPortChangeMode.NoChange); World.UpdateAbsoluteCamera(0.0); World.UpdateViewingDistances(); break; case 2: //Switch camera to track MainLoop.SaveCameraSettings(); Camera.CurrentMode = 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); } Camera.AlignmentDirection = new CameraAlignment(); Camera.AlignmentSpeed = new CameraAlignment(); Renderer.UpdateViewport(ViewPortChangeMode.NoChange); World.UpdateAbsoluteCamera(0.0); World.UpdateViewingDistances(); break; case 3: //Switch camera to flyby MainLoop.SaveCameraSettings(); Camera.CurrentMode = 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); } Camera.AlignmentDirection = new CameraAlignment(); Camera.AlignmentSpeed = new CameraAlignment(); Renderer.UpdateViewport(ViewPortChangeMode.NoChange); World.UpdateAbsoluteCamera(0.0); World.UpdateViewingDistances(); break; case 4: //Switch camera to flyby MainLoop.SaveCameraSettings(); Camera.CurrentMode = 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); } Camera.AlignmentDirection = new CameraAlignment(); Camera.AlignmentSpeed = new CameraAlignment(); Renderer.UpdateViewport(ViewPortChangeMode.NoChange); World.UpdateAbsoluteCamera(0.0); World.UpdateViewingDistances(); break; } }
internal static void keyDownEvent(object sender, KeyboardKeyEventArgs e) { double speedModified = (ShiftPressed ? 2.0 : 1.0) * (ControlPressed ? 4.0 : 1.0) * (AltPressed ? 8.0 : 1.0); switch (e.Key) { case Key.ShiftLeft: case Key.ShiftRight: ShiftPressed = true; break; case Key.ControlLeft: case Key.ControlRight: ControlPressed = true; break; case Key.LAlt: case Key.RAlt: AltPressed = true; break; case Key.F5: if (CurrentRoute != null && CurrentlyLoading == false) { CurrentlyLoading = true; Renderer.OptionInterface = false; if (!Interface.CurrentOptions.LoadingBackground) { Renderer.RenderScene(0.0); currentGameWindow.SwapBuffers(); Bitmap bitmap = new Bitmap(Renderer.ScreenWidth, Renderer.ScreenHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); BitmapData bData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); GL.ReadPixels(0, 0, Renderer.ScreenWidth, Renderer.ScreenHeight, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bData.Scan0); bitmap.UnlockBits(bData); bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); Renderer.TextureLoadingBkg = TextureManager.RegisterTexture(bitmap, false); bitmap.Dispose(); } World.CameraAlignment a = World.CameraCurrentAlignment; if (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); } CurrentlyLoading = false; Renderer.OptionInterface = true; TextureManager.UnregisterTexture(ref Renderer.TextureLoadingBkg); } break; case Key.F7: if (CurrentlyLoading == true) { break; } OpenFileDialog Dialog = new OpenFileDialog(); Dialog.CheckFileExists = true; Dialog.Filter = "CSV/RW files|*.csv;*.rw|All files|*"; if (Dialog.ShowDialog() == DialogResult.OK) { Application.DoEvents(); CurrentlyLoading = true; CurrentRoute = Dialog.FileName; LoadRoute(); ObjectManager.UpdateAnimatedWorldObjects(0.0, true); CurrentlyLoading = false; UpdateCaption(); } 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.F8: if (Program.CurrentlyLoading == true) { //Don't allow the user to update the settings during loading, bad idea.... break; } if (formOptions.ShowOptions() == DialogResult.OK) { UpdateGraphicsSettings(); } Application.DoEvents(); break; case Key.F9: if (Interface.MessageCount != 0) { formMessages.ShowMessages(); Application.DoEvents(); } break; case Key.F10: Renderer.RenderStatsOverlay = !Renderer.RenderStatsOverlay; break; case Key.A: case Key.Keypad4: World.CameraAlignmentDirection.Position.X = -World.CameraExteriorTopSpeed * speedModified; CpuReducedMode = false; break; case Key.D: case Key.Keypad6: World.CameraAlignmentDirection.Position.X = World.CameraExteriorTopSpeed * speedModified; CpuReducedMode = false; break; case Key.Keypad2: World.CameraAlignmentDirection.Position.Y = -World.CameraExteriorTopSpeed * speedModified; CpuReducedMode = false; break; case Key.Keypad8: World.CameraAlignmentDirection.Position.Y = World.CameraExteriorTopSpeed * speedModified; CpuReducedMode = false; break; case Key.W: case Key.Keypad9: World.CameraAlignmentDirection.TrackPosition = World.CameraExteriorTopSpeed * speedModified; CpuReducedMode = false; break; case Key.S: case Key.Keypad3: World.CameraAlignmentDirection.TrackPosition = -World.CameraExteriorTopSpeed * speedModified; CpuReducedMode = false; break; case Key.Left: World.CameraAlignmentDirection.Yaw = -World.CameraExteriorTopAngularSpeed * speedModified; CpuReducedMode = false; break; case Key.Right: World.CameraAlignmentDirection.Yaw = World.CameraExteriorTopAngularSpeed * speedModified; CpuReducedMode = false; break; case Key.Up: World.CameraAlignmentDirection.Pitch = World.CameraExteriorTopAngularSpeed * speedModified; CpuReducedMode = false; break; case Key.Down: World.CameraAlignmentDirection.Pitch = -World.CameraExteriorTopAngularSpeed * speedModified; CpuReducedMode = false; break; case Key.KeypadDivide: World.CameraAlignmentDirection.Roll = -World.CameraExteriorTopAngularSpeed * speedModified; CpuReducedMode = false; break; case Key.KeypadMultiply: World.CameraAlignmentDirection.Roll = World.CameraExteriorTopAngularSpeed * speedModified; CpuReducedMode = false; break; case Key.Keypad0: World.CameraAlignmentDirection.Zoom = World.CameraZoomTopSpeed * speedModified; CpuReducedMode = false; break; case Key.KeypadPeriod: World.CameraAlignmentDirection.Zoom = -World.CameraZoomTopSpeed * speedModified; CpuReducedMode = false; break; case Key.Keypad1: Game.ApplyPointOfInterest(-1, true); CpuReducedMode = false; break; case Key.Keypad7: Game.ApplyPointOfInterest(1, true); CpuReducedMode = false; break; case Key.PageUp: JumpToStation(1); CpuReducedMode = false; break; case Key.PageDown: JumpToStation(-1); CpuReducedMode = false; break; case Key.Keypad5: World.CameraCurrentAlignment.Yaw = 0.0; World.CameraCurrentAlignment.Pitch = 0.0; World.CameraCurrentAlignment.Roll = 0.0; World.CameraCurrentAlignment.Position = new Vector3(0.0, 2.5, 0.0); World.CameraCurrentAlignment.Zoom = 0.0; World.CameraAlignmentDirection = new World.CameraAlignment(); World.CameraAlignmentSpeed = new World.CameraAlignment(); World.VerticalViewingAngle = World.OriginalVerticalViewingAngle; UpdateViewport(); World.UpdateAbsoluteCamera(0.0); World.UpdateViewingDistances(); CpuReducedMode = false; break; case Key.F: Renderer.OptionWireframe = !Renderer.OptionWireframe; CpuReducedMode = false; if (Renderer.OptionWireframe) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } else { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } break; case Key.N: Renderer.OptionNormals = !Renderer.OptionNormals; CpuReducedMode = false; break; case Key.E: Renderer.OptionEvents = !Renderer.OptionEvents; CpuReducedMode = false; break; case Key.C: CpuAutomaticMode = !CpuAutomaticMode; CpuReducedMode = false; break; case Key.I: Renderer.OptionInterface = !Renderer.OptionInterface; CpuReducedMode = false; break; case Key.M: //SoundManager.Mute = !SoundManager.Mute; break; case Key.Plus: case Key.KeypadPlus: if (!JumpToPositionEnabled) { JumpToPositionEnabled = true; JumpToPositionValue = "+"; CpuReducedMode = false; } break; case Key.Minus: case Key.KeypadMinus: if (!JumpToPositionEnabled) { JumpToPositionEnabled = true; JumpToPositionValue = "-"; CpuReducedMode = false; } break; case Key.Number0: case Key.Number1: case Key.Number2: case Key.Number3: case Key.Number4: case Key.Number5: case Key.Number6: case Key.Number7: case Key.Number8: case Key.Number9: if (!JumpToPositionEnabled) { JumpToPositionEnabled = true; JumpToPositionValue = string.Empty; } JumpToPositionValue += char.ConvertFromUtf32(48 + e.Key - Key.Number0); CpuReducedMode = false; break; case Key.Period: if (!JumpToPositionEnabled) { JumpToPositionEnabled = true; JumpToPositionValue = "0."; } else if (JumpToPositionValue.IndexOf('.') == -1) { JumpToPositionValue += "."; } CpuReducedMode = false; break; case Key.BackSpace: if (JumpToPositionEnabled && JumpToPositionValue.Length != 0) { JumpToPositionValue = JumpToPositionValue.Substring(0, JumpToPositionValue.Length - 1); CpuReducedMode = false; } break; case Key.Enter: if (JumpToPositionEnabled) { if (JumpToPositionValue.Length != 0) { int direction; if (JumpToPositionValue[0] == '-') { JumpToPositionValue = JumpToPositionValue.Substring(1); direction = -1; } else if (JumpToPositionValue[0] == '+') { JumpToPositionValue = JumpToPositionValue.Substring(1); direction = 1; } else { direction = 0; } double value; if (double.TryParse(JumpToPositionValue, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { if (value < TrackManager.CurrentTrack.Elements[TrackManager.CurrentTrack.Elements.Length - 1].StartingTrackPosition + 100 && value > MinimumJumpToPositionValue - 100) { if (direction != 0) { value = World.CameraTrackFollower.TrackPosition + (double)direction * value; } TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, value, true, false); World.CameraCurrentAlignment.TrackPosition = value; World.UpdateAbsoluteCamera(0.0); World.UpdateViewingDistances(); } } } } JumpToPositionEnabled = false; CpuReducedMode = false; break; case Key.Escape: JumpToPositionEnabled = false; CpuReducedMode = false; break; } }
internal static void Main(string[] args) { CurrentHost = new Host(); commandLineArguments = args; Options.LoadOptions(); Interface.CurrentOptions.UseSound = true; Interface.CurrentOptions.ObjectOptimizationBasicThreshold = 1000; Interface.CurrentOptions.ObjectOptimizationFullThreshold = 250; // platform and mono int p = (int)Environment.OSVersion.Platform; if (p == 4 | p == 128) { // general Unix CurrentPlatform = Platform.Linux; } else if (p == 6) { // Mac CurrentPlatform = Platform.Mac; } else { // non-Unix CurrentPlatform = Platform.Windows; } CurrentlyRunOnMono = Type.GetType("Mono.Runtime") != null; // 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, "ObjectViewer.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 == 0 || Text.IndexOf("CreateMeshBuilder", StringComparison.OrdinalIgnoreCase) >= 0) { 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; } } } // application currentGraphicsMode = new GraphicsMode(new ColorFormat(8, 8, 8, 8), 24, 8, Interface.CurrentOptions.AntialiasingLevel); currentGameWindow = new RouteViewer(Renderer.ScreenWidth, Renderer.ScreenHeight, currentGraphicsMode, "Route Viewer", GameWindowFlags.Default); currentGameWindow.Visible = true; currentGameWindow.TargetUpdateFrequency = 0; currentGameWindow.TargetRenderFrequency = 0; currentGameWindow.Title = "Route Viewer"; processCommandLineArgs = true; currentGameWindow.Run(); //Unload TextureManager.UnuseAllTextures(); Sounds.Deinitialize(); }
public override bool LoadTexture(Texture Texture, OpenGlTextureWrapMode wrapMode) { return(TextureManager.LoadTexture(Texture, wrapMode, CPreciseTimer.GetClockTicks(), Interface.CurrentOptions.Interpolation, Interface.CurrentOptions.AnisotropicFilteringLevel)); }
/// <summary>Registers a texture and returns a handle to the texture.</summary> /// <param name="texture">The texture data.</param> /// <param name="parameters">The parameters that specify how to process the texture.</param> /// <param name="handle">Receives the handle to the texture.</param> /// <returns>Whether loading the texture was successful.</returns> public override bool RegisterTexture(Texture texture, TextureParameters parameters, out Texture handle) { texture = texture.ApplyParameters(parameters); handle = TextureManager.RegisterTexture(texture); return(true); }
// // SET CUSTOM LOADING SCREEN BACKGROUND // /// <summary>Sets the loading screen background to a custom image</summary> internal static void SetLoadingBkg(string fileName) { TextureLoadingBkg = TextureManager.RegisterTexture(fileName, TextureManager.TextureWrapMode.ClampToEdge, TextureManager.TextureWrapMode.ClampToEdge, false); TextureManager.UseTexture(TextureLoadingBkg, TextureManager.UseMode.LoadImmediately); customLoadScreen = true; }
// render data private static void RenderData(ref Table Table) { // prepare timetable int w = 384, h = 192; int offsetx = 0; int actualheight = h; float descriptionwidth = 256; float descriptionheight = 16; float stationnamewidth = 16; for (int k = 0; k < 2; k++) { Bitmap b = new Bitmap(w, h); Graphics g = Graphics.FromImage(b); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; g.Clear(Color.Transparent); g.FillRectangle(Brushes.White, new RectangleF(offsetx, 0, w, actualheight)); Font f = new Font(FontFamily.GenericSansSerif, 13.0f, GraphicsUnit.Pixel); Font fs = new Font(FontFamily.GenericSansSerif, 11.0f, GraphicsUnit.Pixel); Font fss = new Font(FontFamily.GenericSansSerif, 9.0f, GraphicsUnit.Pixel); // draw timetable string t; SizeF s; // description float x0 = offsetx + 8; float y0 = 8; if (k == 1) { t = DefaultTimetableDescription; g.DrawString(t, f, Brushes.Black, new RectangleF(x0, 6, descriptionwidth, descriptionheight + 8)); y0 += descriptionheight + 2; } // highest speed t = Interface.GetInterfaceString("timetable_highestspeed"); s = g.MeasureString(t, fs); g.DrawString(t, fs, Brushes.Black, x0, y0); float y0a = y0 + s.Height + 2; float x1 = x0 + s.Width + 4; for (int i = 0; i < Table.Tracks.Length; i++) { float y = y0a + 18 * i; t = Table.Tracks[i].Speed; g.DrawString(t, f, Brushes.Black, x0, y); s = g.MeasureString(t, f); float x = x0 + s.Width + 4; if (x > x1) { x1 = x; } } g.DrawLine(Pens.LightGray, new PointF(x1 - 2, 4 + descriptionheight), new PointF(x1 - 2, y0a + 18 * Table.Tracks.Length - 1)); // driving time t = Interface.GetInterfaceString("timetable_drivingtime"); s = g.MeasureString(t, fs); g.DrawString(t, fs, Brushes.Black, x1, y0); float x2 = x1 + s.Width + 4; for (int i = 0; i < Table.Tracks.Length; i++) { float y = y0a + 18 * i; if (Table.Tracks[i].Time.Hour.Length != 0) { t = Table.Tracks[i].Time.Hour; g.DrawString(t, fss, Brushes.Black, x1, y + 2); } else { t = "0"; } s = g.MeasureString(t, fss, 9999, StringFormat.GenericTypographic); float x = x1 + s.Width - 1; if (Table.Tracks[i].Time.Minute.Length != 0) { t = Table.Tracks[i].Time.Minute; g.DrawString(t, fs, Brushes.Black, x, y + 2); } else { t = "00:"; } s = g.MeasureString(t, fs, 9999, StringFormat.GenericTypographic); x += s.Width + 1; t = Table.Tracks[i].Time.Second; g.DrawString(t, fss, Brushes.Black, x, y + 2); s = g.MeasureString(t, fss, 9999, StringFormat.GenericTypographic); x += s.Width + 8; if (x > x2) { x2 = x; } } for (int i = 0; i < Table.Tracks.Length; i++) { float y = y0a + 18 * i; g.DrawLine(Pens.LightGray, new PointF(offsetx + 4, y - 1), new PointF(x2 - 2, y - 1)); } g.DrawLine(Pens.LightGray, new PointF(x2 - 2, 4 + descriptionheight), new PointF(x2 - 2, y0a + 18 * Table.Tracks.Length - 1)); // station name float y2 = y0; t = Interface.GetInterfaceString("timetable_stationname"); s = g.MeasureString(t, f); g.DrawString(t, f, Brushes.Black, x2, y2); float x3 = x2 + s.Width + 4; for (int i = 0; i < Table.Stations.Length; i++) { float y = y0 + 18 * (i + 1) + 2; g.DrawLine(Pens.LightGray, new PointF(x2 - 2, y - 1), new PointF(w - 4, y - 1)); t = Table.Stations[i].Name; if (Table.Stations[i].NameJapanese & Table.Stations[i].Name.Length > 1) { float[] sizes = new float[t.Length]; float totalsize = 0.0f; for (int j = 0; j < t.Length; j++) { sizes[j] = g.MeasureString(new string(t[j], 1), f, 9999, StringFormat.GenericTypographic).Width; totalsize += sizes[j]; } float space = (stationnamewidth - totalsize) / (float)(t.Length - 1); float x = 0.0f; for (int j = 0; j < t.Length; j++) { g.DrawString(new string(t[j], 1), f, Brushes.Black, x2 + x, y); x += sizes[j] + space; } } else { g.DrawString(t, f, Brushes.Black, x2, y); } s = g.MeasureString(t, f); { float x = x2 + s.Width + 4; if (x > x3) { x3 = x; } } } g.DrawLine(Pens.LightGray, new PointF(x3 - 2, 4 + descriptionheight), new PointF(x3 - 2, y0 + 18 * (Table.Stations.Length + 1))); if (k == 0) { stationnamewidth = x3 - x2 - 6; } // arrival time t = Interface.GetInterfaceString("timetable_arrivaltime"); s = g.MeasureString(t, f); g.DrawString(t, f, Brushes.Black, x3, y2); float x4 = x3 + s.Width + 4; for (int i = 0; i < Table.Stations.Length; i++) { float y = y0 + 18 * (i + 1) + 2; if (Table.Stations[i].Pass) { t = "00"; s = g.MeasureString(t, fs); float x = x3 + s.Width; t = " ↓"; g.DrawString(t, f, Brushes.Black, x, y); s = g.MeasureString(t, f); x += +s.Width + 4; if (x > x4) { x4 = x; } } else { if (Table.Stations[i].Arrival.Hour.Length != 0) { t = Table.Stations[i].Arrival.Hour; g.DrawString(t, fs, Brushes.Black, x3, y); } else { t = "00"; } s = g.MeasureString(t, fs); float x = x3 + s.Width; if (Table.Stations[i].Arrival.Minute.Length != 0 & Table.Stations[i].Arrival.Second.Length != 0) { t = Table.Stations[i].Arrival.Minute + ":" + Table.Stations[i].Arrival.Second; } else { t = ""; } g.DrawString(t, f, Brushes.Black, x, y); s = g.MeasureString(t, f); x += s.Width + 4; if (x > x4) { x4 = x; } } } g.DrawLine(Pens.LightGray, new PointF(x4 - 2, 4 + descriptionheight), new PointF(x4 - 2, y0 + 18 * (Table.Stations.Length + 1))); // departure time t = Interface.GetInterfaceString("timetable_departuretime"); s = g.MeasureString(t, f); g.DrawString(t, f, Brushes.Black, x4, y2); float x5 = x4 + s.Width + 4; for (int i = 0; i < Table.Stations.Length; i++) { float y = y0 + 18 * (i + 1) + 2; if (Table.Stations[i].Terminal) { t = "00"; s = g.MeasureString(t, fs); float x = x4 + s.Width; const float c0 = 4; const float c1 = 32; g.DrawLine(Pens.Black, new PointF(x + c0, y + 6), new PointF(x + c1, y + 6)); g.DrawLine(Pens.Black, new PointF(x + c0, y + 10), new PointF(x + c1, y + 10)); x += c1 + 4; if (x > x5) { x5 = x; } } else { if (Table.Stations[i].Departure.Hour.Length != 0) { t = Table.Stations[i].Departure.Hour; g.DrawString(t, fs, Brushes.Black, x4, y); } else { t = "00"; } s = g.MeasureString(t, fs); float x = x4 + s.Width; if (Table.Stations[i].Departure.Minute.Length != 0 & Table.Stations[i].Departure.Second.Length != 0) { t = Table.Stations[i].Departure.Minute + ":" + Table.Stations[i].Departure.Second; } else { t = ""; } g.DrawString(t, f, Brushes.Black, x, y); s = g.MeasureString(t, f); x += s.Width + 4; if (x > x5) { x5 = x; } } } for (int i = 0; i < Table.Stations.Length; i++) { float y = y0 + 18 * (i + 1) + 2; g.DrawLine(Pens.LightGray, new PointF(x2 - 2, y - 1), new PointF(w - 4, y - 1)); } // border if (k == 1) { g.DrawLine(Pens.Black, new PointF(offsetx + 4, 4), new PointF(offsetx + 4, y0a + 18 * Table.Tracks.Length - 1)); g.DrawLine(Pens.Black, new PointF(offsetx + 4, y0a + 18 * Table.Tracks.Length - 1), new PointF(x2 - 2, y0a + 18 * Table.Tracks.Length - 1)); g.DrawLine(Pens.Black, new PointF(offsetx + 4, 4), new PointF(w - 4, 4)); g.DrawLine(Pens.Black, new PointF(offsetx + 4, 4 + descriptionheight), new PointF(w - 4, 4 + descriptionheight)); g.DrawLine(Pens.Black, new PointF(x2 - 2, y0 + 18 * (Table.Stations.Length + 1)), new PointF(w - 4, y0 + 18 * (Table.Stations.Length + 1))); g.DrawLine(Pens.Black, new PointF(w - 4, 4), new PointF(w - 4, y0 + 18 * (Table.Stations.Length + 1))); g.DrawLine(Pens.Black, new PointF(x2 - 2, y0a + 18 * Table.Tracks.Length - 1), new PointF(x2 - 2, y0 + 18 * (Table.Stations.Length + 1))); } // measure w = (int)Math.Ceiling((double)(x5 + 1)); h = (int)Math.Ceiling((double)(y0 + 18 * (Table.Stations.Length + 1) + 4)); // description if (k == 0) { t = DefaultTimetableDescription; s = g.MeasureString(t, f, w - 16); descriptionwidth = s.Width; descriptionheight = s.Height + 2; h += (int)Math.Ceiling((double)s.Height) + 4; } // finish if (k == 0) { // measures int nw = Interface.RoundToPowerOfTwo(w); offsetx = nw - w; w = nw; actualheight = h; h = Interface.RoundToPowerOfTwo(h); } else { // create texture g.Dispose(); DefaultTimetableTexture = TextureManager.RegisterTexture(b, true); b.Dispose(); } } }
// --- constructors --- /// <summary>Creates a new table of characters.</summary> /// <param name="font">The font.</param> /// <param name="offset">The offset from codepoint U+0000.</param> internal OpenGlFontTable(Font font, int offset) { /* * Measure characters. * */ Size[] physicalSizes = new Size[256]; Size[] typographicSizes = new Size[256]; Bitmap bitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb); Graphics graphics = Graphics.FromImage(bitmap); graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; for (int i = 0; i < 256; i++) { SizeF physicalSize = graphics.MeasureString(char.ConvertFromUtf32(offset + i), font, int.MaxValue, StringFormat.GenericDefault); SizeF typographicSize = graphics.MeasureString(char.ConvertFromUtf32(offset + i), font, int.MaxValue, StringFormat.GenericTypographic); physicalSizes[i] = new Size((int)Math.Ceiling(physicalSize.Width), (int)Math.Ceiling(physicalSize.Height)); typographicSizes[i] = new Size((int)Math.Ceiling(typographicSize.Width == 0.0f ? physicalSize.Width : typographicSize.Width), (int)Math.Ceiling(typographicSize.Height == 0.0f ? physicalSize.Height : typographicSize.Height)); } /* * Find suitable bitmap dimensions. * */ const int width = 256; const int border = 1; int x = border; int y = border; int lineHeight = 0; for (int i = 0; i < 256; i++) { if (x + physicalSizes[i].Width + border > width) { x = border; y += lineHeight; lineHeight = 0; } else { x += physicalSizes[i].Width + 2 * border; } if (physicalSizes[i].Height + border > lineHeight) { lineHeight = physicalSizes[i].Height + 2 * border; } } y += lineHeight; int height = (int)RoundToPowerOfTwo((uint)y); graphics.Dispose(); bitmap.Dispose(); /* * Draw character to bitmap. * */ bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); graphics = Graphics.FromImage(bitmap); graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; graphics.Clear(Color.Black); x = border; y = border; lineHeight = 0; this.Characters = new OpenGlFontChar[256]; for (int i = 0; i < 256; i++) { if (x + physicalSizes[i].Width + border > width) { x = border; y += lineHeight; lineHeight = 0; } graphics.DrawString(char.ConvertFromUtf32(offset + i), font, Brushes.White, new PointF(x, y)); float x0 = (float)(x - border) / (float)width; float x1 = (float)(x + physicalSizes[i].Width + border) / (float)width; float y0 = (float)(y - border) / (float)height; float y1 = (float)(y + physicalSizes[i].Height + border) / (float)height; this.Characters[i] = new OpenGlFontChar(new RectangleF(x0, y0, x1 - x0, y1 - y0), new Size(physicalSizes[i].Width + 2 * border, physicalSizes[i].Height + 2 * border), typographicSizes[i]); x += physicalSizes[i].Width + 2 * border; if (physicalSizes[i].Height + border > lineHeight) { lineHeight = physicalSizes[i].Height + 2 * border; } } graphics.Dispose(); this.Texture = TextureManager.RegisterTexture(bitmap, false); }
private static void ApplyMeshBuilder(ref ObjectManager.StaticObject Object, MeshBuilder Builder, ObjectManager.ObjectLoadMode LoadMode, bool ForceTextureRepeatX, bool ForceTextureRepeatY) { if (Builder.Faces.Count != 0) { int mf = Object.Mesh.Faces.Length; int mm = Object.Mesh.Materials.Length; int mv = Object.Mesh.Vertices.Length; Array.Resize <World.MeshFace>(ref Object.Mesh.Faces, mf + Builder.Faces.Count); if (Builder.Materials.Length > 0) { Array.Resize <World.MeshMaterial>(ref Object.Mesh.Materials, mm + Builder.Materials.Length); } else { /* * If no materials have been defined for this face group, use the last material */ mm -= 1; } Array.Resize <World.Vertex>(ref Object.Mesh.Vertices, mv + Builder.Vertices.Count); for (int i = 0; i < Builder.Vertices.Count; i++) { Object.Mesh.Vertices[mv + i] = Builder.Vertices[i]; } for (int i = 0; i < Builder.Faces.Count; i++) { Object.Mesh.Faces[mf + i] = Builder.Faces[i]; for (int j = 0; j < Object.Mesh.Faces[mf + i].Vertices.Length; j++) { Object.Mesh.Faces[mf + i].Vertices[j].Index += (ushort)mv; } Object.Mesh.Faces[mf + i].Material += (ushort)mm; } for (int i = 0; i < Builder.Materials.Length; i++) { Object.Mesh.Materials[mm + i].Flags = (byte)((Builder.Materials[i].EmissiveColorUsed ? World.MeshMaterial.EmissiveColorMask : 0) | (Builder.Materials[i].TransparentColorUsed ? World.MeshMaterial.TransparentColorMask : 0)); Object.Mesh.Materials[mm + i].Color = Builder.Materials[i].Color; Object.Mesh.Materials[mm + i].TransparentColor = Builder.Materials[i].TransparentColor; TextureManager.TextureWrapMode WrapX, WrapY; if (ForceTextureRepeatX) { WrapX = TextureManager.TextureWrapMode.Repeat; } else { WrapX = TextureManager.TextureWrapMode.ClampToEdge; } if (ForceTextureRepeatY) { WrapY = TextureManager.TextureWrapMode.Repeat; } else { WrapY = TextureManager.TextureWrapMode.ClampToEdge; } if (WrapX != TextureManager.TextureWrapMode.Repeat | WrapY != TextureManager.TextureWrapMode.Repeat) { for (int j = 0; j < Builder.Vertices.Count; j++) { if (Builder.Vertices[j].TextureCoordinates.X <0.0 | Builder.Vertices[j].TextureCoordinates.X> 1.0) { WrapX = TextureManager.TextureWrapMode.Repeat; } if (Builder.Vertices[j].TextureCoordinates.Y <0.0 | Builder.Vertices[j].TextureCoordinates.Y> 1.0) { WrapY = TextureManager.TextureWrapMode.Repeat; } } } if (Builder.Materials[i].DaytimeTexture != null) { int tday = TextureManager.RegisterTexture(Builder.Materials[i].DaytimeTexture, Builder.Materials[i].TransparentColor, Builder.Materials[i].TransparentColorUsed ? (byte)1 : (byte)0, WrapX, WrapY, LoadMode != ObjectManager.ObjectLoadMode.Normal); Object.Mesh.Materials[mm + i].DaytimeTextureIndex = tday; } else { Object.Mesh.Materials[mm + i].DaytimeTextureIndex = -1; } Object.Mesh.Materials[mm + i].EmissiveColor = Builder.Materials[i].EmissiveColor; if (Builder.Materials[i].NighttimeTexture != null) { int tnight = TextureManager.RegisterTexture(Builder.Materials[i].NighttimeTexture, Builder.Materials[i].TransparentColor, Builder.Materials[i].TransparentColorUsed ? (byte)1 : (byte)0, WrapX, WrapY, LoadMode != ObjectManager.ObjectLoadMode.Normal); Object.Mesh.Materials[mm + i].NighttimeTextureIndex = tnight; } else { Object.Mesh.Materials[mm + i].NighttimeTextureIndex = -1; } Object.Mesh.Materials[mm + i].DaytimeNighttimeBlend = 0; Object.Mesh.Materials[mm + i].BlendMode = Builder.Materials[i].BlendMode; Object.Mesh.Materials[mm + i].GlowAttenuationData = Builder.Materials[i].GlowAttenuationData; } } }
// 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(); TextureManager.UnuseAllTextures(); 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, 0, 0, 0); ObjectManager.CreateObject(o, new World.Vector3D(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.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); break; case Key.F7: { OpenFileDialog Dialog = new OpenFileDialog(); Dialog.CheckFileExists = true; Dialog.Multiselect = true; Dialog.Filter = "CSV/B3D/X/ANIMATED files|*.csv;*.b3d;*.x;*.animated;*.l3dobj;*.l3dgrp|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(); TextureManager.UnuseAllTextures(); 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, 0, 0, 0); ObjectManager.CreateObject(o, new World.Vector3D(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); } } break; case Key.F9: if (Interface.MessageCount != 0) { formMessages.ShowMessages(); Application.DoEvents(); } break; case Key.Delete: ReducedMode = false; LightingRelative = -1.0; Game.Reset(); TextureManager.UnuseAllTextures(); Fonts.Initialize(); Interface.ClearMessages(); Files = new string[] {}; UpdateCaption(); 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.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; } }
internal static void Main(string[] args) { // platform and mono int p = (int)Environment.OSVersion.Platform; if (p == 4 | p == 128) { // general Unix CurrentPlatform = Platform.Linux; } else if (p == 6) { // Mac CurrentPlatform = Platform.Mac; } else { // non-Unix CurrentPlatform = Platform.Windows; } CurrentlyRunOnMono = Type.GetType("Mono.Runtime") != null; // file system FileSystem = FileSystem.FromCommandLineArgs(args); FileSystem.CreateFileSystem(); SetPackageLookupDirectories(); // command line arguments bool[] 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 (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; } } } // application Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); 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; } Interface.CurrentOptions.ObjectOptimizationBasicThreshold = 1000; Interface.CurrentOptions.ObjectOptimizationFullThreshold = 250; // initialize sdl window SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DOUBLEBUFFER, 1); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, 16); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_RED_SIZE, 8); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_GREEN_SIZE, 8); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_BLUE_SIZE, 8); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_ALPHA_SIZE, 8); SDL.SDL_ShowCursor(1); // initialize camera ResetCamera(); // create window Renderer.ScreenWidth = 960; Renderer.ScreenHeight = 600; int Bits = 32; //Sdl.SDL_SetVideoMode(Renderer.ScreenWidth, Renderer.ScreenHeight, Bits, Sdl.SDL_OPENGL | Sdl.SDL_DOUBLEBUF); SDLWindow = SDL.SDL_CreateWindow(Application.ProductName, SDL.SDL_WINDOWPOS_UNDEFINED, SDL.SDL_WINDOWPOS_UNDEFINED, Renderer.ScreenWidth, Renderer.ScreenHeight, SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE); if (SDLWindow != IntPtr.Zero) { // create window string File = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder(), "icon.png"); if (System.IO.File.Exists(File)) { // set up icon iconBmp = new Bitmap(File); // load file iconData = iconBmp.LockBits(new Rectangle(0, 0, iconBmp.Width, iconBmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); // lock data iconSurface = SDL.SDL_CreateRGBSurfaceFrom(iconData.Scan0, iconBmp.Width, iconBmp.Height, 32, iconData.Stride, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); // upload to sdl SDL.SDL_SetWindowIcon(SDLWindow, iconSurface); // use icon // free is on the end of the program /* * IntPtr bitmap = SDL.SDL_LoadBMP(File); * if (bitmap != IntPtr.Zero) { * SDL.SDL_Surface Surface = (SDL.SDL_Surface)System.Runtime.InteropServices.Marshal.PtrToStructure(bitmap, typeof(SDL.SDL_Surface)); * uint ColorKey = SDL.SDL_MapRGB(Surface.format, 0, 0, 255); * SDL.SDL_SetColorKey(bitmap, 1, ColorKey); * SDL.SDL_SetWindowIcon(SDLWindow,bitmap); * } */ } GLContext = SDL.SDL_GL_CreateContext(SDLWindow); GraphicsContext tkContext = new GraphicsContext(new ContextHandle(GLContext), SDL.SDL_GL_GetProcAddress, () => new ContextHandle(SDL.SDL_GL_GetCurrentContext())); // anisotropic filtering string[] extensions = GL.GetString(StringName.Extensions).Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); Interface.CurrentOptions.AnisotropicFilteringMaximum = 0; for (int i = 0; i < extensions.Length; i++) { if (extensions[i] == "GL_EXT_texture_filter_anisotropic") { float n; GL.GetFloat((GetPName)ExtTextureFilterAnisotropic.MaxTextureMaxAnisotropyExt, out n); Interface.CurrentOptions.AnisotropicFilteringMaximum = (int)Math.Round((double)n); break; } } if (Interface.CurrentOptions.AnisotropicFilteringMaximum <= 0) { Interface.CurrentOptions.AnisotropicFilteringMaximum = 0; Interface.CurrentOptions.AnisotropicFilteringLevel = 0; Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.AnisotropicFiltering; } else { Interface.CurrentOptions.AnisotropicFilteringLevel = Interface.CurrentOptions.AnisotropicFilteringMaximum; Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.TrilinearMipmapped; } // module initialization Renderer.Initialize(); Renderer.InitializeLighting(); SDL.SDL_GL_SwapWindow(SDLWindow); Fonts.Initialize(); UpdateViewport(); // command line arguments for (int i = 0; i < args.Length; i++) { if (!SkipArgs[i] && System.IO.File.Exists(args[i])) { try { ObjectManager.UnifiedObject o = ObjectManager.LoadObject(args[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new World.Vector3D(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); } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + args[i] + "."); } Array.Resize <string>(ref Files, Files.Length + 1); Files[Files.Length - 1] = args[i]; } } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); UpdateCaption(); Stopwatch timer = new Stopwatch(); timer.Start(); LastTicks = timer.ElapsedMilliseconds; // loop while (!Quit) { long ticks = timer.ElapsedMilliseconds; double timeElapsed = 0.001 * (double)(ticks - LastTicks); if (timeElapsed < 0.0001) { timeElapsed = 0.0001; } LastTicks = ticks; DateTime time = DateTime.Now; Game.SecondsSinceMidnight = (double)(3600 * time.Hour + 60 * time.Minute + time.Second) + 0.001 * (double)time.Millisecond; ObjectManager.UpdateAnimatedWorldObjects(timeElapsed, false); ProcessEvents(); if (ReducedMode) { System.Threading.Thread.Sleep(125); } else { System.Threading.Thread.Sleep(1); } bool updatelight = false; bool keep = false; // rotate x if (RotateX == 0) { double d = (1.0 + Math.Abs(RotateXSpeed)) * timeElapsed; if (RotateXSpeed >= -d & RotateXSpeed <= d) { RotateXSpeed = 0.0; } else { RotateXSpeed -= (double)Math.Sign(RotateXSpeed) * d; } } else { double d = (1.0 + 1.0 - 1.0 / (1.0 + RotateXSpeed * RotateXSpeed)) * timeElapsed; double m = 1.0; RotateXSpeed += (double)RotateX * d; if (RotateXSpeed < -m) { RotateXSpeed = -m; } else if (RotateXSpeed > m) { RotateXSpeed = m; } } if (RotateXSpeed != 0.0) { double cosa = Math.Cos(RotateXSpeed * timeElapsed); double sina = Math.Sin(RotateXSpeed * timeElapsed); World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, 0.0, 1.0, 0.0, cosa, sina); World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, 0.0, 1.0, 0.0, cosa, sina); World.Rotate(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z, 0.0, 1.0, 0.0, cosa, sina); keep = true; } // rotate y if (RotateY == 0) { double d = (1.0 + Math.Abs(RotateYSpeed)) * timeElapsed; if (RotateYSpeed >= -d & RotateYSpeed <= d) { RotateYSpeed = 0.0; } else { RotateYSpeed -= (double)Math.Sign(RotateYSpeed) * d; } } else { double d = (1.0 + 1.0 - 1.0 / (1.0 + RotateYSpeed * RotateYSpeed)) * timeElapsed; double m = 1.0; RotateYSpeed += (double)RotateY * d; if (RotateYSpeed < -m) { RotateYSpeed = -m; } else if (RotateYSpeed > m) { RotateYSpeed = m; } } if (RotateYSpeed != 0.0) { double cosa = Math.Cos(RotateYSpeed * timeElapsed); double sina = Math.Sin(RotateYSpeed * timeElapsed); World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina); World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina); keep = true; } // move x if (MoveX == 0) { double d = (2.5 + Math.Abs(MoveXSpeed)) * timeElapsed; if (MoveXSpeed >= -d & MoveXSpeed <= d) { MoveXSpeed = 0.0; } else { MoveXSpeed -= (double)Math.Sign(MoveXSpeed) * d; } } else { double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveXSpeed * MoveXSpeed)) * timeElapsed; double m = 25.0; MoveXSpeed += (double)MoveX * d; if (MoveXSpeed < -m) { MoveXSpeed = -m; } else if (MoveXSpeed > m) { MoveXSpeed = m; } } if (MoveXSpeed != 0.0) { World.AbsoluteCameraPosition.X += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.X; World.AbsoluteCameraPosition.Y += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.Y; World.AbsoluteCameraPosition.Z += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.Z; keep = true; } // move y if (MoveY == 0) { double d = (2.5 + Math.Abs(MoveYSpeed)) * timeElapsed; if (MoveYSpeed >= -d & MoveYSpeed <= d) { MoveYSpeed = 0.0; } else { MoveYSpeed -= (double)Math.Sign(MoveYSpeed) * d; } } else { double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveYSpeed * MoveYSpeed)) * timeElapsed; double m = 25.0; MoveYSpeed += (double)MoveY * d; if (MoveYSpeed < -m) { MoveYSpeed = -m; } else if (MoveYSpeed > m) { MoveYSpeed = m; } } if (MoveYSpeed != 0.0) { World.AbsoluteCameraPosition.X += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.X; World.AbsoluteCameraPosition.Y += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.Y; World.AbsoluteCameraPosition.Z += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.Z; keep = true; } // move z if (MoveZ == 0) { double d = (2.5 + Math.Abs(MoveZSpeed)) * timeElapsed; if (MoveZSpeed >= -d & MoveZSpeed <= d) { MoveZSpeed = 0.0; } else { MoveZSpeed -= (double)Math.Sign(MoveZSpeed) * d; } } else { double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveZSpeed * MoveZSpeed)) * timeElapsed; double m = 25.0; MoveZSpeed += (double)MoveZ * d; if (MoveZSpeed < -m) { MoveZSpeed = -m; } else if (MoveZSpeed > m) { MoveZSpeed = m; } } if (MoveZSpeed != 0.0) { World.AbsoluteCameraPosition.X += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.X; World.AbsoluteCameraPosition.Y += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.Y; World.AbsoluteCameraPosition.Z += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.Z; keep = true; } // lighting if (LightingRelative == -1) { LightingRelative = (double)LightingTarget; updatelight = true; } if (LightingTarget == 0) { if (LightingRelative != 0.0) { LightingRelative -= 0.5 * timeElapsed; if (LightingRelative < 0.0) { LightingRelative = 0.0; } updatelight = true; keep = true; } } else { if (LightingRelative != 1.0) { LightingRelative += 0.5 * timeElapsed; if (LightingRelative > 1.0) { LightingRelative = 1.0; } updatelight = true; keep = true; } } // continue if (ReducedMode) { ReducedModeEnteringTime = (int)(ticks + 3000); } else { if (keep) { ReducedModeEnteringTime = (int)(ticks + 3000); } else if (ticks > ReducedModeEnteringTime) { ReducedMode = true; World.AbsoluteCameraSide.Y = 0.0; World.Normalize(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z); World.Normalize(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z); World.AbsoluteCameraUp = World.Cross(World.AbsoluteCameraDirection, World.AbsoluteCameraSide); } } if (updatelight) { Renderer.OptionAmbientColor.R = (byte)Math.Round(32.0 + 128.0 * LightingRelative * (2.0 - LightingRelative)); Renderer.OptionAmbientColor.G = (byte)Math.Round(32.0 + 128.0 * 0.5 * (LightingRelative + LightingRelative * (2.0 - LightingRelative))); Renderer.OptionAmbientColor.B = (byte)Math.Round(32.0 + 128.0 * LightingRelative); Renderer.OptionDiffuseColor.R = (byte)Math.Round(32.0 + 128.0 * LightingRelative); Renderer.OptionDiffuseColor.G = (byte)Math.Round(32.0 + 128.0 * LightingRelative); Renderer.OptionDiffuseColor.B = (byte)Math.Round(32.0 + 128.0 * Math.Sqrt(LightingRelative)); Renderer.InitializeLighting(); } Renderer.RenderScene(); SDL.SDL_GL_SwapWindow(SDLWindow); } // quit TextureManager.UnuseAllTextures(); if (iconSurface != IntPtr.Zero) { SDL.SDL_FreeSurface(iconSurface); // free surface } if (iconBmp != null && iconData != null) { iconBmp.UnlockBits(iconData); // free pixels iconBmp.Dispose(); } SDL.SDL_GL_DeleteContext(GLContext); SDL.SDL_DestroyWindow(SDLWindow); SDL.SDL_Quit(); } else { MessageBox.Show("SDL failed to create the window.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); } }
// process events private static void ProcessEvents() { SDL.SDL_Event Event; while (SDL.SDL_PollEvent(out Event) != 0) { switch (Event.type) { // quit case SDL.SDL_EventType.SDL_QUIT: Quit = true; return; // resize case SDL.SDL_EventType.SDL_WINDOWEVENT: if (Event.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED) { Renderer.ScreenWidth = Event.window.data1; Renderer.ScreenHeight = Event.window.data2; UpdateViewport(); } break; // mouse case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN: MouseCenterX = (short)Event.button.x; MouseCenterY = (short)Event.button.y; MouseCameraPosition = World.AbsoluteCameraPosition; MouseCameraDirection = World.AbsoluteCameraDirection; MouseCameraUp = World.AbsoluteCameraUp; MouseCameraSide = World.AbsoluteCameraSide; MouseButton = Event.button.button; break; case SDL.SDL_EventType.SDL_MOUSEBUTTONUP: MouseButton = 0; break; case SDL.SDL_EventType.SDL_MOUSEMOTION: if (MouseButton == SDL.SDL_BUTTON_LEFT) { World.AbsoluteCameraDirection = MouseCameraDirection; World.AbsoluteCameraUp = MouseCameraUp; World.AbsoluteCameraSide = MouseCameraSide; { double dx = 0.0025 * (double)(MouseCenterX - Event.motion.x); double cosa = Math.Cos(dx); double sina = Math.Sin(dx); World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, 0.0, 1.0, 0.0, cosa, sina); World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, 0.0, 1.0, 0.0, cosa, sina); World.Rotate(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z, 0.0, 1.0, 0.0, cosa, sina); } { double dy = 0.0025 * (double)(MouseCenterY - Event.motion.y); double cosa = Math.Cos(dy); double sina = Math.Sin(dy); World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina); World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina); } ReducedMode = false; } else if (MouseButton == SDL.SDL_BUTTON_RIGHT) { World.AbsoluteCameraPosition = MouseCameraPosition; double dx = -0.025 * (double)(Event.motion.x - MouseCenterX); World.AbsoluteCameraPosition.X += dx * World.AbsoluteCameraSide.X; World.AbsoluteCameraPosition.Y += dx * World.AbsoluteCameraSide.Y; World.AbsoluteCameraPosition.Z += dx * World.AbsoluteCameraSide.Z; double dy = 0.025 * (double)(Event.motion.y - MouseCenterY); World.AbsoluteCameraPosition.X += dy * World.AbsoluteCameraUp.X; World.AbsoluteCameraPosition.Y += dy * World.AbsoluteCameraUp.Y; World.AbsoluteCameraPosition.Z += dy * World.AbsoluteCameraUp.Z; ReducedMode = false; } else if (MouseButton == SDL.SDL_BUTTON_MIDDLE) { World.AbsoluteCameraPosition = MouseCameraPosition; double dx = -0.025 * (double)(Event.motion.x - MouseCenterX); World.AbsoluteCameraPosition.X += dx * World.AbsoluteCameraSide.X; World.AbsoluteCameraPosition.Y += dx * World.AbsoluteCameraSide.Y; World.AbsoluteCameraPosition.Z += dx * World.AbsoluteCameraSide.Z; double dz = -0.025 * (double)(Event.motion.y - MouseCenterY); World.AbsoluteCameraPosition.X += dz * World.AbsoluteCameraDirection.X; World.AbsoluteCameraPosition.Y += dz * World.AbsoluteCameraDirection.Y; World.AbsoluteCameraPosition.Z += dz * World.AbsoluteCameraDirection.Z; ReducedMode = false; } break; // key down case SDL.SDL_EventType.SDL_KEYDOWN: switch (Event.key.keysym.sym) { case SDL.SDL_Keycode.SDLK_LSHIFT: case SDL.SDL_Keycode.SDLK_RSHIFT: ShiftPressed = true; break; case SDL.SDL_Keycode.SDLK_F5: // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); TextureManager.UnuseAllTextures(); 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 World.Vector3D(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.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); break; case SDL.SDL_Keycode.SDLK_F7: { OpenFileDialog Dialog = new OpenFileDialog(); Dialog.CheckFileExists = true; Dialog.Multiselect = true; Dialog.Filter = "CSV/B3D/X/ANIMATED files|*.csv;*.b3d;*.x;*.animated|All files|*"; if (Dialog.ShowDialog() == DialogResult.OK) { 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(); TextureManager.UnuseAllTextures(); 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 World.Vector3D(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); } } break; case SDL.SDL_Keycode.SDLK_F9: if (Interface.MessageCount != 0) { formMessages.ShowMessages(); } break; case SDL.SDL_Keycode.SDLK_DELETE: ReducedMode = false; LightingRelative = -1.0; Game.Reset(); TextureManager.UnuseAllTextures(); Fonts.Initialize(); Interface.ClearMessages(); Files = new string[] { }; UpdateCaption(); break; case SDL.SDL_Keycode.SDLK_LEFT: RotateX = -1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_RIGHT: RotateX = 1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_UP: RotateY = -1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_DOWN: RotateY = 1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_a: case SDL.SDL_Keycode.SDLK_KP_4: MoveX = -1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_d: case SDL.SDL_Keycode.SDLK_KP_6: MoveX = 1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_KP_8: MoveY = 1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_KP_2: MoveY = -1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_w: case SDL.SDL_Keycode.SDLK_KP_9: MoveZ = 1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_s: case SDL.SDL_Keycode.SDLK_KP_3: MoveZ = -1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_KP_5: ResetCamera(); break; case SDL.SDL_Keycode.SDLK_f: case SDL.SDL_Keycode.SDLK_F1: Renderer.OptionWireframe = !Renderer.OptionWireframe; if (Renderer.OptionWireframe) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } else { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } break; case SDL.SDL_Keycode.SDLK_n: case SDL.SDL_Keycode.SDLK_F2: Renderer.OptionNormals = !Renderer.OptionNormals; break; case SDL.SDL_Keycode.SDLK_l: case SDL.SDL_Keycode.SDLK_F3: LightingTarget = 1 - LightingTarget; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_i: case SDL.SDL_Keycode.SDLK_F4: Renderer.OptionInterface = !Renderer.OptionInterface; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_g: case SDL.SDL_Keycode.SDLK_c: Renderer.OptionCoordinateSystem = !Renderer.OptionCoordinateSystem; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_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; } break; // key up case SDL.SDL_EventType.SDL_KEYUP: switch (Event.key.keysym.sym) { case SDL.SDL_Keycode.SDLK_LSHIFT: case SDL.SDL_Keycode.SDLK_RSHIFT: ShiftPressed = false; break; case SDL.SDL_Keycode.SDLK_LEFT: case SDL.SDL_Keycode.SDLK_RIGHT: RotateX = 0; break; case SDL.SDL_Keycode.SDLK_UP: case SDL.SDL_Keycode.SDLK_DOWN: RotateY = 0; break; case SDL.SDL_Keycode.SDLK_a: case SDL.SDL_Keycode.SDLK_d: case SDL.SDL_Keycode.SDLK_KP_4: case SDL.SDL_Keycode.SDLK_KP_6: MoveX = 0; break; case SDL.SDL_Keycode.SDLK_KP_8: case SDL.SDL_Keycode.SDLK_KP_2: MoveY = 0; break; case SDL.SDL_Keycode.SDLK_w: case SDL.SDL_Keycode.SDLK_s: case SDL.SDL_Keycode.SDLK_KP_9: case SDL.SDL_Keycode.SDLK_KP_3: MoveZ = 0; break; } break; } } }
private static void ApplyMeshBuilder(ref ObjectManager.StaticObject Object, MeshBuilder Builder, ObjectManager.ObjectLoadMode LoadMode, bool ForceTextureRepeatX, bool ForceTextureRepeatY) { if (Builder.Faces.Length != 0) { int mf = Object.Mesh.Faces.Length; int mm = Object.Mesh.Materials.Length; int mv = Object.Mesh.Vertices.Length; Array.Resize <World.MeshFace>(ref Object.Mesh.Faces, mf + Builder.Faces.Length); Array.Resize <World.MeshMaterial>(ref Object.Mesh.Materials, mm + Builder.Materials.Length); Array.Resize <World.Vertex>(ref Object.Mesh.Vertices, mv + Builder.Vertices.Length); for (int i = 0; i < Builder.Vertices.Length; i++) { Object.Mesh.Vertices[mv + i] = Builder.Vertices[i]; } for (int i = 0; i < Builder.Faces.Length; i++) { Object.Mesh.Faces[mf + i] = Builder.Faces[i]; for (int j = 0; j < Object.Mesh.Faces[mf + i].Vertices.Length; j++) { Object.Mesh.Faces[mf + i].Vertices[j].Index += (ushort)mv; } Object.Mesh.Faces[mf + i].Material += (ushort)mm; } for (int i = 0; i < Builder.Materials.Length; i++) { Object.Mesh.Materials[mm + i].Flags = (byte)((Builder.Materials[i].EmissiveColorUsed ? World.MeshMaterial.EmissiveColorMask : 0) | (Builder.Materials[i].TransparentColorUsed ? World.MeshMaterial.TransparentColorMask : 0)); Object.Mesh.Materials[mm + i].Color = Builder.Materials[i].Color; Object.Mesh.Materials[mm + i].TransparentColor = Builder.Materials[i].TransparentColor; TextureManager.TextureWrapMode WrapX, WrapY; if (ForceTextureRepeatX) { WrapX = TextureManager.TextureWrapMode.Repeat; } else { WrapX = TextureManager.TextureWrapMode.ClampToEdge; } if (ForceTextureRepeatY) { WrapY = TextureManager.TextureWrapMode.Repeat; } else { WrapY = TextureManager.TextureWrapMode.ClampToEdge; } if (WrapX != TextureManager.TextureWrapMode.Repeat | WrapY != TextureManager.TextureWrapMode.Repeat) { for (int j = 0; j < Builder.Vertices.Length; j++) { if (Builder.Vertices[j].TextureCoordinates.X <0.0 | Builder.Vertices[j].TextureCoordinates.X> 1.0) { WrapX = TextureManager.TextureWrapMode.Repeat; } if (Builder.Vertices[j].TextureCoordinates.Y <0.0 | Builder.Vertices[j].TextureCoordinates.Y> 1.0) { WrapY = TextureManager.TextureWrapMode.Repeat; } } } if (Builder.Materials[i].DaytimeTexture != null) { int tday; if (!string.IsNullOrEmpty(Builder.Materials[i].TransparencyTexture)) { Bitmap Main = new Bitmap(Builder.Materials[i].DaytimeTexture); Main = ResizeImage(Main, Main.Size.Width, Main.Size.Height); Bitmap Alpha = new Bitmap(Builder.Materials[i].TransparencyTexture); if (Alpha.Size != Main.Size) { Alpha = ResizeImage(Alpha, Main.Size.Width, Main.Size.Height); } Bitmap texture = MergeAlphaBitmap(Main, Alpha); //Dispose of main and alpha Main.Dispose(); Alpha.Dispose(); tday = TextureManager.RegisterTexture(texture, true); } else { tday = TextureManager.RegisterTexture(Builder.Materials[i].DaytimeTexture, Builder.Materials[i].TransparentColor, Builder.Materials[i].TransparentColorUsed ? (byte)1 : (byte)0, WrapX, WrapY, LoadMode != ObjectManager.ObjectLoadMode.Normal); } Object.Mesh.Materials[mm + i].DaytimeTextureIndex = tday; } else { Object.Mesh.Materials[mm + i].DaytimeTextureIndex = -1; } Object.Mesh.Materials[mm + i].EmissiveColor = Builder.Materials[i].EmissiveColor; if (Builder.Materials[i].NighttimeTexture != null) { int tnight = TextureManager.RegisterTexture(Builder.Materials[i].NighttimeTexture, Builder.Materials[i].TransparentColor, Builder.Materials[i].TransparentColorUsed ? (byte)1 : (byte)0, WrapX, WrapY, LoadMode != ObjectManager.ObjectLoadMode.Normal); Object.Mesh.Materials[mm + i].NighttimeTextureIndex = tnight; } else { Object.Mesh.Materials[mm + i].NighttimeTextureIndex = -1; } Object.Mesh.Materials[mm + i].DaytimeNighttimeBlend = 0; Object.Mesh.Materials[mm + i].BlendMode = Builder.Materials[i].BlendMode; Object.Mesh.Materials[mm + i].GlowAttenuationData = Builder.Materials[i].GlowAttenuationData; } } }
/// <summary>Renders the debug (F10) overlay</summary> private static void RenderDebugOverlays() { System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture; // debug GL.Color4(0.5, 0.5, 0.5, 0.5); LibRender.Renderer.RenderOverlaySolid(0.0f, 0.0f, (double)LibRender.Screen.Width, (double)LibRender.Screen.Height); // actual handles { string t = "actual: " + (TrainManager.PlayerTrain.Handles.Reverser.Actual == TrainManager.ReverserPosition.Reverse ? "B" : TrainManager.PlayerTrain.Handles.Reverser.Actual == TrainManager.ReverserPosition.Forwards ? "F" : "N"); if (TrainManager.PlayerTrain.Handles.SingleHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Actual ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Actual != 0 ? "B" + TrainManager.PlayerTrain.Handles.Brake.Actual.ToString(Culture) : TrainManager.PlayerTrain.Handles.HoldBrake.Actual ? "HLD" : TrainManager.PlayerTrain.Handles.Power.Actual != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Actual.ToString(Culture) : "N"); } else if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.Power.Actual != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Actual.ToString(Culture) : "N"); t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Actual ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Actual == (int)TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.Brake.Actual == (int)TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); } else { t += " - " + (TrainManager.PlayerTrain.Handles.Power.Actual != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Actual.ToString(Culture) : "N"); t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Actual ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Actual != 0 ? "B" + TrainManager.PlayerTrain.Handles.Brake.Actual.ToString(Culture) : TrainManager.PlayerTrain.Handles.HoldBrake.Actual ? "HLD" : "N"); } if (TrainManager.PlayerTrain.Handles.HasLocoBrake) { if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int)TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int)TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); } else { t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual != 0 ? "L" + TrainManager.PlayerTrain.Handles.LocoBrake.Actual.ToString(Culture) : "N"); } } LibRender.Renderer.DrawString(Fonts.SmallFont, t, new System.Drawing.Point(2, LibRender.Screen.Height - 46), TextAlignment.TopLeft, Color128.White, true); } // safety handles { string t = "safety: " + (TrainManager.PlayerTrain.Handles.Reverser.Actual == TrainManager.ReverserPosition.Reverse ? "B" : TrainManager.PlayerTrain.Handles.Reverser.Actual == TrainManager.ReverserPosition.Forwards ? "F" : "N"); if (TrainManager.PlayerTrain.Handles.SingleHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Safety ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Safety != 0 ? "B" + TrainManager.PlayerTrain.Handles.Brake.Safety.ToString(Culture) : TrainManager.PlayerTrain.Handles.HoldBrake.Actual ? "HLD" : TrainManager.PlayerTrain.Handles.Power.Safety != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Safety.ToString(Culture) : "N"); } else if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.Power.Safety != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Safety.ToString(Culture) : "N"); t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Safety ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Safety == (int)TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.Brake.Safety == (int)TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); } else { t += " - " + (TrainManager.PlayerTrain.Handles.Power.Safety != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Safety.ToString(Culture) : "N"); t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Safety ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Safety != 0 ? "B" + TrainManager.PlayerTrain.Handles.Brake.Safety.ToString(Culture) : TrainManager.PlayerTrain.Handles.HoldBrake.Actual ? "HLD" : "N"); } if (TrainManager.PlayerTrain.Handles.HasLocoBrake) { if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int)TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int)TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); } else { t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual != 0 ? "L" + TrainManager.PlayerTrain.Handles.LocoBrake.Actual.ToString(Culture) : "N"); } } LibRender.Renderer.DrawString(Fonts.SmallFont, t, new System.Drawing.Point(2, LibRender.Screen.Height - 32), TextAlignment.TopLeft, Color128.White, true); } // driver handles { string t = "driver: " + (TrainManager.PlayerTrain.Handles.Reverser.Driver == TrainManager.ReverserPosition.Reverse ? "B" : TrainManager.PlayerTrain.Handles.Reverser.Driver == TrainManager.ReverserPosition.Forwards ? "F" : "N"); if (TrainManager.PlayerTrain.Handles.SingleHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Driver != 0 ? "B" + TrainManager.PlayerTrain.Handles.Brake.Driver.ToString(Culture) : TrainManager.PlayerTrain.Handles.HoldBrake.Driver ? "HLD" : TrainManager.PlayerTrain.Handles.Power.Driver != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture) : "N"); } else if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.Power.Driver != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture) : "N"); t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); } else { t += " - " + (TrainManager.PlayerTrain.Handles.Power.Driver != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture) : "N"); t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Driver != 0 ? "B" + TrainManager.PlayerTrain.Handles.Brake.Driver.ToString(Culture) : TrainManager.PlayerTrain.Handles.HoldBrake.Driver ? "HLD" : "N"); } if (TrainManager.PlayerTrain.Handles.HasLocoBrake) { if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int)TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int)TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); } else { t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual != 0 ? "L" + TrainManager.PlayerTrain.Handles.LocoBrake.Actual.ToString(Culture) : "N"); } } LibRender.Renderer.DrawString(Fonts.SmallFont, t, new System.Drawing.Point(2, LibRender.Screen.Height - 18), TextAlignment.TopLeft, Color128.White, true); } // debug information int texturesLoaded = TextureManager.GetNumberOfLoadedTextures(); int texturesRegistered = TextureManager.GetNumberOfRegisteredTextures(); int soundBuffersRegistered = Program.Sounds.GetNumberOfRegisteredBuffers(); int soundBuffersLoaded = Program.Sounds.GetNumberOfLoadedBuffers(); int soundSourcesRegistered = Program.Sounds.GetNumberOfRegisteredSources(); int soundSourcesPlaying = Program.Sounds.GetNumberOfPlayingSources(); int car = 0; for (int i = 0; i < TrainManager.PlayerTrain.Cars.Length; i++) { if (TrainManager.PlayerTrain.Cars[i].Specs.IsMotorCar) { car = i; break; } } double mass = 0.0; for (int i = 0; i < TrainManager.PlayerTrain.Cars.Length; i++) { mass += TrainManager.PlayerTrain.Cars[i].Specs.MassCurrent; } int hours = (int)Game.SecondsSinceMidnight / 3600, remainder = (int)Game.SecondsSinceMidnight % 3600, minutes = remainder / 60, seconds = remainder % 60; string[] Lines = new string[] { "=system", "fps: " + LibRender.Renderer.FrameRate.ToString("0.0", Culture) + (MainLoop.LimitFramerate ? " (low cpu)" : ""), "time:" + hours.ToString("00") + ":" + minutes.ToString("00") + ":" + seconds.ToString("00"), "score: " + Game.CurrentScore.CurrentValue.ToString(Culture), "", "=train", "speed: " + (Math.Abs(TrainManager.PlayerTrain.CurrentSpeed) * 3.6).ToString("0.00", Culture) + " km/h", "power (car " + car.ToString(Culture) + "): " + (TrainManager.PlayerTrain.Cars[car].Specs.CurrentAccelerationOutput < 0.0 ? TrainManager.PlayerTrain.Cars[car].Specs.CurrentAccelerationOutput * (double)Math.Sign(TrainManager.PlayerTrain.Cars[car].CurrentSpeed) : TrainManager.PlayerTrain.Cars[car].Specs.CurrentAccelerationOutput * (double)TrainManager.PlayerTrain.Handles.Reverser.Actual).ToString("0.0000", Culture) + " m/s²", "acceleration: " + TrainManager.PlayerTrain.Specs.CurrentAverageAcceleration.ToString("0.0000", Culture) + " m/s²", "position: " + TrainManager.PlayerTrain.FrontCarTrackPosition().ToString("0.00", Culture) + " m", "elevation: " + (CurrentRoute.InitialElevation + TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].FrontAxle.Follower.WorldPosition.Y).ToString("0.00", Culture) + " m", "temperature: " + (TrainManager.PlayerTrain.Specs.CurrentAirTemperature - 273.15).ToString("0.00", Culture) + " °C", "air pressure: " + (0.001 * TrainManager.PlayerTrain.Specs.CurrentAirPressure).ToString("0.00", Culture) + " kPa", "air density: " + TrainManager.PlayerTrain.Specs.CurrentAirDensity.ToString("0.0000", Culture) + " kg/m³", "speed of sound: " + (Atmosphere.GetSpeedOfSound(TrainManager.PlayerTrain.Specs.CurrentAirDensity) * 3.6).ToString("0.00", Culture) + " km/h", "passenger ratio: " + TrainManager.PlayerTrain.Passengers.PassengerRatio.ToString("0.00"), "total mass: " + mass.ToString("0.00", Culture) + " kg", "", "=route", "track limit: " + (TrainManager.PlayerTrain.CurrentRouteLimit == double.PositiveInfinity ? "unlimited" : ((TrainManager.PlayerTrain.CurrentRouteLimit * 3.6).ToString("0.0", Culture) + " km/h")), "signal limit: " + (TrainManager.PlayerTrain.CurrentSectionLimit == double.PositiveInfinity ? "unlimited" : ((TrainManager.PlayerTrain.CurrentSectionLimit * 3.6).ToString("0.0", Culture) + " km/h")), "total static objects: " + ObjectManager.ObjectsUsed.ToString(Culture), "total static GL_TRIANGLES: " + LibRender.Renderer.InfoTotalTriangles.ToString(Culture), "total static GL_TRIANGLE_STRIP: " + LibRender.Renderer.InfoTotalTriangleStrip.ToString(Culture), "total static GL_QUADS: " + LibRender.Renderer.InfoTotalQuads.ToString(Culture), "total static GL_QUAD_STRIP: " + LibRender.Renderer.InfoTotalQuadStrip.ToString(Culture), "total static GL_POLYGON: " + LibRender.Renderer.InfoTotalPolygon.ToString(Culture), "total animated objects: " + ObjectManager.AnimatedWorldObjectsUsed.ToString(Culture), "", "=renderer", "static opaque faces: " + LibRender.Renderer.InfoStaticOpaqueFaceCount.ToString(Culture), "dynamic opaque faces: " + DynamicOpaque.FaceCount.ToString(Culture), "dynamic alpha faces: " + DynamicAlpha.FaceCount.ToString(Culture), "overlay opaque faces: " + OverlayOpaque.FaceCount.ToString(Culture), "overlay alpha faces: " + OverlayAlpha.FaceCount.ToString(Culture), "textures loaded: " + texturesLoaded.ToString(Culture) + " / " + texturesRegistered.ToString(Culture), "", "=camera", "position: " + World.CameraTrackFollower.TrackPosition.ToString("0.00", Culture) + " m", "curve radius: " + World.CameraTrackFollower.CurveRadius.ToString("0.00", Culture) + " m", "curve cant: " + (1000.0 * Math.Abs(World.CameraTrackFollower.CurveCant)).ToString("0.00", Culture) + " mm" + (World.CameraTrackFollower.CurveCant <0.0 ? " (left)" : World.CameraTrackFollower.CurveCant> 0.0 ? " (right)" : ""), "pitch: " + World.CameraTrackFollower.Pitch.ToString("0.00", Culture), "", "=sound", "sound buffers: " + soundBuffersLoaded.ToString(Culture) + " / " + soundBuffersRegistered.ToString(Culture), "sound sources: " + soundSourcesPlaying.ToString(Culture) + " / " + soundSourcesRegistered.ToString(Culture), (Interface.CurrentOptions.SoundModel == SoundModels.Inverse ? "log clamp factor: " + Program.Sounds.LogClampFactor.ToString("0.00") : "outer radius factor: " + Program.Sounds.OuterRadiusFactor.ToString("0.00", Culture)), "", "=debug", "train plugin status: " + (TrainManager.PlayerTrain.Plugin != null ? (TrainManager.PlayerTrain.Plugin.PluginValid ? "ok" : "error") : "n/a"), "train plugin message: " + (TrainManager.PlayerTrain.Plugin != null ? (TrainManager.PlayerTrain.Plugin.PluginMessage ?? "n/a") : "n/a"), Game.InfoDebugString ?? "" }; double x = 4.0; double y = 4.0; for (int i = 0; i < Lines.Length; i++) { if (Lines[i].Length != 0) { if (Lines[i][0] == '=') { string text = Lines[i].Substring(1); System.Drawing.Size size = Fonts.SmallFont.MeasureString(text); GL.Color4(0.35f, 0.65f, 0.90f, 0.8f); LibRender.Renderer.RenderOverlaySolid(x, y, x + size.Width + 6.0f, y + size.Height + 2.0f); LibRender.Renderer.DrawString(Fonts.SmallFont, text, new System.Drawing.Point((int)x + 3, (int)y), TextAlignment.TopLeft, Color128.White); } else { LibRender.Renderer.DrawString(Fonts.SmallFont, Lines[i], new System.Drawing.Point((int)x, (int)y), TextAlignment.TopLeft, Color128.White, true); } y += 14.0; } else if (y >= (double)LibRender.Screen.Height - 240.0) { x += 280.0; y = 4.0; } else { y += 14.0; } } }
// load all textures private static int[] LoadAllTextures(string BaseFile, World.ColorRGB TransparentColor, byte TransparentColorUsed, TextureManager.TextureLoadMode LoadMode) { string Folder = System.IO.Path.GetDirectoryName(BaseFile); if (!System.IO.Directory.Exists(Folder)) return new int[] { }; string Name = System.IO.Path.GetFileNameWithoutExtension(BaseFile); int[] Textures = new int[] { }; string[] Files = System.IO.Directory.GetFiles(Folder); for (int i = 0; i < Files.Length; i++) { string a = System.IO.Path.GetFileNameWithoutExtension(Files[i]); if (a.StartsWith(Name, StringComparison.OrdinalIgnoreCase)) { if (a.Length > Name.Length) { string b = a.Substring(Name.Length).TrimStart(); int j; if (int.TryParse(b, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out j)) { if (j >= 0) { string c = System.IO.Path.GetExtension(Files[i]); switch (c.ToLowerInvariant()) { case ".bmp": case ".gif": case ".jpg": case ".jpeg": case ".png": case ".tif": case ".tiff": if (j >= Textures.Length) { int n = Textures.Length; Array.Resize<int>(ref Textures, j + 1); for (int k = n; k < j; k++) { Textures[k] = -1; } } Textures[j] = TextureManager.RegisterTexture(Files[i], TransparentColor, TransparentColorUsed, LoadMode, TextureManager.TextureWrapMode.Repeat, TextureManager.TextureWrapMode.Repeat, true, 0, 0, 0, 0); TextureManager.UseTexture(Textures[j], TextureManager.UseMode.Normal); break; } } } } } } return Textures; }
private void button1_Click(object sender, EventArgs e) { TextureManager.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 = TextureManager.InterpolationMode.NearestNeighbor; break; case 1: Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.Bilinear; break; case 2: Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.NearestNeighborMipmapped; break; case 3: Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.BilinearMipmapped; break; case 4: Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.TrilinearMipmapped; break; case 5: Interface.CurrentOptions.Interpolation = TextureManager.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(); TextureManager.UnuseAllTextures(); Fonts.Initialize(); 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 != TextureManager.InterpolationMode.NearestNeighbor & Interface.CurrentOptions.Interpolation != TextureManager.InterpolationMode.Bilinear; Options.SaveOptions(); this.Close(); }