OSDN Git Service

#xxxxx DTXViewerのプロジェクトを追加。
[dtxmania/dtxmania.git] / DTXViewerプロジェクト / @FDK10プロジェクト / CD3DDisplay.cpp
1 #include "stdafx.h"
2 #include "CD3DDisplay.h"
3 #include "FDKError.h"
4
5 namespace FDK {
6         namespace AppBase {
7
8 // Direct3D \83f\83o\83C\83X\97ñ\8b\93\97p\82Ì\83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\81B
9 static HRESULT WINAPI DeviceEnumCallback( TCHAR* strDesc, TCHAR* strName, D3DDEVICEDESC7* pDesc, VOID* pContext )
10 {
11         CD3DDisplay* app                = (CD3DDisplay*) pContext;
12         D3DAdapterInfo* adapter = app->pAdapter;
13         D3DDeviceInfo* device   = adapter->pDevice;
14
15         // \83f\83o\83C\83X\8fî\95ñ\82ð\83R\83s\81[\82·\82é\81B
16         ZeroMemory( device, sizeof(D3DDeviceInfo) );
17         device->guidDevice                      = pDesc->deviceGUID;
18         device->pDeviceGUID                     = &device->guidDevice;
19         device->bHardware                       = (pDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) ? true : false;
20         memcpy( &device->ddDeviceDesc, pDesc, sizeof(D3DDEVICEDESC7) );
21         if( adapter->pAdapterGUID )
22                 lstrcpyn( device->strDesc, adapter->strDesc, 39 );                                                      // strDesc[]
23         else
24                 lstrcpyn( device->strDesc, strName, 39 );
25         if( device->bHardware )                                                                                                                 // type
26                 device->type = ( device->guidDevice == IID_IDirect3DTnLHalDevice ) ? D3DAPPDEV_HALTnL : D3DAPPDEV_HAL;
27         else
28                 device->type = ( device->guidDevice == IID_IDirect3DRefDevice ) ? D3DAPPDEV_REF : D3DAPPDEV_HEL;
29         device->bStereoCompatible = false;                                      // bStereoCompatible\81i\8cã\82Å\8dÄ\83`\83F\83b\83N\82·\82é\81j
30         device->dwNumModes = 0;                                                         // dwNumModes
31         device->bWindowed = adapter->bDesktopCompatible;        // bWindowed\81i\8f\89\8aú\82Å\83E\83B\83\93\83h\83E\82É\82È\82ê\82é\82È\82çtrue\81j
32         device->pMode = &(device->modes[0]);                            // pMode\81i\8cã\82Å640x480\82Ì\83\82\81[\83h\82ð\90Ý\92è\82·\82é\81j
33
34         // \8fd\95¡\89ñ\94ð\81G\83Z\83J\83\93\83_\83\8a\83A\83_\83v\83^\88È\8d~\82É\82Â\82¢\82Ä\82Í\81AHAL/HALTnL \82Ì\82Ý\83\8a\83X\83g\83A\83b\83v\82·\82é\81B
35     if( adapter->pAdapterGUID != NULL && ! device->bHardware )
36                 return D3DENUMRET_OK;
37         
38     // \83A\83v\83\8a\82É\82±\82Ì\83f\83o\83C\83X\82Ì\8b\96\89Â\81^\95s\8b\96\89Â\82ð\94»\92f\82³\82¹\82é\81B
39     if( FAILED( app->ConfirmDevice( &adapter->ddHALCaps, &device->ddDeviceDesc ) ) )
40                 return D3DENUMRET_OK;
41         
42         // DirectDraw \82Ì\91S\83\82\81[\83h\83\8a\83X\83g\81iAdapter\82Ìmodes[]\81j\82Ì\82¤\82¿\81ADirect3D \83f\83o\83C\83X\82Æ\8cÝ\8a·\90«\82Ì\82 \82é\83\82\81[\83h\82ð\94²\90\88\82µ\82½\83\8a\83X\83g\82ð\8dì\90¬\82·\82é\81B
43     for( DWORD i=0; i<adapter->dwNumModes; i++ )
44     {
45         DDSURFACEDESC2 ddsdDDMode       = adapter->modes[i];
46         DWORD dwDDDepth                         = ddsdDDMode.ddpfPixelFormat.dwRGBBitCount;                     // \83A\83_\83v\83^\82Ì\90[\93x
47         DWORD dwD3DDepths                       = device->ddDeviceDesc.dwDeviceRenderBitDepth;          // D3D\83f\83o\83C\83X\82Ì\90[\93x
48
49                 // Direct3D \83f\83o\83C\83X\82Ì\83\82\81[\83h\82Æ\8cÝ\8a·\90«\82Ì\82 \82é\83\82\81[\83h\82¾\82¯\82ð\94F\82ß\82é\81B
50         if( ( ( dwDDDepth == 32 ) && ( dwD3DDepths & DDBD_32 ) ) ||
51             ( ( dwDDDepth == 24 ) && ( dwD3DDepths & DDBD_24 ) ) ||
52             ( ( dwDDDepth == 16 ) && ( dwD3DDepths & DDBD_16 ) ) )
53         {
54                         // \83\82\81[\83h\82ð\83f\83o\83C\83X\83\82\81[\83h\82Ì\83\8a\83X\83g\82É\83R\83s\81[\82·\82é\81B
55             device->modes[device->dwNumModes++] = ddsdDDMode;
56
57                         // \83X\83e\83\8c\83I\83t\83\8a\83b\83s\83\93\83O\83`\83F\81[\83\93\82Å\82 \82é\82©\82ð\8bL\98^\82·\82é\81B\81i\83\82\81[\83h\92\86\82P\82Â\82Å\82à\82»\82¤\82È\82ç trur \82É\82È\82é\81j
58             if( ddsdDDMode.ddsCaps.dwCaps2 & DDSCAPS2_STEREOSURFACELEFT )
59                 device->bStereoCompatible = true;
60         }
61     }
62
63         // \83f\83o\83C\83X\82ª\83\82\81[\83h\82ð\82P\82Â\82à\83T\83|\81[\83g\82µ\82È\82¢\82È\82ç\82±\82±\82Å\8eß\95ú\81B
64     if( device->dwNumModes == 0 )
65         return D3DENUMRET_OK;
66
67         // \83f\83t\83H\83\8b\83g\82Ì\91S\89æ\96Ê\83\82\81[\83h\82Æ\82µ\82Ä 640x480x16 \83\82\81[\83h\82ð\8c\9f\8dõ\82·\82é\81B
68         for( DWORD i=0; i < device->dwNumModes; i++ )
69         {
70                 if( ( device->modes[i].dwWidth == 640 ) &&
71                         ( device->modes[i].dwHeight == 480 ) &&
72                         ( device->modes[i].ddpfPixelFormat.dwRGBBitCount == 16 ) )
73                 {
74                         device->pMode = &( device->modes[i] );
75                         break;
76                 }
77         }
78
79         // \83f\83o\83C\83X\82ð\94F\82ß\81A\96ß\82é\81B
80     if( adapter->dwNumDevices < 4 )
81         {
82                 adapter->dwNumDevices++;
83                 adapter->pDevice++;
84         }
85
86     return D3DENUMRET_OK;
87 }
88
89 // DirectDraw \82Ì\83t\83\8b\83X\83N\83\8a\81[\83\93\83\82\81[\83h\97ñ\8b\93\97p\82Ì\83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\81B
90 static HRESULT WINAPI ModeEnumCallback( DDSURFACEDESC2* pddsd, VOID* pContext )
91 {
92         D3DAdapterInfo* adapter = (D3DAdapterInfo*) pContext;
93         adapter->modes[ adapter->dwNumModes ] = (*pddsd);
94         if( adapter->dwNumModes < 149 ) adapter->dwNumModes++;
95     return DDENUMRET_OK;
96 }
97
98 // \83f\83B\83X\83v\83\8c\83C\83\82\81[\83h\8f\87\82É\83\\81[\83g\82·\82é\82½\82ß\82Ì\83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\81B
99 static int SortModesCallback( const VOID* arg1, const VOID* arg2 )
100 {
101     DDSURFACEDESC2* p1 = (DDSURFACEDESC2*)arg1;
102     DDSURFACEDESC2* p2 = (DDSURFACEDESC2*)arg2;
103
104     if( p1->dwWidth < p2->dwWidth )
105         return -1;
106     if( p1->dwWidth > p2->dwWidth )
107         return +1;
108
109     if( p1->dwHeight < p2->dwHeight )
110         return -1;
111     if( p1->dwHeight > p2->dwHeight )
112         return +1;
113
114     if( p1->ddpfPixelFormat.dwRGBBitCount < p2->ddpfPixelFormat.dwRGBBitCount )
115         return -1;
116     if( p1->ddpfPixelFormat.dwRGBBitCount > p2->ddpfPixelFormat.dwRGBBitCount )
117         return +1;
118
119     return 0;
120 }
121
122 // \83A\83_\83v\83^\97ñ\8b\93\97p\82Ì\83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\81B
123 static BOOL WINAPI AdapterEnumCallback( GUID* pGUID, TCHAR* strDesc, TCHAR* strName, VOID* pContext )
124 {
125     LPDIRECTDRAW7       pDD;
126     LPDIRECT3D7         pD3D;
127     HRESULT                     hr;
128         TCHAR                   strErrorMsg[2048];
129         
130         CD3DDisplay* app                = (CD3DDisplay*) pContext;
131         D3DAdapterInfo* adapter = app->pAdapter;
132         
133     // GUID \82ð\8ew\92è\82µ\82Ä DirectDraw \82ð\8dì\90¬\82·\82é\81B
134     hr = DirectDrawCreateEx( pGUID, (VOID**)&pDD, IID_IDirectDraw7, NULL );
135         if( FAILED(hr) )
136         {
137                 D3DXGetErrorString( hr, 2048, strErrorMsg );
138         return D3DENUMRET_OK;   // \8e¸\94s
139     }
140         
141     // D3D\83f\83o\83C\83X\82ð\97ñ\8b\93\82·\82é\82½\82ß\82É\81ADirect3D \82ð\8eæ\93¾\82·\82é\81B
142     hr = pDD->QueryInterface( IID_IDirect3D7, (VOID**)&pD3D );
143     if( FAILED(hr) )
144         {
145         pDD->Release();
146                 D3DXGetErrorString( hr, 2048, strErrorMsg );
147         return D3DENUMRET_OK;   // \8e¸\94s
148         }
149
150         // \83A\83_\83v\83^\8fî\95ñ\8d\\91¢\91Ì\82Ö\83f\81[\83^\82ð\83R\83s\81[\82·\82é\81B
151         ZeroMemory( adapter, sizeof(D3DAdapterInfo) );
152     if( pGUID )
153         {
154         adapter->guidAdapter = (*pGUID);                                // \97ñ\8b\93\82ª\8fI\82í\82é\82Æ GUID \82à\96³\8cø\82É\82È\82é\82Ì\82Å\81AGUID \82Ì\96{\91Ì\82²\82Æ\8dT\82¦\82Ä\82¨\82­\81B
155         adapter->pAdapterGUID = &adapter->guidAdapter;  // \82Æ\82¢\82Á\82Ä\82à GUID \82ª NULL \82Ì\8fê\8d\87\82à\82 \82é\82Ì\82Å\81A\8e¯\95Ê\82Ì\82½\82ß\82É GUID \82Ö\82Ì\83|\83C\83\93\83^\82à\97p\88Ó\82·\82é\81B
156     }
157         DDDEVICEIDENTIFIER2 dddi;
158         pDD->GetDeviceIdentifier( &dddi, 0 );
159         lstrcpyn( adapter->strDriver, dddi.szDescription, 512 );        // strDriver[]
160         lstrcpyn( adapter->strDesc, strDesc, 39 );                                      // strDesc[]
161         DWORD dwTotal, dwFree;
162         DDSCAPS2 ddsc;
163         ZeroMemory( &ddsc, sizeof(ddsc) );
164         ddsc.dwCaps = DDSCAPS_VIDEOMEMORY;
165         pDD->GetAvailableVidMem( &ddsc, &dwTotal, &dwFree );
166         adapter->dwTotalMemory = dwTotal;                                                       // dwTotalMemory
167         adapter->ddHALCaps.dwSize = sizeof(DDCAPS);
168     adapter->ddHELCaps.dwSize = sizeof(DDCAPS);
169     pDD->GetCaps( &adapter->ddHALCaps, &adapter->ddHELCaps );   // ddHALCaps, ddHELCaps
170     if( adapter->ddHALCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED )        // \83E\83B\83\93\83h\83E\83\82\81[\83h\82Ì\95`\89æ\82ª\82Å\82«\81A
171         if( adapter->pAdapterGUID == NULL )                                                     // \83h\83\89\83C\83o\82Ì GUID \82ª NULL \82Å\82 \82é\82È\82ç
172             adapter->bDesktopCompatible = true;                                         // \83f\83X\83N\83g\83b\83v\8cÝ\8a·\83A\83_\83v\83^\82Å\82 \82é\81B
173
174         adapter->dwNumModes = 0;                                                // dwNumModes
175         adapter->dwNumDevices = 0;                                              // dwNumDevices
176         adapter->pDevice = &(adapter->devices[0]);              // pDevice
177         
178         // DirectDraw \82Å\97\98\97p\89Â\94\\82È\91S\83\82\81[\83h\82ð\97ñ\8b\93\82µ\81A\83\\81[\83g\82µ\82Ä\93à\95\94\82É\8bL\89¯\82µ\82Ä\82¨\82­\81B
179         // \81¨ \82±\82Ì\83\82\81[\83h\83\8a\83X\83g\82ð\95ê\8fW\8d\87\82Æ\82µ\82Ä\81A\8ae\82R\82c\83f\83o\83C\83X\82Å\97\98\97p\89Â\94\\82È\83\82\81[\83h\82ð\83s\83b\83N\83A\83b\83v\82·\82é\81B
180     pDD->EnumDisplayModes( 0, NULL, adapter, ModeEnumCallback );
181     qsort( adapter->modes, adapter->dwNumModes, sizeof(DDSURFACEDESC2), SortModesCallback );
182
183         // \82R\82c\83f\83o\83C\83X\82ð\82·\82×\82Ä\97ñ\8b\93\82·\82é\81B
184     pD3D->EnumDevices( DeviceEnumCallback, app );
185
186         // \83f\83t\83H\83\8b\83g\83f\83o\83C\83X\82ð\91I\91ð\82·\82é\81B
187         int nRank = -1;
188         for( DWORD d=0; d<adapter->dwNumDevices; d++ )
189         {
190                 if( adapter->devices[d].type == D3DAPPDEV_HALTnL )                                              // \8dÅ\97D\90æ\82Í HALTnL
191                 {
192                         nRank = 4;
193                         adapter->pDevice = &( adapter->devices[d] );
194                 }
195                 else if( adapter->devices[d].type == D3DAPPDEV_HAL && nRank < 4 )               // \8e\9f\82É HAL
196                 {
197                         nRank = 3;
198                         adapter->pDevice = &( adapter->devices[d] );
199                 }
200                 else if( adapter->devices[d].type == D3DAPPDEV_HEL && nRank < 3 )               // \8e\9f\82É HEL
201                 {
202                         nRank = 2;
203                         adapter->pDevice = &( adapter->devices[d] );
204                 }
205                 else
206                 {
207                         nRank = 1;
208                         adapter->pDevice = &( adapter->devices[d] );                                            // \8dÅ\8cã\82É\82»\82Ì\91¼
209                 }
210         }
211         if( nRank < 0 )
212                 adapter->pDevice = &( adapter->devices[0] );
213         
214         // \91|\8f\9c\82µ\82Ä\8e\9f\82Ì\83A\83_\83v\83^\82Ö\81B
215     pD3D->Release();
216     pDD->Release();
217         if( app->dwNumAdapters < 19 )
218         {
219                 app->dwNumAdapters ++;
220                 app->pAdapter ++;
221         }
222
223         return DDENUMRET_OK;
224 }
225
226 CD3DDisplay::CD3DDisplay()
227 {
228         this->pAdapter = &(this->adapters[0]);
229         this->dwNumAdapters = 0;
230 }
231
232 HRESULT CD3DDisplay::EnumerateDevices()
233 {
234         // \97ñ\8b\93\82·\82é
235     DirectDrawEnumerate( AdapterEnumCallback, this );
236
237         if( this->dwNumAdapters == 0 )
238                 return FDKERR_\83A\83_\83v\83^\82ª\82È\82¢;
239
240         // m_pAdapter \82É\83f\83t\83H\83\8b\83g\82Ì\83A\83_\83v\83^\82Ö\82Ì\83|\83C\83\93\83^\82ð\83Z\83b\83g\82·\82é\81B
241         for( DWORD a = 0; a < this->dwNumAdapters; a++ )
242         {
243                 if( this->adapters[a].bDesktopCompatible )
244                 {
245                         this->pAdapter = &(this->adapters[a]);
246                         break;
247                 }
248         }
249         return S_OK;
250 }
251
252 bool    CD3DDisplay::FindMode( DWORD w, DWORD h, DWORD bpp )
253 {
254         D3DAdapterInfo* a = this->pAdapter;
255         D3DDeviceInfo*  d = a->pDevice;
256         
257         for( DWORD i = 0; i < d->dwNumModes; i++ )
258         {
259                 if( ( d->modes[i].dwWidth == w ) &&
260                         ( d->modes[i].dwHeight == h ) &&
261                         ( d->modes[i].ddpfPixelFormat.dwRGBBitCount == bpp ) )
262                 {
263                         d->pMode = &( d->modes[i] );
264                         return true;            // \8c©\82Â\82©\82Á\82½
265                 }
266         }
267         return false;   // \82È\82©\82Á\82½
268 }
269
270
271         }//AppBase
272 }//FDK