/// <summary> /// Finds valid device settings based upon the desired settings. /// </summary> /// <param name="settings">The desired settings.</param> /// <returns>The best valid device settings matching the input settings.</returns> public static DeviceSettings FindValidSettings(DeviceSettings settings) { // check the desired API version try { GraphicsDeviceManager.EnsureD3D10(); } catch (Exception e) { throw new NoCompatibleDevicesException("Could not initialize Direct3D10.", e); } if (!Enumeration10.HasEnumerated) { Enumeration10.Enumerate(); } DeviceSettings newSettings = settings.Clone(); Direct3D10Settings d3d10 = FindValidD3D10Settings(settings); newSettings.Direct3D10 = d3d10; return(newSettings); }
void CreateDevice(DeviceSettings settings) { DeviceSettings oldSettings = CurrentSettings; CurrentSettings = settings; ignoreSizeChanges = true; bool keepCurrentWindowSize = false; if (settings.BackBufferWidth == 0 && settings.BackBufferHeight == 0) { keepCurrentWindowSize = true; } if (settings.Windowed) { if (oldSettings != null && !oldSettings.Windowed) { fullscreenWindowWidth = oldSettings.BackBufferWidth; fullscreenWindowHeight = oldSettings.BackBufferHeight; } } else { if (oldSettings != null && oldSettings.Windowed) { windowedWindowWidth = oldSettings.BackBufferWidth; windowedWindowHeight = oldSettings.BackBufferHeight; } } // check if the device can be reset, or if we need to completely recreate it Result result = SlimDX.DXGI.ResultCode.Success; bool canReset = CanDeviceBeReset(oldSettings, settings); if (canReset) { result = ResetDevice(); } if (result == SlimDX.Direct3D9.ResultCode.DeviceLost) { deviceLost = true; } else if (!canReset || result.IsFailure) { if (oldSettings != null) { ReleaseDevice(); } InitializeDevice(); } UpdateDeviceInformation(); // check if we need to resize if (settings.Windowed && !keepCurrentWindowSize) { int width; int height; if (NativeMethods.IsIconic(game.Window.Handle)) { WINDOWPLACEMENT placement = new WINDOWPLACEMENT(); placement.length = WINDOWPLACEMENT.Length; NativeMethods.GetWindowPlacement(game.Window.Handle, ref placement); // check if we are being restored if ((placement.flags & WindowConstants.WPF_RESTORETOMAXIMIZED) != 0 && placement.showCmd == WindowConstants.SW_SHOWMINIMIZED) { NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_RESTORE); Rectangle rect = NativeMethods.GetClientRectangle(game.Window.Handle); width = rect.Width; height = rect.Height; NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_MINIMIZE); } else { NativeRectangle frame = new NativeRectangle(); NativeMethods.AdjustWindowRect(ref frame, (uint)windowedStyle, false); int frameWidth = frame.right - frame.left; int frameHeight = frame.bottom - frame.top; width = placement.rcNormalPosition.right - placement.rcNormalPosition.left - frameWidth; height = placement.rcNormalPosition.bottom - placement.rcNormalPosition.top - frameHeight; } } else { Rectangle rect = NativeMethods.GetClientRectangle(game.Window.Handle); width = rect.Width; height = rect.Height; } // check if we have a different desired size if (width != settings.BackBufferWidth || height != settings.BackBufferHeight) { if (NativeMethods.IsIconic(game.Window.Handle)) { NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_RESTORE); } if (NativeMethods.IsZoomed(game.Window.Handle)) { NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_RESTORE); } NativeRectangle rect = new NativeRectangle(); rect.right = settings.BackBufferWidth; rect.bottom = settings.BackBufferHeight; NativeMethods.AdjustWindowRect(ref rect, NativeMethods.GetWindowLong(game.Window.Handle, WindowConstants.GWL_STYLE), false); NativeMethods.SetWindowPos(game.Window.Handle, IntPtr.Zero, 0, 0, rect.right - rect.left, rect.bottom - rect.top, WindowConstants.SWP_NOZORDER | WindowConstants.SWP_NOMOVE); Rectangle r = NativeMethods.GetClientRectangle(game.Window.Handle); int clientWidth = r.Width; int clientHeight = r.Height; // check if the size was modified by Windows if (clientWidth != settings.BackBufferWidth || clientHeight != settings.BackBufferHeight) { DeviceSettings newSettings = CurrentSettings.Clone(); newSettings.BackBufferWidth = 0; newSettings.BackBufferHeight = 0; if (newSettings.Direct3D10 != null) { SwapChainDescription scd = newSettings.Direct3D10.SwapChainDescription; ModeDescription md = scd.ModeDescription; md.Width = 0; md.Height = 0; scd.ModeDescription = md; newSettings.Direct3D10.SwapChainDescription = scd; } CreateDevice(newSettings); } } } // if the window is still hidden, make sure it is shown if (!game.Window.Visible) { NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_SHOW); } // set the execution state of the thread if (!IsWindowed) { NativeMethods.SetThreadExecutionState(WindowConstants.ES_DISPLAY_REQUIRED | WindowConstants.ES_CONTINUOUS); } else { NativeMethods.SetThreadExecutionState(WindowConstants.ES_CONTINUOUS); } ignoreSizeChanges = false; }