Implemented IDirect3D9::GetAdapterDisplayMode()
authorGregor Brunmar <gbrunmar.ros@gmail.com>
Tue, 12 Feb 2008 17:30:32 +0000 (17:30 +0000)
committerGregor Brunmar <gbrunmar.ros@gmail.com>
Tue, 12 Feb 2008 17:30:32 +0000 (17:30 +0000)
svn path=/trunk/; revision=32326

reactos/dll/directx/d3d9/adapter.c
reactos/dll/directx/d3d9/adapter.h
reactos/dll/directx/d3d9/d3d9_impl.c
reactos/dll/directx/d3d9/d3d9_private.h

index a43cd4d..086f87e 100644 (file)
@@ -169,6 +169,96 @@ BOOL GetAdapterInfo(LPCSTR lpszDeviceName, D3DADAPTER_IDENTIFIER9* pIdentifier)
 
 
 
+static D3DFORMAT Get16BitD3DFormat(LPCSTR lpszDeviceName)
+{
+    HDC hDC;
+    HBITMAP hBitmap;
+    LPBITMAPINFO pBitmapInfo;
+    D3DFORMAT Format = D3DFMT_R5G6B5;
+
+    if (NULL == (hDC = CreateDCA(NULL, lpszDeviceName, NULL, NULL)))
+    {
+        return Format;
+    }
+
+    if (NULL == (hBitmap = CreateCompatibleBitmap(hDC, 1, 1)))
+    {
+        DeleteDC(hDC);
+        return Format;
+    }
+
+    pBitmapInfo = LocalAlloc(LMEM_ZEROINIT, sizeof(BITMAPINFOHEADER) + 4 * sizeof(RGBQUAD));
+    if (NULL == pBitmapInfo)
+    {
+        DeleteObject(hBitmap);
+        DeleteDC(hDC);
+        return Format;
+    }
+
+    pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    if (GetDIBits(hDC, hBitmap, 0, 0, NULL, pBitmapInfo, DIB_RGB_COLORS) > 0)
+    {
+        if (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS)
+        {
+            if (GetDIBits(hDC, hBitmap, 0, pBitmapInfo->bmiHeader.biHeight, NULL, pBitmapInfo, DIB_RGB_COLORS) > 0)
+            {
+                /* Check if the green field is 6 bits long */
+                if (*(DWORD*)(&pBitmapInfo->bmiColors[1]) == 0x000003E0)
+                {
+                    Format = D3DFMT_X1R5G5B5;
+                }
+            }
+        }
+    }
+
+    LocalFree(pBitmapInfo);
+    DeleteObject(hBitmap);
+    DeleteDC(hDC);
+
+    return Format;
+}
+
+BOOL GetAdapterMode(LPCSTR lpszDeviceName, D3DDISPLAYMODE* pMode)
+{
+    DEVMODEA DevMode;
+    
+    memset(&DevMode, 0, sizeof(DEVMODEA));
+    DevMode.dmSize = sizeof(DEVMODEA);
+    if (FALSE == EnumDisplaySettingsA(lpszDeviceName, ENUM_CURRENT_SETTINGS, &DevMode))
+        return FALSE;
+
+    pMode->Width = DevMode.dmPelsWidth;
+    pMode->Height = DevMode.dmPelsHeight;
+    pMode->RefreshRate = DevMode.dmDisplayFrequency;
+    
+    switch (DevMode.dmBitsPerPel)
+    {
+    case 8:
+        pMode->Format = D3DFMT_P8;
+        break;
+
+    case 16:
+        pMode->Format = Get16BitD3DFormat(lpszDeviceName);
+        break;
+
+    case 24:
+        pMode->Format = D3DFMT_R8G8B8;
+        break;
+
+    case 32:
+        pMode->Format = D3DFMT_X8R8G8B8;
+        break;
+
+    default:
+        pMode->Format = D3DFMT_UNKNOWN;
+        break;
+    }
+
+    return TRUE;
+}
+
+
+
 static BOOL CALLBACK AdapterMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
 {
     MONITORINFOEXA MonitorInfoEx;
index 3ee1e22..8818789 100644 (file)
@@ -11,6 +11,8 @@
 
 BOOL GetAdapterInfo(LPCSTR lpszDeviceName, D3DADAPTER_IDENTIFIER9* pIdentifier);
 
+BOOL GetAdapterMode(LPCSTR lpszDeviceName, D3DDISPLAYMODE* pMode);
+
 HMONITOR GetAdapterMonitor(LPCSTR lpszDeviceName);
 
 UINT GetDisplayFormatCount(D3DFORMAT Format, const D3DDISPLAYMODE* pSupportedDisplayModes, UINT NumDisplayModes);
index 87b7bdd..7fcae5b 100644 (file)
@@ -291,10 +291,51 @@ static HRESULT WINAPI IDirect3D9Impl_EnumAdapterModes(LPDIRECT3D9 iface, UINT Ad
     return D3D_OK;
 }
 
-static HRESULT WINAPI IDirect3D9Impl_GetAdapterDisplayMode(LPDIRECT3D9 iface, UINT Adapter, D3DDISPLAYMODE* pMode)
+/*++
+* @name IDirect3D9::GetAdapterDisplayMode
+* @implemented
+*
+* The function IDirect3D9Impl_GetAdapterDisplayMode fills the pMode argument with the
+* currently set display mode.
+*
+* @param LPDIRECT3D iface
+* Pointer to the IDirect3D object returned from Direct3DCreate9()
+*
+* @param UINT Adapter
+* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
+* The maximum value for this is the value returned by IDirect3D::GetAdapterCount().
+*
+* @param D3DDISPLAYMODE* pMode
+* Pointer to a D3DDISPLAYMODE structure to be filled with the current display mode information.
+*
+* @return HRESULT
+* If the method successfully fills the pMode structure, the return value is D3D_OK.
+* If Adapter is out of range or pMode is a bad pointer, the return value will be D3DERR_INVALIDCALL.
+*
+*/static HRESULT WINAPI IDirect3D9Impl_GetAdapterDisplayMode(LPDIRECT3D9 iface, UINT Adapter, D3DDISPLAYMODE* pMode)
 {
-    UNIMPLEMENTED
+    LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
+    LOCK_D3D9();
 
+    if (Adapter >= This->NumDisplayAdapters)
+    {
+        DPRINT1("Invalid Adapter number specified");
+        UNLOCK_D3D9();
+        return D3DERR_INVALIDCALL;
+    }
+
+    if (IsBadWritePtr(pMode, sizeof(D3DDISPLAYMODE)))
+    {
+        DPRINT1("Invalid pMode parameter specified");
+        UNLOCK_D3D9();
+        return D3DERR_INVALIDCALL;
+    }
+
+    /* TODO: Handle (This->DisplayAdapters[Adapter].bInUseFlag == FALSE) */
+    if (FALSE == GetAdapterMode(This->DisplayAdapters[Adapter].szDeviceName, pMode))
+        DPRINT1("Internal error, GetAdapterMode() failed.");
+
+    UNLOCK_D3D9();
     return D3D_OK;
 }
 
index 1678a48..ba48707 100644 (file)
@@ -102,11 +102,11 @@ typedef struct _tagDIRECT3D9DisplayAdapterInfo_
 /* 0x0260 */    DWORD unknown000083;
 /* 0x0264 */    DWORD unknown000084;
 /* 0x0268 */    DWORD unknown000085;
-/* 0x026c */    DWORD dwDisplayWidth; /* Current display res */
-/* 0x0270 */    DWORD dwDisplayHeight; /* Current display res */
-/* 0x0274 */    DWORD unknown000088;
-/* 0x0278 */    DWORD unknown000089;
-/* 0x027c */    DWORD unknown000090;
+/* 0x026c */    DWORD dwDisplayWidth;   /* Current display res */
+/* 0x0270 */    DWORD dwDisplayHeight;  /* Current display res */
+/* 0x0274 */    DWORD unknown000088;    /* Current D3DFORMAT */
+/* 0x0278 */    DWORD unknown000089;    /* Current D3DFORMAT - duplicate? */
+/* 0x027c */    DWORD MonitorFrequency; /* Current monitor frequency */
 /* 0x0280 */    DWORD unknown000091;
 /* 0x0284 */    DWORD unknown000092;
 /* 0x0288 */    DWORD unknown000093;