OSDN Git Service

Merge branch 'feature/37178_プロジェクトとソリューションファイルの英語化' into develop
[dtxmania/dtxmania.git] / FDK / コード / 01.フレームワーク / DeviceSettings / Direct3D9Settings.cs
diff --git a/FDK/コード/01.フレームワーク/DeviceSettings/Direct3D9Settings.cs b/FDK/コード/01.フレームワーク/DeviceSettings/Direct3D9Settings.cs
new file mode 100644 (file)
index 0000000..6efe97b
--- /dev/null
@@ -0,0 +1,446 @@
+/*
+* Copyright (c) 2007-2009 SlimDX Group
+* 
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+* 
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+* 
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*/
+using System;
+using System.Collections.Generic;
+using SharpDX.Direct3D9;
+
+namespace SampleFramework
+{
+       class Direct3D9Settings : ICloneable
+       {
+               public int AdapterOrdinal
+               {
+                       get;
+                       set;
+               }
+
+               public DeviceType DeviceType
+               {
+                       get;
+                       set;
+               }
+
+               public Format AdapterFormat
+               {
+                       get;
+                       set;
+               }
+
+               public CreateFlags CreationFlags
+               {
+                       get;
+                       set;
+               }
+
+               public PresentParameters PresentParameters
+               {
+                       get;
+                       set;
+               }
+
+               public Direct3D9Settings()
+               {
+                       PresentParameters = new PresentParameters();
+                       DeviceType = DeviceType.Hardware;
+                       AdapterFormat = Format.Unknown;
+                       CreationFlags = CreateFlags.HardwareVertexProcessing;
+
+                       var pp = this.PresentParameters;
+                       pp.Windowed = true;
+                       pp.BackBufferFormat = Format.Unknown;
+                       pp.BackBufferCount = 1;
+                       pp.MultiSampleType = MultisampleType.None;
+                       pp.SwapEffect = SwapEffect.Discard;
+                       pp.EnableAutoDepthStencil = true;
+                       pp.AutoDepthStencilFormat = Format.Unknown;
+                       pp.PresentFlags = PresentFlags.DiscardDepthStencil;
+                       pp.PresentationInterval = PresentInterval.Default;
+                       this.PresentParameters = pp;
+               }
+
+               public Direct3D9Settings Clone()
+               {
+                       Direct3D9Settings clone = new Direct3D9Settings();
+                       clone.AdapterFormat = AdapterFormat;
+                       clone.AdapterOrdinal = AdapterOrdinal;
+                       clone.CreationFlags = CreationFlags;
+                       clone.DeviceType = DeviceType;
+                       clone.PresentParameters = PresentParameters;
+
+                       return clone;
+               }
+
+               object ICloneable.Clone()
+               {
+                       return Clone();
+               }
+
+               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;
+               }
+
+               public static float RankSettingsCombo(SettingsCombo9 combo, Direct3D9Settings optimal, DisplayMode desktopMode)
+               {
+                       float ranking = 0.0f;
+
+                       if(combo.AdapterOrdinal == optimal.AdapterOrdinal)
+                               ranking += 1000.0f;
+
+                       if(combo.DeviceType == optimal.DeviceType)
+                               ranking += 100.0f;
+
+                       if(combo.DeviceType == DeviceType.Hardware)
+                               ranking += 0.1f;
+
+                       if(combo.Windowed == optimal.PresentParameters.Windowed)
+                               ranking += 10.0f;
+
+                       if(combo.AdapterFormat == optimal.AdapterFormat)
+                               ranking += 1.0f;
+                       else
+                       {
+                               int bitDepthDelta = Math.Abs(ConversionMethods.GetColorBits(combo.AdapterFormat) -
+                                       ConversionMethods.GetColorBits(optimal.AdapterFormat));
+                               float scale = Math.Max(0.9f - bitDepthDelta * 0.2f, 0.0f);
+                               ranking += scale;
+                       }
+
+                       if(!combo.Windowed)
+                       {
+                               bool match;
+                               if(ConversionMethods.GetColorBits(desktopMode.Format) >= 8)
+                                       match = (combo.AdapterFormat == desktopMode.Format);
+                               else
+                                       match = (combo.AdapterFormat == Format.X8R8G8B8);
+
+                               if(match)
+                                       ranking += 0.1f;
+                       }
+
+                       if((optimal.CreationFlags & CreateFlags.HardwareVertexProcessing) != 0 &&
+                               (optimal.CreationFlags & CreateFlags.MixedVertexProcessing) != 0)
+                       {
+                               if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
+                                       ranking += 1.0f;
+                       }
+
+                       if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
+                               ranking += 0.1f;
+
+                       foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
+                       {
+                               if(displayMode.Format == combo.AdapterFormat &&
+                                       displayMode.Width == optimal.PresentParameters.BackBufferWidth &&
+                                       displayMode.Height == optimal.PresentParameters.BackBufferHeight)
+                               {
+                                       ranking += 1.0f;
+                                       break;
+                               }
+                       }
+
+                       if(combo.BackBufferFormat == optimal.PresentParameters.BackBufferFormat)
+                               ranking += 1.0f;
+                       else
+                       {
+                               int bitDepthDelta = Math.Abs(ConversionMethods.GetColorBits(combo.BackBufferFormat) -
+                                       ConversionMethods.GetColorBits(optimal.PresentParameters.BackBufferFormat));
+                               float scale = Math.Max(0.9f - bitDepthDelta * 0.2f, 0.0f);
+                               ranking += scale;
+                       }
+
+                       if(combo.BackBufferFormat == combo.AdapterFormat)
+                               ranking += 0.1f;
+
+                       for(int i = 0; i < combo.MultisampleTypes.Count; i++)
+                       {
+                               MultisampleType type = combo.MultisampleTypes[i];
+                               int quality = combo.MultisampleQualities[i];
+
+                               if(type == optimal.PresentParameters.MultiSampleType && quality == optimal.PresentParameters.MultiSampleQuality)
+                               {
+                                       ranking += 1.0f;
+                                       break;
+                               }
+                       }
+
+                       if(combo.DepthStencilFormats.Contains(optimal.PresentParameters.AutoDepthStencilFormat))
+                               ranking += 1.0f;
+
+                       foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
+                       {
+                               if(displayMode.Format == combo.AdapterFormat &&
+                                       displayMode.RefreshRate == optimal.PresentParameters.FullScreenRefreshRateInHz)
+                               {
+                                       ranking += 1.0f;
+                                       break;
+                               }
+                       }
+
+                       if(combo.PresentIntervals.Contains(optimal.PresentParameters.PresentationInterval))
+                               ranking += 1.0f;
+
+                       return ranking;
+               }
+
+               public static Direct3D9Settings BuildValidSettings(SettingsCombo9 combo, Direct3D9Settings input)
+               {
+                       Direct3D9Settings settings = new Direct3D9Settings();
+                       var pp = settings.PresentParameters;
+
+                       settings.AdapterOrdinal = combo.AdapterOrdinal;
+                       settings.DeviceType = combo.DeviceType;
+                       settings.AdapterFormat = combo.AdapterFormat;
+                       pp.Windowed = combo.Windowed;
+                       pp.BackBufferFormat = combo.BackBufferFormat;
+                       pp.SwapEffect = input.PresentParameters.SwapEffect;
+                       pp.PresentFlags = input.PresentParameters.PresentFlags | PresentFlags.DiscardDepthStencil;
+
+                       settings.CreationFlags = input.CreationFlags;
+                       if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) == 0 &&
+                               ((settings.CreationFlags & CreateFlags.HardwareVertexProcessing) != 0 ||
+                               (settings.CreationFlags & CreateFlags.MixedVertexProcessing) != 0))
+                       {
+                               settings.CreationFlags &= ~CreateFlags.HardwareVertexProcessing;
+                               settings.CreationFlags &= ~CreateFlags.MixedVertexProcessing;
+                               settings.CreationFlags |= CreateFlags.SoftwareVertexProcessing;
+                       }
+
+                       if((settings.CreationFlags & CreateFlags.HardwareVertexProcessing) == 0 &&
+                               (settings.CreationFlags & CreateFlags.MixedVertexProcessing) == 0 &&
+                               (settings.CreationFlags & CreateFlags.SoftwareVertexProcessing) == 0)
+                       {
+                               if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
+                                       settings.CreationFlags |= CreateFlags.HardwareVertexProcessing;
+                               else
+                                       settings.CreationFlags |= CreateFlags.SoftwareVertexProcessing;
+                       }
+
+                       DisplayMode bestDisplayMode = FindValidResolution(combo, input);
+                       pp.BackBufferWidth = bestDisplayMode.Width;
+                       pp.BackBufferHeight = bestDisplayMode.Height;
+
+                       pp.BackBufferCount = input.PresentParameters.BackBufferCount;
+                       if(pp.BackBufferCount > 3)
+                               pp.BackBufferCount = 3;
+                       if(pp.BackBufferCount < 1)
+                               pp.BackBufferCount = 1;
+
+                       if(input.PresentParameters.SwapEffect != SwapEffect.Discard)
+                       {
+                               pp.MultiSampleType = MultisampleType.None;
+                               pp.MultiSampleQuality = 0;
+                       }
+                       else
+                       {
+                               MultisampleType bestType = MultisampleType.None;
+                               int bestQuality = 0;
+
+                               for(int i = 0; i < combo.MultisampleTypes.Count; i++)
+                               {
+                                       MultisampleType type = combo.MultisampleTypes[i];
+                                       int quality = combo.MultisampleQualities[0];
+
+                                       if(Math.Abs(type - input.PresentParameters.MultiSampleType) < Math.Abs(bestType - input.PresentParameters.MultiSampleType))
+                                       {
+                                               bestType = type;
+                                               bestQuality = Math.Min(quality - 1, input.PresentParameters.MultiSampleQuality);
+                                       }
+                               }
+
+                               pp.MultiSampleType = bestType;
+                               pp.MultiSampleQuality = bestQuality;
+                       }
+
+                       List<int> rankings = new List<int>();
+                       int inputDepthBitDepth = ConversionMethods.GetDepthBits(input.PresentParameters.AutoDepthStencilFormat);
+                       int inputStencilBitDepth = ConversionMethods.GetStencilBits(input.PresentParameters.AutoDepthStencilFormat);
+
+                       foreach(Format format in combo.DepthStencilFormats)
+                       {
+                               int currentBitDepth = ConversionMethods.GetDepthBits(format);
+                               int currentStencilDepth = ConversionMethods.GetStencilBits(format);
+
+                               int ranking = Math.Abs(currentBitDepth - inputDepthBitDepth);
+                               ranking += Math.Abs(currentStencilDepth - inputStencilBitDepth);
+                               rankings.Add(ranking);
+                       }
+
+                       int bestRanking = int.MaxValue;
+                       foreach(int ranking in rankings)
+                       {
+                               if(ranking < bestRanking)
+                                       bestRanking = ranking;
+                       }
+                       int bestIndex = rankings.IndexOf(bestRanking);
+
+                       if(bestIndex >= 0)
+                       {
+                               pp.AutoDepthStencilFormat = combo.DepthStencilFormats[bestIndex];
+                               pp.EnableAutoDepthStencil = true;
+                       }
+                       else
+                       {
+                               pp.AutoDepthStencilFormat = Format.Unknown;
+                               pp.EnableAutoDepthStencil = false;
+                       }
+
+                       if(combo.Windowed)
+                               pp.FullScreenRefreshRateInHz = 0;
+                       else
+                       {
+                               int match = input.PresentParameters.FullScreenRefreshRateInHz;
+                               bestDisplayMode.RefreshRate = 0;
+                               if(match != 0)
+                               {
+                                       bestRanking = 100000;
+                                       foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
+                                       {
+                                               if(displayMode.Format != combo.AdapterFormat ||
+                                                       displayMode.Width != bestDisplayMode.Width ||
+                                                       displayMode.Height != bestDisplayMode.Height)
+                                                       continue;
+
+                                               int ranking = Math.Abs(displayMode.RefreshRate - match);
+
+                                               if(ranking < bestRanking)
+                                               {
+                                                       bestDisplayMode.RefreshRate = displayMode.RefreshRate;
+                                                       bestRanking = ranking;
+
+                                                       if(bestRanking == 0)
+                                                               break;
+                                               }
+                                       }
+                               }
+
+                               pp.FullScreenRefreshRateInHz = bestDisplayMode.RefreshRate;
+                       }
+
+                       if(combo.PresentIntervals.Contains(input.PresentParameters.PresentationInterval))
+                               pp.PresentationInterval = input.PresentParameters.PresentationInterval;
+                       else
+                               pp.PresentationInterval = PresentInterval.Default;
+
+                       settings.PresentParameters = pp;
+                       return settings;
+               }
+
+               static DisplayMode FindValidResolution(SettingsCombo9 combo, Direct3D9Settings input)
+               {
+                       DisplayMode bestMode = new DisplayMode();
+
+                       if(combo.Windowed)
+                       {
+                               bestMode.Width = input.PresentParameters.BackBufferWidth;
+                               bestMode.Height = input.PresentParameters.BackBufferHeight;
+                               return bestMode;
+                       }
+
+                       int bestRanking = 100000;
+                       int ranking;
+                       foreach(DisplayMode mode in combo.AdapterInfo.DisplayModes)
+                       {
+                               if(mode.Format != combo.AdapterFormat)
+                                       continue;
+
+                               ranking = Math.Abs(mode.Width - input.PresentParameters.BackBufferWidth) +
+                                       Math.Abs(mode.Height - input.PresentParameters.BackBufferHeight);
+
+                               if(ranking < bestRanking)
+                               {
+                                       bestMode = mode;
+                                       bestRanking = ranking;
+
+                                       if(bestRanking == 0)
+                                               break;
+                               }
+                       }
+
+                       if(bestMode.Width == 0)
+                       {
+                               bestMode.Width = input.PresentParameters.BackBufferWidth;
+                               bestMode.Height = input.PresentParameters.BackBufferHeight;
+                       }
+
+                       return bestMode;
+               }
+       }
+}