OSDN Git Service

リポジトリの中間ファイルをすべて削除し、再構築。
[dtxmania/dtxmania.git] / FDK17プロジェクト / コード / 01.フレームワーク / DeviceSettings / Direct3D9Settings.cs
1 /*\r
2 * Copyright (c) 2007-2009 SlimDX Group\r
3\r
4 * Permission is hereby granted, free of charge, to any person obtaining a copy\r
5 * of this software and associated documentation files (the "Software"), to deal\r
6 * in the Software without restriction, including without limitation the rights\r
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
8 * copies of the Software, and to permit persons to whom the Software is\r
9 * furnished to do so, subject to the following conditions:\r
10\r
11 * The above copyright notice and this permission notice shall be included in\r
12 * all copies or substantial portions of the Software.\r
13\r
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
20 * THE SOFTWARE.\r
21 */\r
22 using System;\r
23 using System.Collections.Generic;\r
24 using SlimDX.Direct3D9;\r
25 \r
26 namespace SampleFramework\r
27 {\r
28         class Direct3D9Settings : ICloneable\r
29         {\r
30                 public int AdapterOrdinal\r
31                 {\r
32                         get;\r
33                         set;\r
34                 }\r
35 \r
36                 public DeviceType DeviceType\r
37                 {\r
38                         get;\r
39                         set;\r
40                 }\r
41 \r
42                 public Format AdapterFormat\r
43                 {\r
44                         get;\r
45                         set;\r
46                 }\r
47 \r
48                 public CreateFlags CreationFlags\r
49                 {\r
50                         get;\r
51                         set;\r
52                 }\r
53 \r
54                 public PresentParameters PresentParameters\r
55                 {\r
56                         get;\r
57                         private set;\r
58                 }\r
59 \r
60                 public Direct3D9Settings()\r
61                 {\r
62                         PresentParameters = new PresentParameters();\r
63                         DeviceType = DeviceType.Hardware;\r
64                         PresentParameters.Windowed = true;\r
65                         AdapterFormat = Format.Unknown;\r
66                         CreationFlags = CreateFlags.HardwareVertexProcessing;\r
67                         PresentParameters.BackBufferFormat = Format.Unknown;\r
68                         PresentParameters.BackBufferCount = 1;\r
69                         PresentParameters.Multisample = MultisampleType.None;\r
70                         PresentParameters.SwapEffect = SwapEffect.Discard;\r
71                         PresentParameters.EnableAutoDepthStencil = true;\r
72                         PresentParameters.AutoDepthStencilFormat = Format.Unknown;\r
73                         PresentParameters.PresentFlags = PresentFlags.DiscardDepthStencil;\r
74                         PresentParameters.PresentationInterval = PresentInterval.Default;\r
75                 }\r
76 \r
77                 public Direct3D9Settings Clone()\r
78                 {\r
79                         Direct3D9Settings clone = new Direct3D9Settings();\r
80                         clone.AdapterFormat = AdapterFormat;\r
81                         clone.AdapterOrdinal = AdapterOrdinal;\r
82                         clone.CreationFlags = CreationFlags;\r
83                         clone.DeviceType = DeviceType;\r
84                         clone.PresentParameters = PresentParameters.Clone();\r
85 \r
86                         return clone;\r
87                 }\r
88 \r
89                 object ICloneable.Clone()\r
90                 {\r
91                         return Clone();\r
92                 }\r
93 \r
94                 public static Direct3D9Settings BuildOptimalSettings(DeviceSettings settings)\r
95                 {\r
96                         DisplayMode desktopMode = GraphicsDeviceManager.Direct3D9Object.GetAdapterDisplayMode(0);\r
97                         Direct3D9Settings optimal = new Direct3D9Settings();\r
98 \r
99                         optimal.AdapterOrdinal = settings.AdapterOrdinal;\r
100                         optimal.DeviceType = settings.DeviceType;\r
101                         optimal.PresentParameters.Windowed = settings.Windowed;\r
102                         optimal.PresentParameters.BackBufferCount = settings.BackBufferCount;\r
103                         optimal.PresentParameters.Multisample = settings.MultisampleType;\r
104                         optimal.PresentParameters.MultisampleQuality = settings.MultisampleQuality;\r
105                         optimal.PresentParameters.FullScreenRefreshRateInHertz = settings.RefreshRate;\r
106 \r
107                         if(settings.Multithreaded)\r
108                                 optimal.CreationFlags |= CreateFlags.Multithreaded;\r
109 \r
110                         if(optimal.PresentParameters.Windowed || ConversionMethods.GetColorBits(desktopMode.Format) >= 8)\r
111                                 optimal.AdapterFormat = desktopMode.Format;\r
112                         else\r
113                                 optimal.AdapterFormat = Format.X8R8G8B8;\r
114 \r
115                         if(settings.BackBufferWidth == 0 || settings.BackBufferHeight == 0)\r
116                         {\r
117                                 if(optimal.PresentParameters.Windowed)\r
118                                 {\r
119                                         optimal.PresentParameters.BackBufferWidth = 640;\r
120                                         optimal.PresentParameters.BackBufferHeight = 480;\r
121                                 }\r
122                                 else\r
123                                 {\r
124                                         optimal.PresentParameters.BackBufferWidth = desktopMode.Width;\r
125                                         optimal.PresentParameters.BackBufferHeight = desktopMode.Height;\r
126                                 }\r
127                         }\r
128                         else\r
129                         {\r
130                                 optimal.PresentParameters.BackBufferWidth = settings.BackBufferWidth;\r
131                                 optimal.PresentParameters.BackBufferHeight = settings.BackBufferHeight;\r
132                         }\r
133 \r
134                         if(settings.BackBufferFormat == Format.Unknown)\r
135                                 optimal.PresentParameters.BackBufferFormat = optimal.AdapterFormat;\r
136                         else\r
137                                 optimal.PresentParameters.BackBufferFormat = settings.BackBufferFormat;\r
138 \r
139                         if(settings.DepthStencilFormat == Format.Unknown)\r
140                         {\r
141                                 if(ConversionMethods.GetColorBits(optimal.PresentParameters.BackBufferFormat) >= 8)\r
142                                         optimal.PresentParameters.AutoDepthStencilFormat = Format.D32;\r
143                                 else\r
144                                         optimal.PresentParameters.AutoDepthStencilFormat = Format.D16;\r
145                         }\r
146                         else\r
147                                 optimal.PresentParameters.AutoDepthStencilFormat = settings.DepthStencilFormat;\r
148 \r
149                         if(!settings.EnableVSync)\r
150                                 optimal.PresentParameters.PresentationInterval = PresentInterval.Immediate;\r
151 \r
152                         return optimal;\r
153                 }\r
154 \r
155                 public static float RankSettingsCombo(SettingsCombo9 combo, Direct3D9Settings optimal, DisplayMode desktopMode)\r
156                 {\r
157                         float ranking = 0.0f;\r
158 \r
159                         if(combo.AdapterOrdinal == optimal.AdapterOrdinal)\r
160                                 ranking += 1000.0f;\r
161 \r
162                         if(combo.DeviceType == optimal.DeviceType)\r
163                                 ranking += 100.0f;\r
164 \r
165                         if(combo.DeviceType == DeviceType.Hardware)\r
166                                 ranking += 0.1f;\r
167 \r
168                         if(combo.Windowed == optimal.PresentParameters.Windowed)\r
169                                 ranking += 10.0f;\r
170 \r
171                         if(combo.AdapterFormat == optimal.AdapterFormat)\r
172                                 ranking += 1.0f;\r
173                         else\r
174                         {\r
175                                 int bitDepthDelta = Math.Abs(ConversionMethods.GetColorBits(combo.AdapterFormat) -\r
176                                         ConversionMethods.GetColorBits(optimal.AdapterFormat));\r
177                                 float scale = Math.Max(0.9f - bitDepthDelta * 0.2f, 0.0f);\r
178                                 ranking += scale;\r
179                         }\r
180 \r
181                         if(!combo.Windowed)\r
182                         {\r
183                                 bool match;\r
184                                 if(ConversionMethods.GetColorBits(desktopMode.Format) >= 8)\r
185                                         match = (combo.AdapterFormat == desktopMode.Format);\r
186                                 else\r
187                                         match = (combo.AdapterFormat == Format.X8R8G8B8);\r
188 \r
189                                 if(match)\r
190                                         ranking += 0.1f;\r
191                         }\r
192 \r
193                         if((optimal.CreationFlags & CreateFlags.HardwareVertexProcessing) != 0 &&\r
194                                 (optimal.CreationFlags & CreateFlags.MixedVertexProcessing) != 0)\r
195                         {\r
196                                 if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)\r
197                                         ranking += 1.0f;\r
198                         }\r
199 \r
200                         if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)\r
201                                 ranking += 0.1f;\r
202 \r
203                         foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)\r
204                         {\r
205                                 if(displayMode.Format == combo.AdapterFormat &&\r
206                                         displayMode.Width == optimal.PresentParameters.BackBufferWidth &&\r
207                                         displayMode.Height == optimal.PresentParameters.BackBufferHeight)\r
208                                 {\r
209                                         ranking += 1.0f;\r
210                                         break;\r
211                                 }\r
212                         }\r
213 \r
214                         if(combo.BackBufferFormat == optimal.PresentParameters.BackBufferFormat)\r
215                                 ranking += 1.0f;\r
216                         else\r
217                         {\r
218                                 int bitDepthDelta = Math.Abs(ConversionMethods.GetColorBits(combo.BackBufferFormat) -\r
219                                         ConversionMethods.GetColorBits(optimal.PresentParameters.BackBufferFormat));\r
220                                 float scale = Math.Max(0.9f - bitDepthDelta * 0.2f, 0.0f);\r
221                                 ranking += scale;\r
222                         }\r
223 \r
224                         if(combo.BackBufferFormat == combo.AdapterFormat)\r
225                                 ranking += 0.1f;\r
226 \r
227                         for(int i = 0; i < combo.MultisampleTypes.Count; i++)\r
228                         {\r
229                                 MultisampleType type = combo.MultisampleTypes[i];\r
230                                 int quality = combo.MultisampleQualities[i];\r
231 \r
232                                 if(type == optimal.PresentParameters.Multisample && quality == optimal.PresentParameters.MultisampleQuality)\r
233                                 {\r
234                                         ranking += 1.0f;\r
235                                         break;\r
236                                 }\r
237                         }\r
238 \r
239                         if(combo.DepthStencilFormats.Contains(optimal.PresentParameters.AutoDepthStencilFormat))\r
240                                 ranking += 1.0f;\r
241 \r
242                         foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)\r
243                         {\r
244                                 if(displayMode.Format == combo.AdapterFormat &&\r
245                                         displayMode.RefreshRate == optimal.PresentParameters.FullScreenRefreshRateInHertz)\r
246                                 {\r
247                                         ranking += 1.0f;\r
248                                         break;\r
249                                 }\r
250                         }\r
251 \r
252                         if(combo.PresentIntervals.Contains(optimal.PresentParameters.PresentationInterval))\r
253                                 ranking += 1.0f;\r
254 \r
255                         return ranking;\r
256                 }\r
257 \r
258                 public static Direct3D9Settings BuildValidSettings(SettingsCombo9 combo, Direct3D9Settings input)\r
259                 {\r
260                         Direct3D9Settings settings = new Direct3D9Settings();\r
261 \r
262                         settings.AdapterOrdinal = combo.AdapterOrdinal;\r
263                         settings.DeviceType = combo.DeviceType;\r
264                         settings.PresentParameters.Windowed = combo.Windowed;\r
265                         settings.AdapterFormat = combo.AdapterFormat;\r
266                         settings.PresentParameters.BackBufferFormat = combo.BackBufferFormat;\r
267                         settings.PresentParameters.SwapEffect = input.PresentParameters.SwapEffect;\r
268                         settings.PresentParameters.PresentFlags = input.PresentParameters.PresentFlags | PresentFlags.DiscardDepthStencil;\r
269 \r
270                         settings.CreationFlags = input.CreationFlags;\r
271                         if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) == 0 &&\r
272                                 ((settings.CreationFlags & CreateFlags.HardwareVertexProcessing) != 0 ||\r
273                                 (settings.CreationFlags & CreateFlags.MixedVertexProcessing) != 0))\r
274                         {\r
275                                 settings.CreationFlags &= ~CreateFlags.HardwareVertexProcessing;\r
276                                 settings.CreationFlags &= ~CreateFlags.MixedVertexProcessing;\r
277                                 settings.CreationFlags |= CreateFlags.SoftwareVertexProcessing;\r
278                         }\r
279 \r
280                         if((settings.CreationFlags & CreateFlags.HardwareVertexProcessing) == 0 &&\r
281                                 (settings.CreationFlags & CreateFlags.MixedVertexProcessing) == 0 &&\r
282                                 (settings.CreationFlags & CreateFlags.SoftwareVertexProcessing) == 0)\r
283                         {\r
284                                 if((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)\r
285                                         settings.CreationFlags |= CreateFlags.HardwareVertexProcessing;\r
286                                 else\r
287                                         settings.CreationFlags |= CreateFlags.SoftwareVertexProcessing;\r
288                         }\r
289 \r
290                         DisplayMode bestDisplayMode = FindValidResolution(combo, input);\r
291                         settings.PresentParameters.BackBufferWidth = bestDisplayMode.Width;\r
292                         settings.PresentParameters.BackBufferHeight = bestDisplayMode.Height;\r
293 \r
294                         settings.PresentParameters.BackBufferCount = input.PresentParameters.BackBufferCount;\r
295                         if(settings.PresentParameters.BackBufferCount > 3)\r
296                                 settings.PresentParameters.BackBufferCount = 3;\r
297                         if(settings.PresentParameters.BackBufferCount < 1)\r
298                                 settings.PresentParameters.BackBufferCount = 1;\r
299 \r
300                         if(input.PresentParameters.SwapEffect != SwapEffect.Discard)\r
301                         {\r
302                                 settings.PresentParameters.Multisample = MultisampleType.None;\r
303                                 settings.PresentParameters.MultisampleQuality = 0;\r
304                         }\r
305                         else\r
306                         {\r
307                                 MultisampleType bestType = MultisampleType.None;\r
308                                 int bestQuality = 0;\r
309 \r
310                                 for(int i = 0; i < combo.MultisampleTypes.Count; i++)\r
311                                 {\r
312                                         MultisampleType type = combo.MultisampleTypes[i];\r
313                                         int quality = combo.MultisampleQualities[0];\r
314 \r
315                                         if(Math.Abs(type - input.PresentParameters.Multisample) < Math.Abs(bestType -\r
316                                                 input.PresentParameters.Multisample))\r
317                                         {\r
318                                                 bestType = type;\r
319                                                 bestQuality = Math.Min(quality - 1, input.PresentParameters.MultisampleQuality);\r
320                                         }\r
321                                 }\r
322 \r
323                                 settings.PresentParameters.Multisample = bestType;\r
324                                 settings.PresentParameters.MultisampleQuality = bestQuality;\r
325                         }\r
326 \r
327                         List<int> rankings = new List<int>();\r
328                         int inputDepthBitDepth = ConversionMethods.GetDepthBits(input.PresentParameters.AutoDepthStencilFormat);\r
329                         int inputStencilBitDepth = ConversionMethods.GetStencilBits(input.PresentParameters.AutoDepthStencilFormat);\r
330 \r
331                         foreach(Format format in combo.DepthStencilFormats)\r
332                         {\r
333                                 int currentBitDepth = ConversionMethods.GetDepthBits(format);\r
334                                 int currentStencilDepth = ConversionMethods.GetStencilBits(format);\r
335 \r
336                                 int ranking = Math.Abs(currentBitDepth - inputDepthBitDepth);\r
337                                 ranking += Math.Abs(currentStencilDepth - inputStencilBitDepth);\r
338                                 rankings.Add(ranking);\r
339                         }\r
340 \r
341                         int bestRanking = int.MaxValue;\r
342                         foreach(int ranking in rankings)\r
343                         {\r
344                                 if(ranking < bestRanking)\r
345                                         bestRanking = ranking;\r
346                         }\r
347                         int bestIndex = rankings.IndexOf(bestRanking);\r
348 \r
349                         if(bestIndex >= 0)\r
350                         {\r
351                                 settings.PresentParameters.AutoDepthStencilFormat = combo.DepthStencilFormats[bestIndex];\r
352                                 settings.PresentParameters.EnableAutoDepthStencil = true;\r
353                         }\r
354                         else\r
355                         {\r
356                                 settings.PresentParameters.AutoDepthStencilFormat = Format.Unknown;\r
357                                 settings.PresentParameters.EnableAutoDepthStencil = false;\r
358                         }\r
359 \r
360                         if(combo.Windowed)\r
361                                 settings.PresentParameters.FullScreenRefreshRateInHertz = 0;\r
362                         else\r
363                         {\r
364                                 int match = input.PresentParameters.FullScreenRefreshRateInHertz;\r
365                                 bestDisplayMode.RefreshRate = 0;\r
366                                 if(match != 0)\r
367                                 {\r
368                                         bestRanking = 100000;\r
369                                         foreach(DisplayMode displayMode in combo.AdapterInfo.DisplayModes)\r
370                                         {\r
371                                                 if(displayMode.Format != combo.AdapterFormat ||\r
372                                                         displayMode.Width != bestDisplayMode.Width ||\r
373                                                         displayMode.Height != bestDisplayMode.Height)\r
374                                                         continue;\r
375 \r
376                                                 int ranking = Math.Abs(displayMode.RefreshRate - match);\r
377 \r
378                                                 if(ranking < bestRanking)\r
379                                                 {\r
380                                                         bestDisplayMode.RefreshRate = displayMode.RefreshRate;\r
381                                                         bestRanking = ranking;\r
382 \r
383                                                         if(bestRanking == 0)\r
384                                                                 break;\r
385                                                 }\r
386                                         }\r
387                                 }\r
388 \r
389                                 settings.PresentParameters.FullScreenRefreshRateInHertz = bestDisplayMode.RefreshRate;\r
390                         }\r
391 \r
392                         if(combo.PresentIntervals.Contains(input.PresentParameters.PresentationInterval))\r
393                                 settings.PresentParameters.PresentationInterval = input.PresentParameters.PresentationInterval;\r
394                         else\r
395                                 settings.PresentParameters.PresentationInterval = PresentInterval.Default;\r
396 \r
397                         return settings;\r
398                 }\r
399 \r
400                 static DisplayMode FindValidResolution(SettingsCombo9 combo, Direct3D9Settings input)\r
401                 {\r
402                         DisplayMode bestMode = new DisplayMode();\r
403 \r
404                         if(combo.Windowed)\r
405                         {\r
406                                 bestMode.Width = input.PresentParameters.BackBufferWidth;\r
407                                 bestMode.Height = input.PresentParameters.BackBufferHeight;\r
408                                 return bestMode;\r
409                         }\r
410 \r
411                         int bestRanking = 100000;\r
412                         int ranking;\r
413                         foreach(DisplayMode mode in combo.AdapterInfo.DisplayModes)\r
414                         {\r
415                                 if(mode.Format != combo.AdapterFormat)\r
416                                         continue;\r
417 \r
418                                 ranking = Math.Abs(mode.Width - input.PresentParameters.BackBufferWidth) +\r
419                                         Math.Abs(mode.Height - input.PresentParameters.BackBufferHeight);\r
420 \r
421                                 if(ranking < bestRanking)\r
422                                 {\r
423                                         bestMode = mode;\r
424                                         bestRanking = ranking;\r
425 \r
426                                         if(bestRanking == 0)\r
427                                                 break;\r
428                                 }\r
429                         }\r
430 \r
431                         if(bestMode.Width == 0)\r
432                         {\r
433                                 bestMode.Width = input.PresentParameters.BackBufferWidth;\r
434                                 bestMode.Height = input.PresentParameters.BackBufferHeight;\r
435                         }\r
436 \r
437                         return bestMode;\r
438                 }\r
439         }\r
440 }\r