コード例 #1
0
        void game_FrameStart(object sender, CancelEventArgs e)
        {
            if (Direct3D9.Device == null)
            {
                e.Cancel = true;
                return;
            }

            //if (!game.IsActive || deviceLost)		// #23568 2010.11.3 yyagi: separate conditions to support valiable sleep value when !IsActive.
            if (deviceLost)
            {
                Thread.Sleep(50);
            }
            else if (!game.IsActive && !this.CurrentSettings.EnableVSync)              // #23568 2010.11.4 yyagi: Don't add sleep() while VSync is enabled.
            {
                Thread.Sleep(this.game.InactiveSleepTime.Milliseconds);
            }

            if (deviceLost)
            {
                Result result = Direct3D9.Device.TestCooperativeLevel();
                if (result == ResultCode.DeviceLost)
                {
                    e.Cancel = true;
                    return;
                }

                // if we are windowed, check the adapter format to see if the user
                // changed the desktop format, causing a lost device
                if (IsWindowed)
                {
                    DisplayMode displayMode = GraphicsDeviceManager.Direct3D9Object.GetAdapterDisplayMode(CurrentSettings.Direct3D9.AdapterOrdinal);
                    if (CurrentSettings.Direct3D9.AdapterFormat != displayMode.Format)
                    {
                        DeviceSettings newSettings = CurrentSettings.Clone();
                        ChangeDevice(newSettings);
                        e.Cancel = true;
                        return;
                    }
                }

                result = ResetDevice();
                if (result.Failure)
                {
                    e.Cancel = true;
                    return;
                }
            }

            deviceLost = false;
        }
コード例 #2
0
        public void ChangeDevice(DeviceSettings settings, DeviceSettings minimumSettings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            Enumeration9.MinimumSettings = minimumSettings;

            DeviceSettings validSettings = DeviceSettings.FindValidSettings(settings);

            var pp = validSettings.Direct3D9.PresentParameters;

            pp.DeviceWindowHandle = game.Window.Handle;
            validSettings.Direct3D9.PresentParameters = pp;

            CreateDevice(validSettings);
        }
コード例 #3
0
        public void ToggleFullScreen()
        {
            if (!EnsureDevice())
            {
                throw new InvalidOperationException("No valid device.");
            }

            DeviceSettings newSettings = CurrentSettings.Clone();

            newSettings.Windowed = !newSettings.Windowed;

            int width  = newSettings.Windowed ? windowedWindowWidth : fullscreenWindowWidth;
            int height = newSettings.Windowed ? windowedWindowHeight : fullscreenWindowHeight;

            newSettings.BackBufferWidth  = width;
            newSettings.BackBufferHeight = height;

            ChangeDevice(newSettings);
        }
コード例 #4
0
        void Window_UserResized(object sender, EventArgs e)
        {
            if (ignoreSizeChanges || !EnsureDevice() || (!IsWindowed))
            {
                return;
            }

            DeviceSettings newSettings = CurrentSettings.Clone();

            Rectangle rect = NativeMethods.GetClientRectangle(game.Window.Handle);

            if (rect.Width != newSettings.BackBufferWidth || rect.Height != newSettings.BackBufferHeight)
            {
                newSettings.BackBufferWidth  = 0;
                newSettings.BackBufferHeight = 0;
                var pp = newSettings.Direct3D9.PresentParameters;
                pp.BackBufferWidth  = GameWindowSize.Width;                 // #23510 2010.10.31 add yyagi: to avoid setting BackBufferSize=ClientSize
                pp.BackBufferHeight = GameWindowSize.Height;                // #23510 2010.10.31 add yyagi: to avoid setting BackBufferSize=ClientSize
                newSettings.Direct3D9.PresentParameters = pp;
                CreateDevice(newSettings);
            }
        }
コード例 #5
0
        /// <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)
        {
            try
            {
                GraphicsDeviceManager.EnsureD3D9();
            }
            catch (Exception e)
            {
                throw new NoCompatibleDevicesException("Could not initialize Direct3D9.", e);
            }

            if (!Enumeration9.HasEnumerated)
            {
                Enumeration9.Enumerate();
            }

            DeviceSettings    newSettings = settings.Clone();
            Direct3D9Settings d3d9        = FindValidD3D9Settings(settings);

            newSettings.Direct3D9 = d3d9;
            return(newSettings);
        }
コード例 #6
0
        static Direct3D9Settings FindValidD3D9Settings(DeviceSettings settings)
        {
            Direct3D9Settings optimal = Direct3D9Settings.BuildOptimalSettings(settings);

            SettingsCombo9 bestCombo   = null;
            float          bestRanking = -1.0f;

            foreach (AdapterInfo9 adapterInfo in Enumeration9.Adapters)
            {
                DisplayMode desktopMode = GraphicsDeviceManager.Direct3D9Object.GetAdapterDisplayMode(adapterInfo.AdapterOrdinal);
                foreach (DeviceInfo9 deviceInfo in adapterInfo.Devices)
                {
                    foreach (SettingsCombo9 combo in deviceInfo.DeviceSettings)
                    {
                        if (combo.Windowed && combo.AdapterFormat != desktopMode.Format)
                        {
                            continue;
                        }

                        float ranking = Direct3D9Settings.RankSettingsCombo(combo, optimal, desktopMode);
                        if (ranking > bestRanking)
                        {
                            bestCombo   = combo;
                            bestRanking = ranking;
                        }
                    }
                }
            }

            if (bestCombo == null)
            {
                throw new NoCompatibleDevicesException("No compatible Direct3D9 devices found.");
            }

            return(Direct3D9Settings.BuildValidSettings(bestCombo, optimal));
        }
コード例 #7
0
        public static Direct3D9Settings BuildOptimalSettings(DeviceSettings settings)
        {
            DisplayMode       desktopMode = GraphicsDeviceManager.Direct3D9Object.GetAdapterDisplayMode(0);
            Direct3D9Settings optimal     = new Direct3D9Settings();
            var pp = optimal.PresentParameters;

            optimal.AdapterOrdinal       = settings.AdapterOrdinal;
            optimal.DeviceType           = settings.DeviceType;
            pp.Windowed                  = settings.Windowed;
            pp.BackBufferCount           = settings.BackBufferCount;
            pp.MultiSampleType           = settings.MultisampleType;
            pp.MultiSampleQuality        = settings.MultisampleQuality;
            pp.FullScreenRefreshRateInHz = settings.RefreshRate;

            if (settings.Multithreaded)
            {
                optimal.CreationFlags |= CreateFlags.Multithreaded;
            }

            if (optimal.PresentParameters.Windowed || ConversionMethods.GetColorBits(desktopMode.Format) >= 8)
            {
                optimal.AdapterFormat = desktopMode.Format;
            }
            else
            {
                optimal.AdapterFormat = Format.X8R8G8B8;
            }

            if (settings.BackBufferWidth == 0 || settings.BackBufferHeight == 0)
            {
                if (optimal.PresentParameters.Windowed)
                {
                    pp.BackBufferWidth  = 640;
                    pp.BackBufferHeight = 480;
                }
                else
                {
                    pp.BackBufferWidth  = desktopMode.Width;
                    pp.BackBufferHeight = desktopMode.Height;
                }
            }
            else
            {
                pp.BackBufferWidth  = settings.BackBufferWidth;
                pp.BackBufferHeight = settings.BackBufferHeight;
            }

            if (settings.BackBufferFormat == Format.Unknown)
            {
                pp.BackBufferFormat = optimal.AdapterFormat;
            }
            else
            {
                pp.BackBufferFormat = settings.BackBufferFormat;
            }

            if (settings.DepthStencilFormat == Format.Unknown)
            {
                if (ConversionMethods.GetColorBits(optimal.PresentParameters.BackBufferFormat) >= 8)
                {
                    pp.AutoDepthStencilFormat = Format.D32;
                }
                else
                {
                    pp.AutoDepthStencilFormat = Format.D16;
                }
            }
            else
            {
                pp.AutoDepthStencilFormat = settings.DepthStencilFormat;
            }

            if (!settings.EnableVSync)
            {
                pp.PresentationInterval = PresentInterval.Immediate;
            }

            optimal.PresentParameters = pp;
            return(optimal);
        }
コード例 #8
0
        void CreateDevice(DeviceSettings settings)
        {
            DeviceSettings oldSettings = CurrentSettings;

            CurrentSettings = settings;

            ignoreSizeChanges = true;

            bool keepCurrentWindowSize = false;

            if (settings.BackBufferWidth == 0 && settings.BackBufferHeight == 0)
            {
                keepCurrentWindowSize = true;
            }

            // handle the window state in Direct3D9 (it will be handled for us in DXGI)
            // check if we are going to windowed or fullscreen mode
            if (settings.Windowed)
            {
                if (oldSettings != null && !oldSettings.Windowed)
                {
                    NativeMethods.SetWindowLong(game.Window.Handle, WindowConstants.GWL_STYLE, (uint)windowedStyle);
                }
            }
            else
            {
                if (oldSettings == null || oldSettings.Windowed)
                {
                    savedTopmost = game.Window.TopMost;
                    long style = NativeMethods.GetWindowLong(game.Window.Handle, WindowConstants.GWL_STYLE);
                    style        &= ~WindowConstants.WS_MAXIMIZE & ~WindowConstants.WS_MINIMIZE;
                    windowedStyle = style;

                    windowedPlacement        = new WINDOWPLACEMENT();
                    windowedPlacement.length = WINDOWPLACEMENT.Length;
                    NativeMethods.GetWindowPlacement(game.Window.Handle, ref windowedPlacement);
                }

                // hide the window until we are done messing with it
                game.Window.Hide();
                NativeMethods.SetWindowLong(game.Window.Handle, WindowConstants.GWL_STYLE, (uint)(WindowConstants.WS_POPUP | WindowConstants.WS_SYSMENU));

                WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
                placement.length = WINDOWPLACEMENT.Length;
                NativeMethods.GetWindowPlacement(game.Window.Handle, ref placement);

                // check if we are in the middle of a restore
                if ((placement.flags & WindowConstants.WPF_RESTORETOMAXIMIZED) != 0)
                {
                    // update the flags to avoid sizing issues
                    placement.flags  &= ~WindowConstants.WPF_RESTORETOMAXIMIZED;
                    placement.showCmd = WindowConstants.SW_RESTORE;
                    NativeMethods.SetWindowPlacement(game.Window.Handle, ref placement);
                }
            }

            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   = ResultCode.Success;
            bool   canReset = CanDeviceBeReset(oldSettings, settings);

            if (canReset)
            {
                result = ResetDevice();
            }

            if (result == ResultCode.DeviceLost)
            {
                deviceLost = true;
            }
            else if (!canReset || result.Failure)
            {
                if (oldSettings != null)
                {
                    ReleaseDevice();
                }

                InitializeDevice();
            }

            UpdateDeviceInformation();

            // check if we changed from fullscreen to windowed mode
            if (oldSettings != null && !oldSettings.Windowed && settings.Windowed)
            {
                NativeMethods.SetWindowPlacement(game.Window.Handle, ref windowedPlacement);
                game.Window.TopMost = savedTopmost;
            }

            // 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.Direct3D9 != null)
                        {
                            var pp = newSettings.Direct3D9.PresentParameters;
                            pp.BackBufferWidth  = GameWindowSize.Width;                             // #23510 2010.10.31 add yyagi: to avoid setting BackBufferSize=ClientSize
                            pp.BackBufferHeight = GameWindowSize.Height;                            // #23510 2010.10.31 add yyagi: to avoid setting BackBufferSize=ClientSize
                            newSettings.Direct3D9.PresentParameters = pp;
                        }

                        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;
        }
コード例 #9
0
 public void ChangeDevice(DeviceSettings settings)
 {
     ChangeDevice(settings, null);
 }