diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index d24ae6ab41..3a3bef1f96 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -304,7 +304,7 @@ namespace OpenRA if (!string.IsNullOrEmpty(supportDirArg)) Platform.OverrideSupportDir(supportDirArg); - Console.WriteLine("Platform is {0}", Platform.CurrentPlatform); + Console.WriteLine($"Platform is {Platform.CurrentPlatform}"); // Load the engine version as early as possible so it can be written to exception logs try @@ -316,8 +316,8 @@ namespace OpenRA if (string.IsNullOrEmpty(EngineVersion)) EngineVersion = "Unknown"; - Console.WriteLine("Engine version is {0}", EngineVersion); - Console.WriteLine("Runtime: {0}", Platform.RuntimeVersion); + Console.WriteLine($"Engine version is {EngineVersion}"); + Console.WriteLine($"Runtime: {Platform.RuntimeVersion}"); // Special case handling of Game.Mod argument: if it matches a real filesystem path // then we use this to override the mod search path, and replace it with the mod id @@ -372,7 +372,7 @@ namespace OpenRA } catch (Exception e) { - Log.Write("graphics", "{0}", e); + Log.Write("graphics", $"{e}"); Console.WriteLine("Renderer initialization failed. Check graphics.log for details."); Renderer?.Dispose(); @@ -391,7 +391,7 @@ namespace OpenRA Mods = new InstalledMods(modSearchPaths, explicitModPaths); Console.WriteLine("Internal mods:"); foreach (var mod in Mods) - Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version); + Console.WriteLine($"\t{mod.Key}: {mod.Value.Metadata.Title} ({mod.Value.Metadata.Version})"); modLaunchWrapper = args.GetValue("Engine.LaunchWrapper", null); @@ -416,7 +416,7 @@ namespace OpenRA Console.WriteLine("External mods:"); foreach (var mod in ExternalMods) - Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version); + Console.WriteLine($"\t{mod.Key}: {mod.Value.Title} ({mod.Value.Version})"); InitializeMod(modID, args); Ui.InitializeTranslation(); @@ -452,7 +452,7 @@ namespace OpenRA if (!Mods.ContainsKey(mod)) throw new InvalidOperationException($"Unknown or invalid mod '{mod}'."); - Console.WriteLine("Loading mod: {0}", mod); + Console.WriteLine($"Loading mod: {mod}"); Sound.StopVideo(); diff --git a/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs b/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs index c3e25f8fde..4027b39cea 100644 --- a/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs +++ b/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs @@ -151,21 +151,28 @@ namespace OpenRA.Platforms.Default if (enableLegacyGL) testProfiles.Add(GLProfile.Legacy); + var errorLog = new List(); supportedProfiles = testProfiles - .Where(CanCreateGLWindow) + .Where(profile => CanCreateGLWindow(profile, errorLog)) .ToArray(); if (!supportedProfiles.Any()) + { + foreach (var error in errorLog) + Log.Write("graphics", error); + throw new InvalidOperationException("No supported OpenGL profiles were found."); + } profile = supportedProfiles.Contains(requestProfile) ? requestProfile : supportedProfiles.First(); // Note: This must be called after the CanCreateGLWindow checks above, // which needs to create and destroy its own SDL contexts as a workaround for specific buggy drivers - SDL.SDL_Init(SDL.SDL_INIT_VIDEO); - SetSDLAttributes(profile); + if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0) + Log.Write("graphics", $"SDL initialisation failed: {SDL.SDL_GetError()}"); - Console.WriteLine("Using SDL 2 with OpenGL ({0}) renderer", profile); + SetSDLAttributes(profile); + Console.WriteLine($"Using SDL 2 with OpenGL ({profile}) renderer"); if (videoDisplay < 0 || videoDisplay >= DisplayCount) videoDisplay = 0; @@ -210,7 +217,7 @@ namespace OpenRA.Platforms.Default } } - Console.WriteLine("Desktop resolution: {0}x{1}", display.w, display.h); + Console.WriteLine($"Desktop resolution: {display.w}x{display.h}"); if (requestEffectiveWindowSize.Width == 0 && requestEffectiveWindowSize.Height == 0) { Console.WriteLine("No custom resolution provided, using desktop resolution"); @@ -219,7 +226,7 @@ namespace OpenRA.Platforms.Default else surfaceSize = windowSize = new Size((int)(requestEffectiveWindowSize.Width * windowScale), (int)(requestEffectiveWindowSize.Height * windowScale)); - Console.WriteLine("Using resolution: {0}x{1}", windowSize.Width, windowSize.Height); + Console.WriteLine($"Using resolution: {windowSize.Width}x{windowSize.Height}"); var windowFlags = SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_ALLOW_HIGHDPI; @@ -510,18 +517,25 @@ namespace OpenRA.Platforms.Default } } - static bool CanCreateGLWindow(GLProfile profile) + static bool CanCreateGLWindow(GLProfile profile, List errorLog) { // Implementation inspired by TestIndividualGLVersion from Veldrid // Need to create and destroy its own SDL contexts as a workaround for specific buggy drivers - SDL.SDL_Init(SDL.SDL_INIT_VIDEO); + if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0) + { + // Continue to harvest additional SDL errors below + errorLog.Add($"{profile}: SDL init failed: {SDL.SDL_GetError()}"); + SDL.SDL_ClearError(); + } + SetSDLAttributes(profile); var flags = SDL.SDL_WindowFlags.SDL_WINDOW_HIDDEN | SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL; var window = SDL.SDL_CreateWindow("", 0, 0, 1, 1, flags); if (window == IntPtr.Zero || !string.IsNullOrEmpty(SDL.SDL_GetError())) { + errorLog.Add($"{profile}: SDL window creation failed: {SDL.SDL_GetError()}"); SDL.SDL_ClearError(); SDL.SDL_Quit(); return false; @@ -530,6 +544,7 @@ namespace OpenRA.Platforms.Default var context = SDL.SDL_GL_CreateContext(window); if (context == IntPtr.Zero || SDL.SDL_GL_MakeCurrent(window, context) < 0) { + errorLog.Add($"{profile}: GL context creation failed: {SDL.SDL_GetError()}"); SDL.SDL_ClearError(); SDL.SDL_DestroyWindow(window); SDL.SDL_Quit(); @@ -542,6 +557,8 @@ namespace OpenRA.Platforms.Default { var isAngle = SDL.SDL_GL_ExtensionSupported("GL_ANGLE_texture_usage") == SDL.SDL_bool.SDL_TRUE; success = isAngle ^ (profile != GLProfile.ANGLE); + if (!success) + errorLog.Add(isAngle ? "GL profile is ANGLE" : "GL profile is Embedded"); } SDL.SDL_GL_DeleteContext(context);