private static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // --- determine the running environment --- CurrentlyRunningOnMono = Type.GetType("Mono.Runtime") != null; CurrentlyRunningOnWindows = Environment.OSVersion.Platform == PlatformID.Win32S | Environment.OSVersion.Platform == PlatformID.Win32Windows | Environment.OSVersion.Platform == PlatformID.Win32NT; CurrentHost = new Host(); try { FileSystem = FileSystem.FromCommandLineArgs(args); FileSystem.CreateFileSystem(); } catch (Exception ex) { MessageBox.Show("The file system configuration could not be accessed or is invalid due to the following reason:\n\n" + ex.Message, "openBVE", MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } // --- set up packages --- SetPackageLookupDirectories(); // --- load options and controls --- Interface.LoadOptions(); Interface.LoadControls(null, out Interface.CurrentControls); { string folder = Program.FileSystem.GetDataFolder("Controls"); string file = OpenBveApi.Path.CombineFile(folder, "Default keyboard assignment.controls"); Interface.Control[] controls; Interface.LoadControls(file, out controls); Interface.AddControls(ref Interface.CurrentControls, controls); } // --- load language --- { string folder = Program.FileSystem.GetDataFolder("Languages"); string file = OpenBveApi.Path.CombineFile(folder, Interface.CurrentOptions.LanguageCode + ".cfg"); if (!System.IO.File.Exists(file)) { file = OpenBveApi.Path.CombineFile(folder, "en-US.cfg"); } Interface.LoadLanguage(file); } // --- check the command-line arguments for route and train --- formMain.MainDialogResult result = new formMain.MainDialogResult(); for (int i = 0; i < args.Length; i++) { if (args[i].StartsWith("/route=", StringComparison.OrdinalIgnoreCase)) { result.RouteFile = args[i].Substring(7); result.RouteEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.RouteEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.RouteEncodings[j].Value, result.RouteFile, StringComparison.InvariantCultureIgnoreCase) == 0) { result.RouteEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.RouteEncodings[j].Codepage); break; } } } else if (args[i].StartsWith("/train=", StringComparison.OrdinalIgnoreCase)) { result.TrainFolder = args[i].Substring(7); result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } // --- check whether route and train exist --- if (result.RouteFile != null) { if (!System.IO.File.Exists(result.RouteFile)) { result.RouteFile = null; } } if (result.TrainFolder != null) { if (!System.IO.Directory.Exists(result.TrainFolder)) { result.TrainFolder = null; } } // --- if a route was provided but no train, try to use the route default --- if (result.RouteFile != null & result.TrainFolder == null) { bool isRW = string.Equals(System.IO.Path.GetExtension(result.RouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(result.RouteFile, isRW, result.RouteEncoding, null, null, null, true); if (Game.TrainName != null && Game.TrainName.Length != 0) { string folder = System.IO.Path.GetDirectoryName(result.RouteFile); while (true) { string trainFolder = OpenBveApi.Path.CombineDirectory(folder, "Train"); if (System.IO.Directory.Exists(trainFolder)) { folder = OpenBveApi.Path.CombineDirectory(trainFolder, Game.TrainName); if (System.IO.Directory.Exists(folder)) { string file = OpenBveApi.Path.CombineFile(folder, "train.dat"); if (System.IO.File.Exists(file)) { result.TrainFolder = folder; result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } break; } else { System.IO.DirectoryInfo info = System.IO.Directory.GetParent(folder); if (info != null) { folder = info.FullName; } else { break; } } } } Game.Reset(false); } // --- show the main menu if necessary --- if (result.RouteFile == null | result.TrainFolder == null) { // begin HACK // if (!Joysticks.Initialize()) { MessageBox.Show("SDL failed to initialize the joystick subsystem.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } // end HACK // result = formMain.ShowMainDialog(result); } else { result.Start = true; } // --- start the actual program --- if (result.Start) { if (Initialize()) { #if !DEBUG try { #endif MainLoop.StartLoopEx(result); #if !DEBUG } catch (Exception ex) { bool found = false; for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i] != null && TrainManager.Trains[i].Plugin != null) { if (TrainManager.Trains[i].Plugin.LastException != null) { MessageBox.Show("The train plugin " + TrainManager.Trains[i].Plugin.PluginTitle + " caused a runtime exception: " + TrainManager.Trains[i].Plugin.LastException.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); found = true; break; } } } if (!found) { MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); } } #endif } Deinitialize(); } // --- restart the program if necessary --- if (RestartArguments != null) { string arguments; if (FileSystem.RestartArguments.Length != 0 & RestartArguments.Length != 0) { arguments = FileSystem.RestartArguments + " " + RestartArguments; } else { arguments = FileSystem.RestartArguments + RestartArguments; } try { System.Diagnostics.Process.Start(FileSystem.RestartProcess, arguments); } catch (Exception ex) { MessageBox.Show(ex.Message + "\n\nProcess = " + FileSystem.RestartProcess + "\nArguments = " + arguments, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
private static void Main(string[] args) { // Add handler for UI thread exceptions Application.ThreadException += (CrashHandler.UIThreadException); // Force all WinForms errors to go through handler Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // This handler is for catching non-UI thread exceptions AppDomain.CurrentDomain.UnhandledException += (CrashHandler.CurrentDomain_UnhandledException); //Determine the current CPU architecture- //ARM will generally only support OpenGL-ES PortableExecutableKinds peKind; typeof(object).Module.GetPEKind(out peKind, out CurrentCPUArchitecture); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //--- determine the running environment --- //I wonder if disabling this hack will stop the craashing on Linux.... CurrentlyRunningOnMono = Type.GetType("Mono.Runtime") != null; //Doesn't appear to, but Mono have fixed the button appearance bug CurrentlyRunningOnWindows = Environment.OSVersion.Platform == PlatformID.Win32S | Environment.OSVersion.Platform == PlatformID.Win32Windows | Environment.OSVersion.Platform == PlatformID.Win32NT; Joysticks = new JoystickManager(); CurrentHost = new Host(); try { FileSystem = FileSystem.FromCommandLineArgs(args); FileSystem.CreateFileSystem(); } catch (Exception ex) { MessageBox.Show(Translations.GetInterfaceString("errors_filesystem_invalid") + Environment.NewLine + Environment.NewLine + ex.Message, Translations.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } Renderer = new NewRenderer(); Sounds = new Sounds(); CurrentRoute = new CurrentRoute(Renderer); //Platform specific startup checks if (CurrentlyRunningOnMono && !CurrentlyRunningOnWindows) { // --- Check if we're running as root, and prompt not to --- if (getuid() == 0) { MessageBox.Show( "You are currently running as the root user." + System.Environment.NewLine + "This is a bad idea, please dont!", Translations.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); } if (File.Exists(@"/System/Library/CoreServices/SystemVersion.plist")) { //Mono's platform detection doesn't reliably differentiate between OS-X and Unix CurrentlyRunningOnMacOS = true; } } else { if (!System.IO.File.Exists(System.IO.Path.Combine(Environment.SystemDirectory, "OpenAL32.dll"))) { MessageBox.Show( "OpenAL was not found on your system, and will now be installed." + System.Environment.NewLine + System.Environment.NewLine + "Please follow the install prompts.", Translations.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); ProcessStartInfo info = new ProcessStartInfo(Path.Combine(FileSystem.DataFolder, "Dependencies\\Win32\\oalinst.exe")); info.UseShellExecute = true; if (Environment.OSVersion.Version.Major >= 6) { info.Verb = "runas"; } try { Process p = Process.Start(info); if (p != null) { p.WaitForExit(); } else { //For unknown reasons, the process failed to trigger, but did not raise an exception itself //Throw one throw new Win32Exception(); } } catch (Win32Exception) { MessageBox.Show( "An error occured during OpenAL installation....", Translations.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); } } } // --- load options and controls --- Interface.LoadOptions(); //Switch between SDL2 and native backends; use native backend by default var options = new ToolkitOptions(); if (Interface.CurrentOptions.PreferNativeBackend) { options.Backend = PlatformBackend.PreferNative; } Toolkit.Init(options); // --- load language --- string folder = Program.FileSystem.GetDataFolder("Languages"); Translations.LoadLanguageFiles(folder); folder = Program.FileSystem.GetDataFolder("Cursors"); Cursors.LoadCursorImages(folder); Interface.LoadControls(null, out Interface.CurrentControls); folder = Program.FileSystem.GetDataFolder("Controls"); string file = OpenBveApi.Path.CombineFile(folder, "Default keyboard assignment.controls"); Interface.Control[] controls; Interface.LoadControls(file, out controls); Interface.AddControls(ref Interface.CurrentControls, controls); InputDevicePlugin.LoadPlugins(Program.FileSystem); // --- check the command-line arguments for route and train --- formMain.MainDialogResult result = new formMain.MainDialogResult(); CommandLine.ParseArguments(args, ref result); // --- check whether route and train exist --- if (result.RouteFile != null) { if (!System.IO.File.Exists(result.RouteFile)) { result.RouteFile = null; } } if (result.TrainFolder != null) { if (!System.IO.Directory.Exists(result.TrainFolder)) { result.TrainFolder = null; } } // --- if a route was provided but no train, try to use the route default --- if (result.RouteFile != null & result.TrainFolder == null) { if (!Plugins.LoadPlugins()) { throw new Exception("Unable to load the required plugins- Please reinstall OpenBVE"); } Game.Reset(false); bool loaded = false; for (int i = 0; i < Program.CurrentHost.Plugins.Length; i++) { if (Program.CurrentHost.Plugins[i].Route != null && Program.CurrentHost.Plugins[i].Route.CanLoadRoute(result.RouteFile)) { object Route = (object)Program.CurrentRoute; //must cast to allow us to use the ref keyword. Program.CurrentHost.Plugins[i].Route.LoadRoute(result.RouteFile, result.RouteEncoding, null, null, null, true, ref Route); Program.CurrentRoute = (CurrentRoute)Route; Program.Renderer.Lighting.OptionAmbientColor = CurrentRoute.Atmosphere.AmbientLightColor; Program.Renderer.Lighting.OptionDiffuseColor = CurrentRoute.Atmosphere.DiffuseLightColor; Program.Renderer.Lighting.OptionLightPosition = CurrentRoute.Atmosphere.LightPosition; loaded = true; break; } } Plugins.UnloadPlugins(); if (!loaded) { throw new Exception("No plugins capable of loading routefile " + result.RouteFile + " were found."); } if (!string.IsNullOrEmpty(Interface.CurrentOptions.TrainName)) { folder = System.IO.Path.GetDirectoryName(result.RouteFile); while (true) { string trainFolder = OpenBveApi.Path.CombineDirectory(folder, "Train"); if (System.IO.Directory.Exists(trainFolder)) { try { folder = OpenBveApi.Path.CombineDirectory(trainFolder, Interface.CurrentOptions.TrainName); } catch (Exception ex) { if (ex is ArgumentException) { break; } } if (System.IO.Directory.Exists(folder)) { file = OpenBveApi.Path.CombineFile(folder, "train.dat"); if (System.IO.File.Exists(file)) { result.TrainFolder = folder; result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } break; } if (folder == null) { continue; } System.IO.DirectoryInfo info = System.IO.Directory.GetParent(folder); if (info != null) { folder = info.FullName; } else { break; } } } Game.Reset(false); } // --- show the main menu if necessary --- if (result.RouteFile == null | result.TrainFolder == null) { Joysticks.RefreshJoysticks(); // end HACK // result = formMain.ShowMainDialog(result); } else { result.Start = true; //Apply translations Translations.SetInGameLanguage(Translations.CurrentLanguageCode); } // --- start the actual program --- if (result.Start) { if (Initialize()) { #if !DEBUG try { #endif MainLoop.StartLoopEx(result); #if !DEBUG } catch (Exception ex) { bool found = false; for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i] != null && TrainManager.Trains[i].Plugin != null) { if (TrainManager.Trains[i].Plugin.LastException != null) { CrashHandler.LoadingCrash(ex.Message, true); MessageBox.Show("The train plugin " + TrainManager.Trains[i].Plugin.PluginTitle + " caused a runtime exception: " + TrainManager.Trains[i].Plugin.LastException.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); found = true; RestartArguments = ""; break; } } } if (!found) { if (ex is System.DllNotFoundException) { Interface.AddMessage(MessageType.Critical, false, "The required system library " + ex.Message + " was not found on the system."); switch (ex.Message) { case "libopenal.so.1": MessageBox.Show("openAL was not found on this system. \n Please install libopenal1 via your distribtion's package management system.", Translations.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); break; default: MessageBox.Show("The required system library " + ex.Message + " was not found on this system.", Translations.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); break; } } else { Interface.AddMessage(MessageType.Critical, false, "The route and train loader encountered the following critical error: " + ex.Message); CrashHandler.LoadingCrash(ex + Environment.StackTrace, false); } RestartArguments = ""; } } #endif } Deinitialize(); } // --- restart the program if necessary --- if (RestartArguments != null) { string arguments; if (FileSystem.RestartArguments.Length != 0 & RestartArguments.Length != 0) { arguments = FileSystem.RestartArguments + " " + RestartArguments; } else { arguments = FileSystem.RestartArguments + RestartArguments; } try { System.Diagnostics.Process.Start(System.IO.File.Exists(FileSystem.RestartProcess) ? FileSystem.RestartProcess : Application.ExecutablePath, arguments); } catch (Exception ex) { MessageBox.Show(ex.Message + "\n\nProcess = " + FileSystem.RestartProcess + "\nArguments = " + arguments, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
// start private static void Start(string[] Args) { // initialize sdl video if (Sdl.SDL_Init(Sdl.SDL_INIT_VIDEO) != 0) { MessageBox.Show("SDL failed to initialize the video subsystem.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } if (Sdl.SDL_Init(Sdl.SDL_INIT_JOYSTICK) != 0) { MessageBox.Show("SDL failed to initialize the joystick subsystem.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } // initialize sdl joysticks { int n = Sdl.SDL_NumJoysticks(); Interface.CurrentJoysticks = new Interface.Joystick[n]; for (int i = 0; i < n; i++) { Interface.CurrentJoysticks[i].SdlHandle = Sdl.SDL_JoystickOpen(i); if (CurrentPlatform == Platform.Windows) { string s = Sdl.SDL_JoystickName(i); /* string returned is ascii packed in utf-16 (2 chars per codepoint) */ System.Text.StringBuilder t = new System.Text.StringBuilder(s.Length << 1); for (int k = 0; k < s.Length; k++) { int a = (int)s[k]; t.Append(char.ConvertFromUtf32(a & 0xFF) + char.ConvertFromUtf32(a >> 8)); } Interface.CurrentJoysticks[i].Name = t.ToString(); } else { Interface.CurrentJoysticks[i].Name = Sdl.SDL_JoystickName(i); } } } // load options and controls Interface.LoadOptions(); Interface.LoadControls(null, out Interface.CurrentControls); { string f = Interface.GetCombinedFileName(Program.FileSystem.GetDataFolder("Controls"), "Default keyboard assignment.controls"); Interface.Control[] c; Interface.LoadControls(f, out c); Interface.AddControls(ref Interface.CurrentControls, c); } // command line arguments formMain.MainDialogResult Result = new formMain.MainDialogResult(); for (int i = 0; i < Args.Length; i++) { if (Args[i].StartsWith("/route=", StringComparison.OrdinalIgnoreCase)) { Result.RouteFile = Args[i].Substring(7); Result.RouteEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.RouteEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.RouteEncodings[j].Value, Result.RouteFile, StringComparison.InvariantCultureIgnoreCase) == 0) { Result.RouteEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.RouteEncodings[j].Codepage); break; } } } else if (Args[i].StartsWith("/train=", StringComparison.OrdinalIgnoreCase)) { Result.TrainFolder = Args[i].Substring(7); Result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, Result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { Result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } // train provided if (Result.TrainFolder != null) { if (System.IO.Directory.Exists(Result.TrainFolder)) { string File = Interface.GetCombinedFileName(Result.TrainFolder, "train.dat"); if (System.IO.File.Exists(File)) { Result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, Result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { Result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); } } } else { Result.TrainFolder = null; } } else { Result.TrainFolder = null; } } // route provided if (Result.RouteFile != null) { if (!System.IO.File.Exists(Result.RouteFile)) { Result.RouteFile = null; } } // route provided but no train if (Result.RouteFile != null & Result.TrainFolder == null) { bool IsRW = string.Equals(System.IO.Path.GetExtension(Result.RouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(Result.RouteFile, IsRW, Result.RouteEncoding, null, null, null, true); if (Game.TrainName != null && Game.TrainName.Length != 0) { string Folder = System.IO.Path.GetDirectoryName(Result.RouteFile); while (true) { string TrainFolder = Interface.GetCombinedFolderName(Folder, "Train"); if (System.IO.Directory.Exists(TrainFolder)) { Folder = Interface.GetCombinedFolderName(TrainFolder, Game.TrainName); if (System.IO.Directory.Exists(Folder)) { string File = Interface.GetCombinedFileName(Folder, "train.dat"); if (System.IO.File.Exists(File)) { // associated train found Result.TrainFolder = Folder; Result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, Result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { Result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } break; } else { System.IO.DirectoryInfo Info = System.IO.Directory.GetParent(Folder); if (Info != null) { Folder = Info.FullName; } else { break; } } } } Game.Reset(false); } // show main menu if applicable if (Result.RouteFile == null | Result.TrainFolder == null) { Result = formMain.ShowMainDialog(); if (!Result.Start) { return; } } // screen int Width = Interface.CurrentOptions.FullscreenMode ? Interface.CurrentOptions.FullscreenWidth : Interface.CurrentOptions.WindowWidth; int Height = Interface.CurrentOptions.FullscreenMode ? Interface.CurrentOptions.FullscreenHeight : Interface.CurrentOptions.WindowHeight; if (Width < 16) { Width = 16; } if (Height < 16) { Height = 16; } Renderer.ScreenWidth = Width; Renderer.ScreenHeight = Height; World.AspectRatio = (double)Renderer.ScreenWidth / (double)Renderer.ScreenHeight; const double degree = 0.0174532925199433; World.VerticalViewingAngle = 45.0 * degree; World.HorizontalViewingAngle = 2.0 * Math.Atan(Math.Tan(0.5 * World.VerticalViewingAngle) * World.AspectRatio); World.OriginalVerticalViewingAngle = World.VerticalViewingAngle; World.ExtraViewingDistance = 50.0; World.ForwardViewingDistance = (double)Interface.CurrentOptions.ViewingDistance; World.BackwardViewingDistance = 0.0; World.BackgroundImageDistance = (double)Interface.CurrentOptions.ViewingDistance; // load route and train SoundManager.Initialize(); if (!Loading.Load(Result.RouteFile, Result.RouteEncoding, Result.TrainFolder, Result.TrainEncoding)) { return; } Game.LogRouteName = System.IO.Path.GetFileName(Result.RouteFile); Game.LogTrainName = System.IO.Path.GetFileName(Result.TrainFolder); Game.LogDateTime = DateTime.Now; // initialize sdl window Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_DOUBLEBUFFER, 1); Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_DEPTH_SIZE, 24); Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_RED_SIZE, 8); Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_GREEN_SIZE, 8); Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_BLUE_SIZE, 8); Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_SWAP_CONTROL, Interface.CurrentOptions.VerticalSynchronization ? 1 : 0); Sdl.SDL_ShowCursor(Sdl.SDL_DISABLE); SdlWindowCreated = true; int Bits = Interface.CurrentOptions.FullscreenMode ? Interface.CurrentOptions.FullscreenBits : 32; // --- window caption and icon --- Sdl.SDL_WM_SetCaption(Application.ProductName, null); { string bitmapFile = OpenBveApi.Path.CombineFile(Program.FileSystem.DataFolder, "icon.bmp"); IntPtr bitmap = Sdl.SDL_LoadBMP(bitmapFile); if (bitmap != null) { string maskFile = OpenBveApi.Path.CombineFile(Program.FileSystem.DataFolder, "mask.bin"); byte[] mask = System.IO.File.ReadAllBytes(maskFile); Sdl.SDL_WM_SetIcon(bitmap, mask); } } // create window int fullscreen = Interface.CurrentOptions.FullscreenMode ? Sdl.SDL_FULLSCREEN : 0; IntPtr video = Sdl.SDL_SetVideoMode(Width, Height, Bits, Sdl.SDL_OPENGL | Sdl.SDL_DOUBLEBUF | fullscreen); if (video != IntPtr.Zero) { // anisotropic filtering string[] Extensions = Gl.glGetString(Gl.GL_EXTENSIONS).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); Interface.CurrentOptions.AnisotropicFilteringMaximum = 0; for (int i = 0; i < Extensions.Length; i++) { if (string.Compare(Extensions[i], "GL_EXT_texture_filter_anisotropic", StringComparison.OrdinalIgnoreCase) == 0) { float n; Gl.glGetFloatv(Gl.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, out n); Interface.CurrentOptions.AnisotropicFilteringMaximum = (int)Math.Round((double)n); break; } } if (Interface.CurrentOptions.AnisotropicFilteringMaximum <= 0) { Interface.CurrentOptions.AnisotropicFilteringMaximum = 0; Interface.CurrentOptions.AnisotropicFilteringLevel = 0; } else if (Interface.CurrentOptions.AnisotropicFilteringLevel == 0 & Interface.CurrentOptions.AnisotropicFilteringMaximum > 0) { Interface.CurrentOptions.AnisotropicFilteringLevel = Interface.CurrentOptions.AnisotropicFilteringMaximum; } else if (Interface.CurrentOptions.AnisotropicFilteringLevel > Interface.CurrentOptions.AnisotropicFilteringMaximum) { Interface.CurrentOptions.AnisotropicFilteringLevel = Interface.CurrentOptions.AnisotropicFilteringMaximum; } // module initialization Fonts.Initialize(); Renderer.Initialize(); Renderer.InitializeLighting(); Sdl.SDL_GL_SwapBuffers(); Timetable.CreateTimetable(); // camera MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); MainLoop.InitializeMotionBlur(); // start loop MainLoop.StartLoop(); } else { // failed MessageBox.Show("SDL failed to create the window.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); } }
private static void Main(string[] args) { #if !DEBUG // Add handler for UI thread exceptions Application.ThreadException += new ThreadExceptionEventHandler(CrashHandler.UIThreadException); // Force all WinForms errors to go through handler Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // This handler is for catching non-UI thread exceptions AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CrashHandler.CurrentDomain_UnhandledException); #endif //Determine the current CPU architecture- //ARM will generally only support OpenGL-ES PortableExecutableKinds peKind; typeof(object).Module.GetPEKind(out peKind, out CurrentCPUArchitecture); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //--- determine the running environment --- //I wonder if disabling this hack will stop the craashing on Linux.... CurrentlyRunningOnMono = Type.GetType("Mono.Runtime") != null; //Doesn't appear to, but Mono have fixed the button appearance bug CurrentlyRunningOnWindows = Environment.OSVersion.Platform == PlatformID.Win32S | Environment.OSVersion.Platform == PlatformID.Win32Windows | Environment.OSVersion.Platform == PlatformID.Win32NT; Joysticks = new JoystickManager(); CurrentHost = new Host(); try { FileSystem = FileSystem.FromCommandLineArgs(args); FileSystem.CreateFileSystem(); } catch (Exception ex) { MessageBox.Show(Interface.GetInterfaceString("errors_filesystem_invalid") + Environment.NewLine + Environment.NewLine + ex.Message, Interface.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } //Platform specific startup checks if (CurrentlyRunningOnMono && !CurrentlyRunningOnWindows) { // --- Check if we're running as root, and prompt not to --- if (getuid() == 0) { MessageBox.Show( "You are currently running as the root user." + System.Environment.NewLine + "This is a bad idea, please dont!", Interface.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); } } else { if (!System.IO.File.Exists(System.IO.Path.Combine(Environment.SystemDirectory, "OpenAL32.dll"))) { MessageBox.Show( "OpenAL was not found on your system, and will now be installed." + System.Environment.NewLine + System.Environment.NewLine + "Please follow the install prompts.", Interface.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); ProcessStartInfo info = new ProcessStartInfo(System.IO.Path.Combine(FileSystem.DataFolder, "Dependencies\\Win32\\oalinst.exe")); info.UseShellExecute = true; if (Environment.OSVersion.Version.Major >= 6) { info.Verb = "runas"; } try { System.Diagnostics.Process p = System.Diagnostics.Process.Start(info); p.WaitForExit(); } catch (Win32Exception) { MessageBox.Show( "An error occured during OpenAL installation....", Interface.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); } } } // --- load options and controls --- Interface.LoadOptions(); //Switch between SDL2 and native backends; use native backend by default var options = new ToolkitOptions(); if (Interface.CurrentOptions.PreferNativeBackend) { options.Backend = PlatformBackend.PreferNative; } Toolkit.Init(options); // --- load language --- { string folder = Program.FileSystem.GetDataFolder("Languages"); try { string[] LanguageFiles = Directory.GetFiles(folder, "*.cfg"); foreach (var File in LanguageFiles) { Interface.AddLanguage(File); } } catch { MessageBox.Show(@"An error occured whilst attempting to load the default language files."); //Environment.Exit(0); } } Interface.LoadControls(null, out Interface.CurrentControls); { string folder = Program.FileSystem.GetDataFolder("Controls"); string file = OpenBveApi.Path.CombineFile(folder, "Default keyboard assignment.controls"); Interface.Control[] controls; Interface.LoadControls(file, out controls); Interface.AddControls(ref Interface.CurrentControls, controls); } // --- check the command-line arguments for route and train --- formMain.MainDialogResult result = new formMain.MainDialogResult(); CommandLine.ParseArguments(args, ref result); // --- check whether route and train exist --- if (result.RouteFile != null) { if (!System.IO.File.Exists(result.RouteFile)) { result.RouteFile = null; } } if (result.TrainFolder != null) { if (!System.IO.Directory.Exists(result.TrainFolder)) { result.TrainFolder = null; } } // --- if a route was provided but no train, try to use the route default --- if (result.RouteFile != null & result.TrainFolder == null) { bool isRW = string.Equals(System.IO.Path.GetExtension(result.RouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(result.RouteFile, isRW, result.RouteEncoding, null, null, null, true); if (!string.IsNullOrEmpty(Game.TrainName)) { string folder = System.IO.Path.GetDirectoryName(result.RouteFile); while (true) { string trainFolder = OpenBveApi.Path.CombineDirectory(folder, "Train"); if (System.IO.Directory.Exists(trainFolder)) { folder = OpenBveApi.Path.CombineDirectory(trainFolder, Game.TrainName); if (System.IO.Directory.Exists(folder)) { string file = OpenBveApi.Path.CombineFile(folder, "train.dat"); if (System.IO.File.Exists(file)) { result.TrainFolder = folder; result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } break; } if (folder == null) { continue; } System.IO.DirectoryInfo info = System.IO.Directory.GetParent(folder); if (info != null) { folder = info.FullName; } else { break; } } } Game.Reset(false); } // --- show the main menu if necessary --- if (result.RouteFile == null | result.TrainFolder == null) { Joysticks.RefreshJoysticks(); // end HACK // result = formMain.ShowMainDialog(result); } else { result.Start = true; //Apply translations Interface.SetInGameLanguage(Interface.CurrentLanguageCode); } // --- start the actual program --- if (result.Start) { if (Initialize()) { #if !DEBUG try { #endif MainLoop.StartLoopEx(result); #if !DEBUG } catch (Exception ex) { bool found = false; //Thread.Sleep(20); for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i] != null && TrainManager.Trains[i].Plugin != null) { if (TrainManager.Trains[i].Plugin.LastException != null) { CrashHandler.LoadingCrash(ex.Message, true); MessageBox.Show("The train plugin " + TrainManager.Trains[i].Plugin.PluginTitle + " caused a runtime exception: " + TrainManager.Trains[i].Plugin.LastException.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); found = true; RestartArguments = ""; break; } } } if (!found) { MessageBox.Show("The route and train loader encountered the following critical error: " + Environment.NewLine + ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); CrashHandler.LoadingCrash(ex.ToString(), false); RestartArguments = ""; } } #endif } Deinitialize(); } // --- restart the program if necessary --- if (RestartArguments != null) { string arguments; if (FileSystem.RestartArguments.Length != 0 & RestartArguments.Length != 0) { arguments = FileSystem.RestartArguments + " " + RestartArguments; } else { arguments = FileSystem.RestartArguments + RestartArguments; } try { System.Diagnostics.Process.Start(System.IO.File.Exists(FileSystem.RestartProcess) ? FileSystem.RestartProcess : Application.ExecutablePath, arguments); } catch (Exception ex) { MessageBox.Show(ex.Message + "\n\nProcess = " + FileSystem.RestartProcess + "\nArguments = " + arguments, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
private static void Main(string[] args) { // --- load options and controls --- try { FileSystem = FileSystem.FromCommandLineArgs(args, CurrentHost); FileSystem.CreateFileSystem(); Interface.LoadOptions(); } catch { // ignored } //Switch between SDL2 and native backends; use native backend by default var options = new ToolkitOptions(); if (Interface.CurrentOptions.PreferNativeBackend) { options.Backend = PlatformBackend.PreferNative; } Toolkit.Init(options); // Add handler for UI thread exceptions Application.ThreadException += (CrashHandler.UIThreadException); // Force all WinForms errors to go through handler Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // This handler is for catching non-UI thread exceptions AppDomain.CurrentDomain.UnhandledException += (CrashHandler.CurrentDomain_UnhandledException); //Determine the current CPU architecture- //ARM will generally only support OpenGL-ES PortableExecutableKinds peKind; typeof(object).Module.GetPEKind(out peKind, out CurrentCPUArchitecture); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); CurrentHost = new Host(); if (IntPtr.Size == 4) { Joysticks = new JoystickManager32(); } else { Joysticks = new JoystickManager64(); } try { FileSystem = FileSystem.FromCommandLineArgs(args, CurrentHost); FileSystem.CreateFileSystem(); } catch (Exception ex) { MessageBox.Show(Translations.GetInterfaceString("errors_filesystem_invalid") + Environment.NewLine + Environment.NewLine + ex.Message, Translations.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } Renderer = new NewRenderer(CurrentHost, Interface.CurrentOptions, FileSystem); Sounds = new Sounds(); CurrentRoute = new CurrentRoute(CurrentHost, Renderer); //Platform specific startup checks // --- Check if we're running as root, and prompt not to --- if (CurrentHost.Platform == HostPlatform.GNULinux && (getuid() == 0 || geteuid() == 0)) { MessageBox.Show( "You are currently running as the root user, or via the sudo command." + System.Environment.NewLine + "This is a bad idea, please dont!", Translations.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); } TrainManager = new TrainManager(CurrentHost, Renderer, Interface.CurrentOptions, FileSystem); // --- load language --- string folder = Program.FileSystem.GetDataFolder("Languages"); Translations.LoadLanguageFiles(folder); folder = Program.FileSystem.GetDataFolder("Cursors"); Cursors.LoadCursorImages(folder); Interface.LoadControls(null, out Interface.CurrentControls); folder = Program.FileSystem.GetDataFolder("Controls"); string file = OpenBveApi.Path.CombineFile(folder, "Default keyboard assignment.controls"); Control[] controls; Interface.LoadControls(file, out controls); Interface.AddControls(ref Interface.CurrentControls, controls); InputDevicePlugin.LoadPlugins(Program.FileSystem); // --- check the command-line arguments for route and train --- formMain.MainDialogResult result = new formMain.MainDialogResult(); CommandLine.ParseArguments(args, ref result); // --- check whether route and train exist --- if (result.RouteFile != null) { if (!System.IO.File.Exists(result.RouteFile)) { result.RouteFile = null; } } if (result.TrainFolder != null) { if (!System.IO.Directory.Exists(result.TrainFolder)) { result.TrainFolder = null; } } // --- if a route was provided but no train, try to use the route default --- if (result.RouteFile != null & result.TrainFolder == null) { string error; if (!CurrentHost.LoadPlugins(FileSystem, Interface.CurrentOptions, out error, TrainManager, Renderer)) { MessageBox.Show(error, @"OpenBVE", MessageBoxButtons.OK, MessageBoxIcon.Error); throw new Exception("Unable to load the required plugins- Please reinstall OpenBVE"); } Game.Reset(false); bool loaded = false; for (int i = 0; i < Program.CurrentHost.Plugins.Length; i++) { if (Program.CurrentHost.Plugins[i].Route != null && Program.CurrentHost.Plugins[i].Route.CanLoadRoute(result.RouteFile)) { object Route = (object)Program.CurrentRoute; //must cast to allow us to use the ref keyword. Program.CurrentHost.Plugins[i].Route.LoadRoute(result.RouteFile, result.RouteEncoding, null, null, null, true, ref Route); Program.CurrentRoute = (CurrentRoute)Route; Program.Renderer.Lighting.OptionAmbientColor = CurrentRoute.Atmosphere.AmbientLightColor; Program.Renderer.Lighting.OptionDiffuseColor = CurrentRoute.Atmosphere.DiffuseLightColor; Program.Renderer.Lighting.OptionLightPosition = CurrentRoute.Atmosphere.LightPosition; loaded = true; break; } } if (!CurrentHost.UnloadPlugins(out error)) { MessageBox.Show(error, @"OpenBVE", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (!loaded) { throw new Exception("No plugins capable of loading routefile " + result.RouteFile + " were found."); } if (!string.IsNullOrEmpty(Interface.CurrentOptions.TrainName)) { folder = System.IO.Path.GetDirectoryName(result.RouteFile); while (true) { string trainFolder = OpenBveApi.Path.CombineDirectory(folder, "Train"); if (System.IO.Directory.Exists(trainFolder)) { try { folder = OpenBveApi.Path.CombineDirectory(trainFolder, Interface.CurrentOptions.TrainName); } catch (Exception ex) { if (ex is ArgumentException) { break; } } if (System.IO.Directory.Exists(folder)) { file = OpenBveApi.Path.CombineFile(folder, "train.dat"); if (System.IO.File.Exists(file)) { result.TrainFolder = folder; result.TrainEncoding = System.Text.Encoding.UTF8; for (int j = 0; j < Interface.CurrentOptions.TrainEncodings.Length; j++) { if (string.Compare(Interface.CurrentOptions.TrainEncodings[j].Value, result.TrainFolder, StringComparison.InvariantCultureIgnoreCase) == 0) { result.TrainEncoding = System.Text.Encoding.GetEncoding(Interface.CurrentOptions.TrainEncodings[j].Codepage); break; } } } } break; } if (folder == null) { continue; } System.IO.DirectoryInfo info = System.IO.Directory.GetParent(folder); if (info != null) { folder = info.FullName; } else { break; } } } Game.Reset(false); } // --- show the main menu if necessary --- if (result.RouteFile == null | result.TrainFolder == null) { Joysticks.RefreshJoysticks(); if (CurrentHost.Platform == HostPlatform.AppleOSX && IntPtr.Size != 4) { //WinForms are not supported on 64-bit Apple, so show the experimental GL menu result.ExperimentalGLMenu = true; } else { if (!result.ExperimentalGLMenu) { result = formMain.ShowMainDialog(result); } } } else { result.Start = true; //Apply translations Translations.SetInGameLanguage(Translations.CurrentLanguageCode); } if (result.ExperimentalGLMenu) { result.Start = true; result.RouteFile = null; result.TrainFolder = null; } // --- start the actual program --- if (result.Start) { if (Initialize()) { #if !DEBUG try { #endif MainLoop.StartLoopEx(result); #if !DEBUG } catch (Exception ex) { bool found = false; for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i] != null && TrainManager.Trains[i].Plugin != null) { if (TrainManager.Trains[i].Plugin.LastException != null) { CrashHandler.LoadingCrash(ex.Message, true); MessageBox.Show("The train plugin " + TrainManager.Trains[i].Plugin.PluginTitle + " caused a runtime exception: " + TrainManager.Trains[i].Plugin.LastException.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); found = true; RestartArguments = ""; break; } } } if (!found) { if (ex is System.DllNotFoundException) { Interface.AddMessage(MessageType.Critical, false, "The required system library " + ex.Message + " was not found on the system."); switch (ex.Message) { case "libopenal.so.1": MessageBox.Show("openAL was not found on this system. \n Please install libopenal1 via your distribtion's package management system.", Translations.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); break; default: MessageBox.Show("The required system library " + ex.Message + " was not found on this system.", Translations.GetInterfaceString("program_title"), MessageBoxButtons.OK, MessageBoxIcon.Hand); break; } } else { Interface.AddMessage(MessageType.Critical, false, "The route and train loader encountered the following critical error: " + ex.Message); CrashHandler.LoadingCrash(ex + Environment.StackTrace, false); } RestartArguments = ""; } } #endif } Deinitialize(); } // --- restart the program if necessary --- if (RestartArguments != null) { string arguments; if (FileSystem.RestartArguments.Length != 0 & RestartArguments.Length != 0) { arguments = FileSystem.RestartArguments + " " + RestartArguments; } else { arguments = FileSystem.RestartArguments + RestartArguments; } try { System.Diagnostics.Process.Start(System.IO.File.Exists(FileSystem.RestartProcess) ? FileSystem.RestartProcess : Application.ExecutablePath, arguments); } catch (Exception ex) { MessageBox.Show(ex.Message + "\n\nProcess = " + FileSystem.RestartProcess + "\nArguments = " + arguments, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }