OSDN Git Service

Merge branch 'feature/37178_プロジェクトとソリューションファイルの英語化' into develop
[dtxmania/dtxmania.git] / FDK / コード / 01.フレームワーク / Rendering / GraphicsDeviceManager.cs
1 /*
2 * Copyright (c) 2007-2009 SlimDX Group
3
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22 using System;
23 using System.ComponentModel;
24 using System.Drawing;
25 using System.Runtime.InteropServices;
26 using System.Text;
27 using System.Threading;
28 using System.Windows.Forms;
29 using SharpDX;
30 using SharpDX.Direct3D9;
31 using SharpDX.DXGI;
32 using System.Diagnostics;
33
34 using Rectangle = System.Drawing.Rectangle;
35
36 namespace SampleFramework
37 {
38     /// <summary>
39     /// Handles the configuration and management of the graphics device.
40     /// </summary>
41     public class GraphicsDeviceManager : IDisposable
42     {
43         Game game;
44         bool ignoreSizeChanges;
45         bool deviceLost;
46 //        bool doNotStoreBufferSize;
47 //        bool renderingOccluded;
48
49         int fullscreenWindowWidth;
50         int fullscreenWindowHeight;
51         int windowedWindowWidth;
52         int windowedWindowHeight;
53         WINDOWPLACEMENT windowedPlacement;
54         long windowedStyle;
55         bool savedTopmost;
56
57 #if TEST_Direct3D9Ex
58                 internal static Direct3DEx Direct3D9Object                      // yyagi
59 #else
60                 internal static Direct3D Direct3D9Object
61 #endif
62                 {
63             get;
64             private set;
65         }
66
67         public DeviceSettings CurrentSettings
68         {
69             get;
70             private set;
71         }
72         public bool IsWindowed
73         {
74             get { return CurrentSettings.Windowed; }
75         }
76         public int ScreenWidth
77         {
78             get { return CurrentSettings.BackBufferWidth; }
79         }
80         public int ScreenHeight
81         {
82             get { return CurrentSettings.BackBufferHeight; }
83         }
84         public Size ScreenSize
85         {
86             get { return new Size(CurrentSettings.BackBufferWidth, CurrentSettings.BackBufferHeight); }
87         }
88         public Direct3D9Manager Direct3D9
89         {
90             get;
91             private set;
92         }
93         public string DeviceStatistics
94         {
95             get;
96             private set;
97         }
98         public string DeviceInformation
99         {
100             get;
101             private set;
102         }
103
104                 public GraphicsDeviceManager( Game game )
105                 {
106                         if( game == null )
107                                 throw new ArgumentNullException( "game" );
108
109                         this.game = game;
110
111                         game.Window.ScreenChanged += Window_ScreenChanged;
112                         game.Window.UserResized += Window_UserResized;
113
114                         game.FrameStart += game_FrameStart;
115                         game.FrameEnd += game_FrameEnd;
116
117                         Direct3D9 = new Direct3D9Manager( this );
118                 }
119
120         public void Dispose()
121         {
122             Dispose(true);
123             GC.SuppressFinalize(this);
124         }
125
126                 public void ChangeDevice( DeviceSettings settings, DeviceSettings minimumSettings )
127                 {
128                         if( settings == null )
129                                 throw new ArgumentNullException( "settings" );
130
131                         Enumeration9.MinimumSettings = minimumSettings;
132
133                         DeviceSettings validSettings = DeviceSettings.FindValidSettings( settings );
134
135                         var pp = validSettings.Direct3D9.PresentParameters;
136                         pp.DeviceWindowHandle = game.Window.Handle;
137                         validSettings.Direct3D9.PresentParameters = pp;
138
139                         CreateDevice( validSettings );
140                 }
141         public void ChangeDevice(bool windowed, int desiredWidth, int desiredHeight)
142         {
143             DeviceSettings desiredSettings = new DeviceSettings();
144             desiredSettings.Windowed = windowed;
145             desiredSettings.BackBufferWidth = desiredWidth;
146             desiredSettings.BackBufferHeight = desiredHeight;
147
148             ChangeDevice(desiredSettings, null);
149         }
150         public void ChangeDevice(DeviceSettings settings)
151         {
152             ChangeDevice(settings, null);
153         }
154
155         public void ToggleFullScreen()
156         {
157             if (!EnsureDevice())
158                 throw new InvalidOperationException("No valid device.");
159
160             DeviceSettings newSettings = CurrentSettings.Clone();
161
162             newSettings.Windowed = !newSettings.Windowed;
163
164             int width = newSettings.Windowed ? windowedWindowWidth : fullscreenWindowWidth;
165             int height = newSettings.Windowed ? windowedWindowHeight : fullscreenWindowHeight;
166
167             newSettings.BackBufferWidth = width;
168             newSettings.BackBufferHeight = height;
169
170             ChangeDevice(newSettings);
171         }
172         public bool EnsureDevice()
173         {
174             if (Direct3D9.Device != null && !deviceLost)
175                 return true;
176
177             return false;
178         }
179
180                 protected virtual void Dispose( bool disposing )
181                 {
182                         if( this.bDisposed )
183                                 return;
184                         this.bDisposed = true;
185
186                         if( disposing )
187                                 ReleaseDevice();
188
189                 }
190                 private bool bDisposed = false;
191
192         void CreateDevice(DeviceSettings settings)
193         {
194             DeviceSettings oldSettings = CurrentSettings;
195             CurrentSettings = settings;
196
197             ignoreSizeChanges = true;
198
199             bool keepCurrentWindowSize = false;
200             if (settings.BackBufferWidth == 0 && settings.BackBufferHeight == 0)
201                 keepCurrentWindowSize = true;
202
203             // handle the window state in Direct3D9 (it will be handled for us in DXGI)
204                 // check if we are going to windowed or fullscreen mode
205                         if( settings.Windowed )
206                         {
207                                 if( oldSettings != null && !oldSettings.Windowed )
208                                         NativeMethods.SetWindowLong( game.Window.Handle, WindowConstants.GWL_STYLE, (uint) windowedStyle );
209                         }
210                         else
211                         {
212                                 if( oldSettings == null || oldSettings.Windowed )
213                                 {
214                                         savedTopmost = game.Window.TopMost;
215                                         long style = NativeMethods.GetWindowLong( game.Window.Handle, WindowConstants.GWL_STYLE );
216                                         style &= ~WindowConstants.WS_MAXIMIZE & ~WindowConstants.WS_MINIMIZE;
217                                         windowedStyle = style;
218
219                                         windowedPlacement = new WINDOWPLACEMENT();
220                                         windowedPlacement.length = WINDOWPLACEMENT.Length;
221                                         NativeMethods.GetWindowPlacement( game.Window.Handle, ref windowedPlacement );
222                                 }
223
224                                 // hide the window until we are done messing with it
225                                 game.Window.Hide();
226                                 NativeMethods.SetWindowLong( game.Window.Handle, WindowConstants.GWL_STYLE, (uint) ( WindowConstants.WS_POPUP | WindowConstants.WS_SYSMENU ) );
227
228                                 WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
229                                 placement.length = WINDOWPLACEMENT.Length;
230                                 NativeMethods.GetWindowPlacement( game.Window.Handle, ref placement );
231
232                                 // check if we are in the middle of a restore
233                                 if( ( placement.flags & WindowConstants.WPF_RESTORETOMAXIMIZED ) != 0 )
234                                 {
235                                         // update the flags to avoid sizing issues
236                                         placement.flags &= ~WindowConstants.WPF_RESTORETOMAXIMIZED;
237                                         placement.showCmd = WindowConstants.SW_RESTORE;
238                                         NativeMethods.SetWindowPlacement( game.Window.Handle, ref placement );
239                                 }
240                         }
241
242             if (settings.Windowed)
243             {
244                 if (oldSettings != null && !oldSettings.Windowed)
245                 {
246                     fullscreenWindowWidth = oldSettings.BackBufferWidth;
247                     fullscreenWindowHeight = oldSettings.BackBufferHeight;
248                 }
249             }
250             else
251             {
252                 if (oldSettings != null && oldSettings.Windowed)
253                 {
254                     windowedWindowWidth = oldSettings.BackBufferWidth;
255                     windowedWindowHeight = oldSettings.BackBufferHeight;
256                 }
257             }
258
259             // check if the device can be reset, or if we need to completely recreate it
260             Result result = SharpDX.Direct3D9.ResultCode.Success;
261             bool canReset = CanDeviceBeReset(oldSettings, settings);
262             if (canReset)
263                 result = ResetDevice();
264
265             if (result == SharpDX.Direct3D9.ResultCode.DeviceLost)
266                 deviceLost = true;
267             else if (!canReset || result.Failure)
268             {
269                 if (oldSettings != null)
270                     ReleaseDevice();
271
272                 InitializeDevice();
273             }
274
275             UpdateDeviceInformation();
276
277             // check if we changed from fullscreen to windowed mode
278             if (oldSettings != null && !oldSettings.Windowed && settings.Windowed)
279             {
280                 NativeMethods.SetWindowPlacement(game.Window.Handle, ref windowedPlacement);
281                 game.Window.TopMost = savedTopmost;
282             }
283
284             // check if we need to resize
285             if (settings.Windowed && !keepCurrentWindowSize)
286             {
287                 int width;
288                 int height;
289                 if (NativeMethods.IsIconic(game.Window.Handle))
290                 {
291                     WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
292                     placement.length = WINDOWPLACEMENT.Length;
293                     NativeMethods.GetWindowPlacement(game.Window.Handle, ref placement);
294
295                     // check if we are being restored
296                     if ((placement.flags & WindowConstants.WPF_RESTORETOMAXIMIZED) != 0 && placement.showCmd == WindowConstants.SW_SHOWMINIMIZED)
297                     {
298                         NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_RESTORE);
299
300                         Rectangle rect = NativeMethods.GetClientRectangle(game.Window.Handle);
301
302                         width = rect.Width;
303                         height = rect.Height;
304                         NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_MINIMIZE);
305                     }
306                     else
307                     {
308                         NativeRectangle frame = new NativeRectangle();
309                         NativeMethods.AdjustWindowRect(ref frame, (uint)windowedStyle, false);
310                         int frameWidth = frame.right - frame.left;
311                         int frameHeight = frame.bottom - frame.top;
312
313                         width = placement.rcNormalPosition.right - placement.rcNormalPosition.left - frameWidth;
314                         height = placement.rcNormalPosition.bottom - placement.rcNormalPosition.top - frameHeight;
315                     }
316                 }
317                 else
318                 {
319                     Rectangle rect = NativeMethods.GetClientRectangle(game.Window.Handle);
320                     width = rect.Width;
321                     height = rect.Height;
322                 }
323
324                 // check if we have a different desired size
325                 if (width != settings.BackBufferWidth ||
326                     height != settings.BackBufferHeight)
327                 {
328                     if (NativeMethods.IsIconic(game.Window.Handle))
329                         NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_RESTORE);
330                     if (NativeMethods.IsZoomed(game.Window.Handle))
331                         NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_RESTORE);
332
333                     NativeRectangle rect = new NativeRectangle();
334                     rect.right = settings.BackBufferWidth;
335                     rect.bottom = settings.BackBufferHeight;
336                     NativeMethods.AdjustWindowRect(ref rect,
337                         NativeMethods.GetWindowLong(game.Window.Handle, WindowConstants.GWL_STYLE), false);
338
339                     NativeMethods.SetWindowPos(game.Window.Handle, IntPtr.Zero, 0, 0, rect.right - rect.left,
340                         rect.bottom - rect.top, WindowConstants.SWP_NOZORDER | WindowConstants.SWP_NOMOVE);
341
342                     Rectangle r = NativeMethods.GetClientRectangle(game.Window.Handle);
343                     int clientWidth = r.Width;
344                     int clientHeight = r.Height;
345
346                     // check if the size was modified by Windows
347                     if (clientWidth != settings.BackBufferWidth ||
348                         clientHeight != settings.BackBufferHeight)
349                     {
350                         DeviceSettings newSettings = CurrentSettings.Clone();
351                         newSettings.BackBufferWidth = 0;
352                         newSettings.BackBufferHeight = 0;
353                         if (newSettings.Direct3D9 != null)
354                         {
355                                                         var pp = newSettings.Direct3D9.PresentParameters;
356                                                         pp.BackBufferWidth = GameWindowSize.Width;      // #23510 2010.10.31 add yyagi: to avoid setting BackBufferSize=ClientSize
357                                                         pp.BackBufferHeight = GameWindowSize.Height;   // #23510 2010.10.31 add yyagi: to avoid setting BackBufferSize=ClientSize
358                                                         newSettings.Direct3D9.PresentParameters = pp;
359                         }
360
361                         CreateDevice(newSettings);
362                     }
363                 }
364             }
365
366             // if the window is still hidden, make sure it is shown
367             if (!game.Window.Visible)
368                 NativeMethods.ShowWindow(game.Window.Handle, WindowConstants.SW_SHOW);
369
370             // set the execution state of the thread
371             if (!IsWindowed)
372                 NativeMethods.SetThreadExecutionState(WindowConstants.ES_DISPLAY_REQUIRED | WindowConstants.ES_CONTINUOUS);
373             else
374                 NativeMethods.SetThreadExecutionState(WindowConstants.ES_CONTINUOUS);
375
376             ignoreSizeChanges = false;
377         }
378
379                 void Window_UserResized( object sender, EventArgs e )
380                 {
381                         if( ignoreSizeChanges || !EnsureDevice() || ( !IsWindowed ) )
382                                 return;
383
384                         DeviceSettings newSettings = CurrentSettings.Clone();
385
386                         Rectangle rect = NativeMethods.GetClientRectangle( game.Window.Handle );
387                         if( rect.Width != newSettings.BackBufferWidth || rect.Height != newSettings.BackBufferHeight )
388                         {
389                                 newSettings.BackBufferWidth = 0;
390                                 newSettings.BackBufferHeight = 0;
391                                 var pp = newSettings.Direct3D9.PresentParameters;
392                                 pp.BackBufferWidth = GameWindowSize.Width;              // #23510 2010.10.31 add yyagi: to avoid setting BackBufferSize=ClientSize
393                                 pp.BackBufferHeight = GameWindowSize.Height;   // 
394                                 newSettings.Direct3D9.PresentParameters = pp;
395                                 CreateDevice( newSettings );
396                         }
397                 }
398                 void Window_ScreenChanged( object sender, EventArgs e )
399                 {
400                         if( !EnsureDevice() || !CurrentSettings.Windowed || ignoreSizeChanges )
401                                 return;
402
403                         IntPtr windowMonitor = NativeMethods.MonitorFromWindow( game.Window.Handle, WindowConstants.MONITOR_DEFAULTTOPRIMARY );
404
405                         DeviceSettings newSettings = CurrentSettings.Clone();
406                         int adapterOrdinal = GetAdapterOrdinal( windowMonitor );
407                         if( adapterOrdinal == -1 )
408                                 return;
409                         newSettings.Direct3D9.AdapterOrdinal = adapterOrdinal;
410
411                         newSettings.BackBufferWidth = 0;                                                                // #23510 2010.11.1 add yyagi to avoid to reset to 640x480 for the first time in XP.
412                         newSettings.BackBufferHeight = 0;                               //
413                         var pp = newSettings.Direct3D9.PresentParameters;
414                         pp.BackBufferWidth = GameWindowSize.Width;              //
415                         pp.BackBufferHeight = GameWindowSize.Height;   //
416                         newSettings.Direct3D9.PresentParameters = pp;
417
418                         CreateDevice( newSettings);
419                 }
420
421                 void game_FrameEnd( object sender, EventArgs e )
422                 {
423                         Result result = SharpDX.Direct3D9.ResultCode.Success;
424
425                         try
426                         {
427                                 //result = Direct3D9.Device.TestCooperativeLevel();
428                                 Direct3D9.Device.Present();
429                         }
430                         catch                   // #23842 2011.1.6 yyagi: catch D3D9Exception to avoid unexpected termination by changing VSyncWait in fullscreen.
431                         {
432                                 deviceLost = true;
433                         }
434
435                         if( result == SharpDX.Direct3D9.ResultCode.DeviceLost )
436                                 deviceLost = true;
437                 }
438         void game_FrameStart(object sender, CancelEventArgs e)
439         {
440             if (Direct3D9.Device == null )
441             {
442                 e.Cancel = true;
443                 return;
444             }
445
446                         //if (!game.IsActive || deviceLost)             // #23568 2010.11.3 yyagi: separate conditions to support valiable sleep value when !IsActive.
447                         if( deviceLost )
448                                 Thread.Sleep( 50 );
449                         else if( !game.IsActive && !this.CurrentSettings.EnableVSync )  // #23568 2010.11.4 yyagi: Don't add sleep() while VSync is enabled.
450                                 Thread.Sleep( this.game.InactiveSleepTime.Milliseconds );
451
452             if (deviceLost)
453             {
454                 Result result = Direct3D9.Device.TestCooperativeLevel();
455                 if (result == SharpDX.Direct3D9.ResultCode.DeviceLost)
456                 {
457                     e.Cancel = true;
458                     return;
459                 }
460
461                 // if we are windowed, check the adapter format to see if the user
462                 // changed the desktop format, causing a lost device
463                 if (IsWindowed)
464                 {
465                     DisplayMode displayMode = GraphicsDeviceManager.Direct3D9Object.GetAdapterDisplayMode(CurrentSettings.Direct3D9.AdapterOrdinal);
466                     if (CurrentSettings.Direct3D9.AdapterFormat != displayMode.Format)
467                     {
468                         DeviceSettings newSettings = CurrentSettings.Clone();
469                         ChangeDevice(newSettings);
470                         e.Cancel = true;
471                         return;
472                     }
473                 }
474
475                 result = ResetDevice();
476                 if (result.Failure)
477                 {
478                     e.Cancel = true;
479                     return;
480                 }
481             }
482
483             deviceLost = false;
484         }
485
486                 bool CanDeviceBeReset( DeviceSettings oldSettings, DeviceSettings newSettings )
487                 {
488                         if( oldSettings == null )
489                                 return false;
490
491                         return Direct3D9.Device != null &&
492                                 oldSettings.Direct3D9.AdapterOrdinal == newSettings.Direct3D9.AdapterOrdinal &&
493                                 oldSettings.Direct3D9.DeviceType == newSettings.Direct3D9.DeviceType &&
494                                 oldSettings.Direct3D9.CreationFlags == newSettings.Direct3D9.CreationFlags;
495                 }
496
497         void InitializeDevice()
498         {
499                         try
500                         {
501                                 EnsureD3D9();
502
503 #if TEST_Direct3D9Ex
504                                 // 2011.4.26 yyagi
505                                 // Direct3D9.DeviceExを呼ぶ際(IDirect3D9Ex::CreateDeviceExを呼ぶ際)、
506                                 // フルスクリーンモードで初期化する場合はDisplayModeEx(D3DDISPLAYMODEEX *pFullscreenDisplayMode)に
507                                 // 適切な値を設定する必要あり。
508                                 // 一方、ウインドウモードで初期化する場合は、D3DDISPLAYMODEEXをNULLにする必要があるが、
509                                 // DisplayModeExがNULL不可と定義されているため、DeviceExのoverloadの中でDisplayModeExを引数に取らないものを
510                                 // 使う。(DeviceEx側でD3DDISPLAYMODEEXをNULLにしてくれる)
511                                 // 結局、DeviceExの呼び出しの際に、フルスクリーンかどうかで場合分けが必要となる。
512                                 if ( CurrentSettings.Direct3D9.PresentParameters.Windowed == false )
513                                 {
514                                         DisplayModeEx fullScreenDisplayMode = new DisplayModeEx();
515                                         fullScreenDisplayMode.Width = CurrentSettings.Direct3D9.PresentParameters.BackBufferWidth;
516                                         fullScreenDisplayMode.Height = CurrentSettings.Direct3D9.PresentParameters.BackBufferHeight;
517                                         fullScreenDisplayMode.RefreshRate = CurrentSettings.Direct3D9.PresentParameters.FullScreenRefreshRateInHertz;
518                                         fullScreenDisplayMode.Format = CurrentSettings.Direct3D9.PresentParameters.BackBufferFormat;
519
520                                         Direct3D9.Device = new SlimDX.Direct3D9.DeviceEx( Direct3D9Object, CurrentSettings.Direct3D9.AdapterOrdinal,
521                                                 CurrentSettings.Direct3D9.DeviceType, game.Window.Handle,
522                                                 CurrentSettings.Direct3D9.CreationFlags, CurrentSettings.Direct3D9.PresentParameters, fullScreenDisplayMode );
523                                 }
524                                 else
525                                 {
526                                         Direct3D9.Device = new SlimDX.Direct3D9.DeviceEx( Direct3D9Object, CurrentSettings.Direct3D9.AdapterOrdinal,
527                                                 CurrentSettings.Direct3D9.DeviceType, game.Window.Handle,
528                                                 CurrentSettings.Direct3D9.CreationFlags, CurrentSettings.Direct3D9.PresentParameters );
529                                 }
530                                 Direct3D9.Device.MaximumFrameLatency = 1;
531 #else
532                                 Direct3D9.Device = new SharpDX.Direct3D9.Device(
533                                         Direct3D9Object,
534                                         CurrentSettings.Direct3D9.AdapterOrdinal,
535                                         CurrentSettings.Direct3D9.DeviceType,
536                                         game.Window.Handle,
537                                         CurrentSettings.Direct3D9.CreationFlags,
538                                         CurrentSettings.Direct3D9.PresentParameters );
539 #endif
540                                 if ( Result.GetResultFromWin32Error( Marshal.GetLastWin32Error() ) == SharpDX.Direct3D9.ResultCode.DeviceLost )
541                                 {
542                                         deviceLost = true;
543                                         return;
544                                 }
545 #if TEST_Direct3D9Ex
546                                 Direct3D9.Device.MaximumFrameLatency = 1;                       // yyagi
547 #endif
548                         }
549                         catch( Exception e )
550                         {
551                                 throw new DeviceCreationException( "Could not create graphics device.", e );
552                         }
553
554             PropogateSettings();
555
556             UpdateDeviceStats();
557
558             game.Initialize();
559             game.LoadContent();
560         }
561
562                 Result ResetDevice()
563                 {
564                         game.UnloadContent();
565
566                         Direct3D9.Device.Reset( CurrentSettings.Direct3D9.PresentParameters );
567
568                         var result = Result.GetResultFromWin32Error( Marshal.GetLastWin32Error() );
569
570                         if( result == SharpDX.Direct3D9.ResultCode.DeviceLost )
571                                 return result;
572
573                         PropogateSettings();
574                         UpdateDeviceStats();
575                         game.LoadContent();
576
577                         return result;
578                 }
579
580                 void ReleaseDevice()
581         {
582             ReleaseDevice9();
583         }
584
585                 void ReleaseDevice9()
586         {
587             if (Direct3D9.Device == null)
588                 return;
589
590             if (game != null)
591             {
592                 game.UnloadContent();
593                 game.Dispose(true);
594             }
595
596                         try
597                         {
598                                 Direct3D9.Device.Dispose();
599                         }
600                         catch( ObjectDisposedException )
601                         {
602                                 // 時々発生するのでキャッチしておく。
603                         }
604             Direct3D9Object.Dispose();
605
606             Direct3D9Object = null;
607             Direct3D9.Device = null;
608         }
609                 void PropogateSettings()
610                 {
611                         CurrentSettings.BackBufferCount = CurrentSettings.Direct3D9.PresentParameters.BackBufferCount;
612                         CurrentSettings.BackBufferWidth = CurrentSettings.Direct3D9.PresentParameters.BackBufferWidth;
613                         CurrentSettings.BackBufferHeight = CurrentSettings.Direct3D9.PresentParameters.BackBufferHeight;
614                         CurrentSettings.BackBufferFormat = CurrentSettings.Direct3D9.PresentParameters.BackBufferFormat;
615                         CurrentSettings.DepthStencilFormat = CurrentSettings.Direct3D9.PresentParameters.AutoDepthStencilFormat;
616                         CurrentSettings.DeviceType = CurrentSettings.Direct3D9.DeviceType;
617                         CurrentSettings.MultisampleQuality = CurrentSettings.Direct3D9.PresentParameters.MultiSampleQuality;
618                         CurrentSettings.MultisampleType = CurrentSettings.Direct3D9.PresentParameters.MultiSampleType;
619                         CurrentSettings.RefreshRate = CurrentSettings.Direct3D9.PresentParameters.FullScreenRefreshRateInHz;
620                         CurrentSettings.Windowed = CurrentSettings.Direct3D9.PresentParameters.Windowed;
621                 }
622
623                 void UpdateDeviceInformation()
624                 {
625                         StringBuilder builder = new StringBuilder();
626
627                         if( CurrentSettings.Direct3D9.DeviceType == DeviceType.Hardware )
628                                 builder.Append( "HAL" );
629                         else if( CurrentSettings.Direct3D9.DeviceType == DeviceType.Reference )
630                                 builder.Append( "REF" );
631                         else if( CurrentSettings.Direct3D9.DeviceType == DeviceType.Software )
632                                 builder.Append( "SW" );
633
634                         if( ( CurrentSettings.Direct3D9.CreationFlags & CreateFlags.HardwareVertexProcessing ) != 0 )
635                                 if( CurrentSettings.Direct3D9.DeviceType == DeviceType.Hardware )
636                                         builder.Append( " (hw vp)" );
637                                 else
638                                         builder.Append( " (simulated hw vp)" );
639                         else if( ( CurrentSettings.Direct3D9.CreationFlags & CreateFlags.MixedVertexProcessing ) != 0 )
640                                 if( CurrentSettings.Direct3D9.DeviceType == DeviceType.Hardware )
641                                         builder.Append( " (mixed vp)" );
642                                 else
643                                         builder.Append( " (simulated mixed vp)" );
644                         else
645                                 builder.Append( " (sw vp)" );
646
647                         if( CurrentSettings.Direct3D9.DeviceType == DeviceType.Hardware )
648                         {
649                                 // loop through each adapter until we find the right one
650                                 foreach( AdapterInfo9 adapterInfo in Enumeration9.Adapters )
651                                 {
652                                         if( adapterInfo.AdapterOrdinal == CurrentSettings.Direct3D9.AdapterOrdinal )
653                                         {
654                                                 builder.AppendFormat( ": {0}", adapterInfo.Description );
655                                                 break;
656                                         }
657                                 }
658                         }
659
660                         DeviceInformation = builder.ToString();
661                 }
662
663                 void UpdateDeviceStats()
664                 {
665                         StringBuilder builder = new StringBuilder();
666
667                         builder.Append( "D3D9 Vsync " );
668
669                         if( CurrentSettings.Direct3D9.PresentParameters.PresentationInterval == PresentInterval.Immediate )
670                                 builder.Append( "off" );
671                         else
672                                 builder.Append( "on" );
673
674                         builder.AppendFormat( " ({0}x{1}), ", CurrentSettings.Direct3D9.PresentParameters.BackBufferWidth, CurrentSettings.Direct3D9.PresentParameters.BackBufferHeight );
675
676                         if( CurrentSettings.Direct3D9.AdapterFormat == CurrentSettings.Direct3D9.PresentParameters.BackBufferFormat )
677                                 builder.Append( Enum.GetName( typeof( SharpDX.Direct3D9.Format ), CurrentSettings.Direct3D9.AdapterFormat ) );
678                         else
679                                 builder.AppendFormat( "backbuf {0}, adapter {1}",
680                                         Enum.GetName( typeof( SharpDX.Direct3D9.Format ), CurrentSettings.Direct3D9.AdapterFormat ),
681                                         Enum.GetName( typeof( SharpDX.Direct3D9.Format ), CurrentSettings.Direct3D9.PresentParameters.BackBufferFormat ) );
682
683                         builder.AppendFormat( " ({0})", Enum.GetName( typeof( SharpDX.Direct3D9.Format ), CurrentSettings.Direct3D9.PresentParameters.AutoDepthStencilFormat ) );
684
685                         if( CurrentSettings.Direct3D9.PresentParameters.MultiSampleType == MultisampleType.NonMaskable )
686                                 builder.Append( " (Nonmaskable Multisample)" );
687                         else if( CurrentSettings.Direct3D9.PresentParameters.MultiSampleType != MultisampleType.None )
688                                 builder.AppendFormat( " ({0}x Multisample)", (int) CurrentSettings.Direct3D9.PresentParameters.MultiSampleQuality );
689
690                         DeviceStatistics = builder.ToString();
691                 }
692
693                 int GetAdapterOrdinal( IntPtr screen )
694                 {
695                         AdapterInfo9 adapter = null;
696                         foreach( AdapterInfo9 a in Enumeration9.Adapters )
697                         {
698                                 if( Direct3D9Object.GetAdapterMonitor( a.AdapterOrdinal ) == screen )
699                                 {
700                                         adapter = a;
701                                         break;
702                                 }
703                         }
704
705                         if( adapter != null )
706                                 return adapter.AdapterOrdinal;
707
708                         return -1;
709                 }
710
711         internal static void EnsureD3D9()
712         {
713                         if ( Direct3D9Object == null )
714 #if TEST_Direct3D9Ex
715                                 Direct3D9Object = new Direct3DEx();             // yyagi
716 #else
717                                 Direct3D9Object = new Direct3D();
718 #endif
719         }
720     }
721 }