From 51dfcdc44d700b1d0b88f36ed1b60511fc688948 Mon Sep 17 00:00:00 2001 From: Gregor Brunmar Date: Sun, 10 Feb 2008 08:44:06 +0000 Subject: [PATCH] Implemented IDirect3D9::GetAdapterModeCount() and IDirect3D9::EnumAdapterModes(). svn path=/trunk/; revision=32249 --- reactos/dll/directx/d3d9/adapter.c | 49 +++++++++ reactos/dll/directx/d3d9/adapter.h | 3 + reactos/dll/directx/d3d9/d3d9_create.h | 2 + reactos/dll/directx/d3d9/d3d9_impl.c | 130 +++++++++++++++++++++++- reactos/dll/directx/d3d9/d3d9_private.h | 8 +- 5 files changed, 185 insertions(+), 7 deletions(-) diff --git a/reactos/dll/directx/d3d9/adapter.c b/reactos/dll/directx/d3d9/adapter.c index 01764e7ca72..a43cd4de5b3 100644 --- a/reactos/dll/directx/d3d9/adapter.c +++ b/reactos/dll/directx/d3d9/adapter.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "adapter.h" typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); @@ -166,6 +167,8 @@ BOOL GetAdapterInfo(LPCSTR lpszDeviceName, D3DADAPTER_IDENTIFIER9* pIdentifier) return TRUE; } + + static BOOL CALLBACK AdapterMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { MONITORINFOEXA MonitorInfoEx; @@ -195,3 +198,49 @@ HMONITOR GetAdapterMonitor(LPCSTR lpszDeviceName) return AdapterMonitor.hMonitor; } + + + +UINT GetDisplayFormatCount(D3DFORMAT Format, const D3DDISPLAYMODE* pSupportedDisplayModes, UINT NumDisplayModes) +{ + UINT DisplayModeIndex; + UINT FormatIndex = 0; + + for (DisplayModeIndex = 0; DisplayModeIndex < NumDisplayModes; DisplayModeIndex++) + { + if (pSupportedDisplayModes[DisplayModeIndex].Format == Format) + { + ++FormatIndex; + } + } + + return FormatIndex; +} + +const D3DDISPLAYMODE* FindDisplayFormat(D3DFORMAT Format, UINT ModeIndex, const D3DDISPLAYMODE* pSupportedDisplayModes, UINT NumDisplayModes) +{ + UINT DisplayModeIndex; + UINT FormatIndex = 0; + + for (DisplayModeIndex = 0; DisplayModeIndex < NumDisplayModes; DisplayModeIndex++) + { + if (pSupportedDisplayModes[DisplayModeIndex].Format == Format) + { + if (ModeIndex == FormatIndex) + return &pSupportedDisplayModes[DisplayModeIndex]; + + ++FormatIndex; + } + } + + if (FormatIndex == 0) + { + DPRINT1("No modes with the specified format found"); + } + else if (FormatIndex < ModeIndex) + { + DPRINT1("Invalid mode index"); + } + + return NULL; +} diff --git a/reactos/dll/directx/d3d9/adapter.h b/reactos/dll/directx/d3d9/adapter.h index e3c80fb70a0..3ee1e224555 100644 --- a/reactos/dll/directx/d3d9/adapter.h +++ b/reactos/dll/directx/d3d9/adapter.h @@ -13,4 +13,7 @@ BOOL GetAdapterInfo(LPCSTR lpszDeviceName, D3DADAPTER_IDENTIFIER9* pIdentifier); HMONITOR GetAdapterMonitor(LPCSTR lpszDeviceName); +UINT GetDisplayFormatCount(D3DFORMAT Format, const D3DDISPLAYMODE* pSupportedDisplayModes, UINT NumDisplayModes); +const D3DDISPLAYMODE* FindDisplayFormat(D3DFORMAT Format, UINT ModeIndex, const D3DDISPLAYMODE* pSupportedDisplayModes, UINT NumDisplayModes); + #endif diff --git a/reactos/dll/directx/d3d9/d3d9_create.h b/reactos/dll/directx/d3d9/d3d9_create.h index 64ea3bd1ded..ce2c866c1cc 100644 --- a/reactos/dll/directx/d3d9/d3d9_create.h +++ b/reactos/dll/directx/d3d9/d3d9_create.h @@ -8,6 +8,8 @@ #ifndef _D3D9_CREATE_H_ #define _D3D9_CREATE_H_ +#include +#include #include "d3d9_private.h" /* Creates a Direct3D9 object */ diff --git a/reactos/dll/directx/d3d9/d3d9_impl.c b/reactos/dll/directx/d3d9/d3d9_impl.c index 49c62bccc5d..142f08d9df5 100644 --- a/reactos/dll/directx/d3d9/d3d9_impl.c +++ b/reactos/dll/directx/d3d9/d3d9_impl.c @@ -135,6 +135,7 @@ HRESULT WINAPI IDirect3D9Impl_GetAdapterIdentifier(LPDIRECT3D9 iface, UINT Adapt if (IsBadWritePtr(pIdentifier, sizeof(D3DADAPTER_IDENTIFIER9))) { + DPRINT1("Invalid pIdentifier parameter specified"); UNLOCK_D3D9(); return D3DERR_INVALIDCALL; } @@ -152,17 +153,140 @@ HRESULT WINAPI IDirect3D9Impl_GetAdapterIdentifier(LPDIRECT3D9 iface, UINT Adapt return D3D_OK; } +/*++ +* @name IDirect3D9::GetAdapterModeCount +* @implemented +* +* The function IDirect3D9Impl_GetAdapterModeCount looks if the specified display adapter supports +* a specific pixel format and counts the available display modes for that format. +* +* @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 D3DFORMAT Format +* The pixel format to search for +* +* @return HRESULT +* If the method is successfull it returns the number of display modes with the specified Format. +* If Adapter is out of range, the return value will be 0. +* +*/ static UINT WINAPI IDirect3D9Impl_GetAdapterModeCount(LPDIRECT3D9 iface, UINT Adapter, D3DFORMAT Format) { - UNIMPLEMENTED + UINT AdapterModeCount; - return D3D_OK; + LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface); + LOCK_D3D9(); + + if (Adapter >= This->NumDisplayAdapters) + { + DPRINT1("Invalid Adapter number specified"); + UNLOCK_D3D9(); + return D3DERR_INVALIDCALL; + } + + if (Format != D3DFMT_R5G6B5) + { + AdapterModeCount = GetDisplayFormatCount( + Format, + This->DisplayAdapters[Adapter].pSupportedD3DFormats, + This->DisplayAdapters[Adapter].NumSupportedD3DFormats); + } + else + { + AdapterModeCount = GetDisplayFormatCount( + Format, + This->DisplayAdapters[Adapter].pSupportedD3DExtendedFormats, + This->DisplayAdapters[Adapter].NumSupportedD3DExtendedFormats); + } + + UNLOCK_D3D9(); + return AdapterModeCount; } +/*++ +* @name IDirect3D9::EnumAdapterModes +* @implemented +* +* The function IDirect3D9Impl_EnumAdapterModes looks if the specified display adapter supports +* a specific pixel format and fills the pMode argument with the available display modes for that format. +* This function is often used in a loop to enumerate all the display modes the adapter supports. +* +* @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 D3DFORMAT Format +* The pixel format to search for +* +* @param UINT Mode +* Index within the pixel format to be returned. +* The maximym value for this is the value returned by IDirect3D9::GetAdapterModeCount(). +* +* @param D3DDISPLAYMODE* pMode +* Pointer to a D3DDISPLAYMODE structure to be filled with the display mode information +* for the specified format. +* +* @return HRESULT +* If the method successfully fills the pMode structure, the return value is D3D_OK. +* If Adapter is out of range, pMode is a bad pointer or, no modes for the specified +* format was found or the mode parameter was invalid - the return value will be D3DERR_INVALIDCALL. +* +*/ static HRESULT WINAPI IDirect3D9Impl_EnumAdapterModes(LPDIRECT3D9 iface, UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) { - UNIMPLEMENTED + const D3DDISPLAYMODE* pMatchingDisplayFormat; + 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; + } + + if (Format != D3DFMT_R5G6B5) + { + pMatchingDisplayFormat = FindDisplayFormat( + Format, + Mode, + This->DisplayAdapters[Adapter].pSupportedD3DFormats, + This->DisplayAdapters[Adapter].NumSupportedD3DFormats); + } + else + { + pMatchingDisplayFormat = FindDisplayFormat( + Format, + Mode, + This->DisplayAdapters[Adapter].pSupportedD3DExtendedFormats, + This->DisplayAdapters[Adapter].NumSupportedD3DExtendedFormats); + } + + if (pMatchingDisplayFormat != NULL) + { + *pMode = *pMatchingDisplayFormat; + } + UNLOCK_D3D9(); + + + if (pMatchingDisplayFormat == NULL) + return D3DERR_INVALIDCALL; return D3D_OK; } diff --git a/reactos/dll/directx/d3d9/d3d9_private.h b/reactos/dll/directx/d3d9/d3d9_private.h index 01584b3ee09..1678a484bf3 100644 --- a/reactos/dll/directx/d3d9/d3d9_private.h +++ b/reactos/dll/directx/d3d9/d3d9_private.h @@ -21,10 +21,10 @@ typedef struct _tagDIRECT3D9DisplayAdapterInfo_ /* 0x011c */ DWORD unknown000002; /* 0x0120 */ DWORD unknown000003; /* 0x0124 */ DWORD unknown000004; /* 0x00000001 */ -/* 0x0128 */ DWORD unknown000005; -/* 0x012c */ DWORD unknown000006; -/* 0x0130 */ DWORD unknown000007; -/* 0x0134 */ DWORD unknown000008; +/* 0x0128 */ DWORD NumSupportedD3DFormats; +/* 0x012c */ DWORD NumSupportedD3DExtendedFormats; +/* 0x0130 */ D3DDISPLAYMODE* pSupportedD3DFormats; +/* 0x0134 */ D3DDISPLAYMODE* pSupportedD3DExtendedFormats; /* 0x0138 */ DWORD unknown000009; /* 0x013c */ DWORD unknown000010; /* D3D9_DRIVERCAPS? */ /* 0x0140 */ DWORD unknown000011;