diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 804939411b..881949eacc 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -14,8 +14,8 @@ using System.Drawing; using System.IO; using System.Linq; using System.Net; -using OpenRA.FileSystem; using MaxMind.GeoIP2; +using OpenRA.FileSystem; using OpenRA.Graphics; using OpenRA.Network; using OpenRA.Primitives; @@ -464,7 +464,7 @@ namespace OpenRA return shellmaps.Random(CosmeticRandom); } - static bool quit; + static RunStatus state = RunStatus.Running; public static event Action OnQuit = () => { }; static double idealFrameTime; @@ -473,7 +473,7 @@ namespace OpenRA idealFrameTime = 1.0 / fps; } - internal static void Run() + internal static RunStatus Run() { if (Settings.Graphics.MaxFramerate < 1) { @@ -483,7 +483,7 @@ namespace OpenRA SetIdealFrameTime(Settings.Graphics.MaxFramerate); - while (!quit) + while (state == RunStatus.Running) { if (Settings.Graphics.CapFramerate) { @@ -506,9 +506,19 @@ namespace OpenRA Renderer.Device.Dispose(); OnQuit(); + + return state; } - public static void Exit() { quit = true; } + public static void Exit() + { + state = RunStatus.Success; + } + + public static void Restart() + { + state = RunStatus.Restart; + } public static Action AddChatLine = (c, n, s) => { }; diff --git a/OpenRA.Game/Support/Program.cs b/OpenRA.Game/Support/Program.cs index 4257d61c5a..1313760448 100644 --- a/OpenRA.Game/Support/Program.cs +++ b/OpenRA.Game/Support/Program.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -11,30 +11,37 @@ using System; using System.Diagnostics; using System.Linq; +using System.Reflection; using System.Text; namespace OpenRA { + enum RunStatus + { + Error = -1, + Success = 0, + Restart = 1, + Running = int.MaxValue + } + static class Program { [STAThread] - static void Main(string[] args) + static int Main(string[] args) { if (Debugger.IsAttached || args.Contains("--just-die")) - { - Run(args); - return; - } + return (int)Run(args); AppDomain.CurrentDomain.UnhandledException += (_, e) => FatalError((Exception)e.ExceptionObject); try { - Run(args); + return (int)Run(args); } catch (Exception e) { FatalError(e); + return (int)RunStatus.Error; } } @@ -102,11 +109,25 @@ namespace OpenRA return sb; } - static void Run(string[] args) + static RunStatus Run(string[] args) { + if (AppDomain.CurrentDomain.IsDefaultAppDomain()) + { + var name = Assembly.GetEntryAssembly().GetName(); + int retCode; + do + { + var domain = AppDomain.CreateDomain("Game"); + retCode = domain.ExecuteAssemblyByName(name, args); + AppDomain.Unload(domain); + } + while (retCode == (int)RunStatus.Restart); + return RunStatus.Success; + } + Game.Initialize(new Arguments(args)); GC.Collect(); - Game.Run(); + return Game.Run(); } } } \ No newline at end of file diff --git a/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs index 0510e992eb..f3e829fe4e 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs @@ -28,6 +28,24 @@ namespace OpenRA.Mods.RA.Widgets.Logic WorldRenderer worldRenderer; SoundDevice soundDevice; + static readonly string originalSoundDevice; + static readonly string originalSoundEngine; + static readonly WindowMode originalGraphicsMode; + static readonly string originalGraphicsRenderer; + static readonly int2 originalGraphicsWindowedSize; + static readonly int2 originalGraphicsFullscreenSize; + + static SettingsLogic() + { + var original = Game.Settings; + originalSoundDevice = original.Sound.Device; + originalSoundEngine = original.Sound.Engine; + originalGraphicsMode = original.Graphics.Mode; + originalGraphicsRenderer = original.Graphics.Renderer; + originalGraphicsWindowedSize = original.Graphics.WindowedSize; + originalGraphicsFullscreenSize = original.Graphics.FullscreenSize; + } + [ObjectCreator.UseCtor] public SettingsLogic(Widget widget, Action onExit, WorldRenderer worldRenderer) { @@ -44,9 +62,25 @@ namespace OpenRA.Mods.RA.Widgets.Logic panelContainer.Get("BACK_BUTTON").OnClick = () => { leavePanelActions[settingsPanel](); - Game.Settings.Save(); - Ui.CloseWindow(); - onExit(); + var current = Game.Settings; + current.Save(); + + Action closeAndExit = () => { Ui.CloseWindow(); onExit(); }; + if (originalSoundDevice != current.Sound.Device || + originalSoundEngine != current.Sound.Engine || + originalGraphicsMode != current.Graphics.Mode || + originalGraphicsRenderer != current.Graphics.Renderer || + originalGraphicsWindowedSize != current.Graphics.WindowedSize || + originalGraphicsFullscreenSize != current.Graphics.FullscreenSize) + ConfirmationDialogs.PromptConfirmAction( + "Restart Now?", + "Some changes will not be applied until\nthe game is restarted. Restart now?", + Game.Restart, + closeAndExit, + "Restart Now", + "Restart Later"); + else + closeAndExit(); }; panelContainer.Get("RESET_BUTTON").OnClick = () => diff --git a/OpenRA.Renderer.Sdl2/Sdl2Input.cs b/OpenRA.Renderer.Sdl2/Sdl2Input.cs index b90b4c7604..6b133589ae 100644 --- a/OpenRA.Renderer.Sdl2/Sdl2Input.cs +++ b/OpenRA.Renderer.Sdl2/Sdl2Input.cs @@ -170,9 +170,7 @@ namespace OpenRA.Renderer.Sdl2 // Special case workaround for windows users if (e.key.keysym.sym == SDL.SDL_Keycode.SDLK_F4 && mods.HasModifier(Modifiers.Alt) && Platform.CurrentPlatform == PlatformType.Windows) - { Game.Exit(); - } else inputHandler.OnKeyInput(keyEvent);