From 0531986011bfb04c0ceffdb41163178dc8916bfa Mon Sep 17 00:00:00 2001 From: Gregor Brunmar Date: Tue, 12 Feb 2008 17:30:32 +0000 Subject: [PATCH] Implemented IDirect3D9::GetAdapterDisplayMode() svn path=/trunk/; revision=32326 --- reactos/dll/directx/d3d9/adapter.c | 90 +++++++++++++++++++++++++ reactos/dll/directx/d3d9/adapter.h | 2 + reactos/dll/directx/d3d9/d3d9_impl.c | 45 ++++++++++++- reactos/dll/directx/d3d9/d3d9_private.h | 10 +-- 4 files changed, 140 insertions(+), 7 deletions(-) diff --git a/reactos/dll/directx/d3d9/adapter.c b/reactos/dll/directx/d3d9/adapter.c index a43cd4de5b3..086f87e052b 100644 --- a/reactos/dll/directx/d3d9/adapter.c +++ b/reactos/dll/directx/d3d9/adapter.c @@ -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; diff --git a/reactos/dll/directx/d3d9/adapter.h b/reactos/dll/directx/d3d9/adapter.h index 3ee1e224555..8818789f9bf 100644 --- a/reactos/dll/directx/d3d9/adapter.h +++ b/reactos/dll/directx/d3d9/adapter.h @@ -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); diff --git a/reactos/dll/directx/d3d9/d3d9_impl.c b/reactos/dll/directx/d3d9/d3d9_impl.c index 87b7bdd2abb..7fcae5b0ffc 100644 --- a/reactos/dll/directx/d3d9/d3d9_impl.c +++ b/reactos/dll/directx/d3d9/d3d9_impl.c @@ -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; } diff --git a/reactos/dll/directx/d3d9/d3d9_private.h b/reactos/dll/directx/d3d9/d3d9_private.h index 1678a484bf3..ba48707174e 100644 --- a/reactos/dll/directx/d3d9/d3d9_private.h +++ b/reactos/dll/directx/d3d9/d3d9_private.h @@ -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;