b74d200299f495fe50540b95878060f0a71375a4
[reactos.git] / reactos / dll / directx / d3d9 / d3d9_helpers.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS ReactX
4 * FILE: dll/directx/d3d9/d3d9_helpers.c
5 * PURPOSE: d3d9.dll helper functions
6 * PROGRAMERS: Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se>
7 */
8
9 #include "d3d9_helpers.h"
10 #include <stdio.h>
11 #include <ddraw.h>
12 #include <debug.h>
13
14 #define MEM_ALIGNMENT 0x20
15
16 static LPCSTR D3D9_DebugRegPath = "Software\\Microsoft\\Direct3D";
17
18 static const GUID DISPLAY_GUID = { 0x67685559, 0x3106, 0x11D0, { 0xB9, 0x71, 0x00, 0xAA, 0x00, 0x34, 0x2F, 0x9F } };
19
20 static CHAR D3D9_PrimaryDeviceName[32];
21
22 LPDIRECT3D9_INT impl_from_IDirect3D9(LPDIRECT3D9 iface)
23 {
24 return (LPDIRECT3D9_INT)((ULONG_PTR)iface - FIELD_OFFSET(DIRECT3D9_INT, lpVtbl));
25 }
26
27 BOOL ReadRegistryValue(IN DWORD ValueType, IN LPCSTR ValueName, OUT LPBYTE DataBuffer, IN OUT LPDWORD DataBufferSize)
28 {
29 HKEY hKey;
30 DWORD Type;
31 LONG Ret;
32
33 if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, D3D9_DebugRegPath, 0, KEY_QUERY_VALUE, &hKey))
34 return FALSE;
35
36 Ret = RegQueryValueEx(hKey, ValueName, 0, &Type, DataBuffer, DataBufferSize);
37
38 RegCloseKey(hKey);
39
40 if (ERROR_SUCCESS != Ret)
41 return FALSE;
42
43 if (Type != ValueType)
44 return FALSE;
45
46 return TRUE;
47 }
48
49 HRESULT FormatDebugString(IN OUT LPSTR Buffer, IN LONG BufferSize, IN LPCSTR FormatString, ... )
50 {
51 int BytesWritten;
52 va_list vargs;
53
54 if (BufferSize == 0)
55 return DDERR_INVALIDPARAMS;
56
57 va_start(vargs, FormatString);
58 BytesWritten = _vsnprintf(Buffer, BufferSize-1, FormatString, vargs);
59
60 if (BytesWritten < BufferSize)
61 return DDERR_GENERIC;
62
63 Buffer[BufferSize-1] = '\0';
64
65 return 0;
66 }
67
68 static BOOL GetDisplayDeviceInfo(IN OUT LPDIRECT3D9_INT pDirect3D9)
69 {
70 DISPLAY_DEVICEA DisplayDevice;
71 DWORD AdapterIndex;
72 DWORD Planes;
73 DWORD Bpp;
74 HDC hDC;
75
76 memset(&DisplayDevice, 0, sizeof(DISPLAY_DEVICEA));
77 DisplayDevice.cb = sizeof(DISPLAY_DEVICEA);
78
79 pDirect3D9->dwNumDisplayAdapters = 0;
80 D3D9_PrimaryDeviceName[0] = '\0';
81
82 AdapterIndex = 0;
83 while (EnumDisplayDevicesA(NULL, AdapterIndex, &DisplayDevice, 0) == TRUE)
84 {
85 if ((DisplayDevice.StateFlags & (DISPLAY_DEVICE_DISCONNECT | DISPLAY_DEVICE_MIRRORING_DRIVER)) == 0 &&
86 (DisplayDevice.StateFlags & (DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) != 0)
87 {
88 memcpy(&pDirect3D9->DisplayAdapters[0].DisplayGuid, &DISPLAY_GUID, sizeof(GUID));
89
90 lstrcpynA(pDirect3D9->DisplayAdapters[0].szDeviceName, DisplayDevice.DeviceName, MAX_PATH);
91
92 if (pDirect3D9->dwNumDisplayAdapters == 0)
93 lstrcpynA(D3D9_PrimaryDeviceName, DisplayDevice.DeviceName, sizeof(D3D9_PrimaryDeviceName));
94
95 pDirect3D9->DisplayAdapters[0].dwStateFlags = DisplayDevice.StateFlags;
96 pDirect3D9->DisplayAdapters[0].bInUseFlag = TRUE;
97
98 ++pDirect3D9->dwNumDisplayAdapters;
99 }
100 }
101
102 AdapterIndex = 0;
103 while (EnumDisplayDevicesA(NULL, AdapterIndex, &DisplayDevice, 0) == TRUE)
104 {
105 if ((DisplayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0 &&
106 (DisplayDevice.StateFlags & (DISPLAY_DEVICE_MIRRORING_DRIVER | DISPLAY_DEVICE_PRIMARY_DEVICE)) == 0)
107 {
108 memcpy(&pDirect3D9->DisplayAdapters[pDirect3D9->dwNumDisplayAdapters].DisplayGuid, &DISPLAY_GUID, sizeof(GUID));
109
110 lstrcpynA(pDirect3D9->DisplayAdapters[pDirect3D9->dwNumDisplayAdapters].szDeviceName, DisplayDevice.DeviceName, MAX_PATH);
111
112 pDirect3D9->DisplayAdapters[pDirect3D9->dwNumDisplayAdapters].dwStateFlags = DisplayDevice.StateFlags;
113 pDirect3D9->DisplayAdapters[pDirect3D9->dwNumDisplayAdapters].bInUseFlag = TRUE;
114
115 ++pDirect3D9->dwNumDisplayAdapters;
116 }
117 }
118
119 hDC = GetDC(NULL);
120 Planes = GetDeviceCaps(hDC, PLANES);
121 Bpp = GetDeviceCaps(hDC, BITSPIXEL);
122 ReleaseDC(NULL, hDC);
123
124 if (Planes * Bpp < 8)
125 return FALSE;
126
127 return TRUE;
128 }
129
130 HRESULT CreateD3D9(OUT LPDIRECT3D9 *ppDirect3D9)
131 {
132 LPDIRECT3D9_INT pDirect3D9;
133
134 if (ppDirect3D9 == 0)
135 return DDERR_INVALIDPARAMS;
136
137 if (AlignedAlloc((LPVOID *)&pDirect3D9, sizeof(DIRECT3D9_INT)) != S_OK)
138 return DDERR_OUTOFMEMORY;
139
140 if (pDirect3D9 == 0)
141 return DDERR_OUTOFMEMORY;
142
143 pDirect3D9->unknown000007 = 0;
144 pDirect3D9->lpInt = 0;
145
146 pDirect3D9->lpVtbl = &Direct3D9_Vtbl;
147 //pDirect3D9->dwProcessId = GetCurrentThreadId();
148 pDirect3D9->dwRefCnt = 1;
149
150 pDirect3D9->unknown004576 = 0;
151 pDirect3D9->unknown004578 = 0;
152 pDirect3D9->unknown004579 = 0;
153 pDirect3D9->unknown004580 = 0;
154 pDirect3D9->unknown004581 = 0;
155 pDirect3D9->unknown004582 = 0;
156 pDirect3D9->unknown004583 = 0;
157 pDirect3D9->unknown004589 = 0x20;
158
159 pDirect3D9->lpInt = pDirect3D9;
160 pDirect3D9->unknown000007 = 1;
161
162 //InitializeCriticalSection(&pDirect3D9->d3d9_cs);
163
164 //memset(pDirect3D9->DisplayAdapters, 0, sizeof(pDirect3D9->DisplayAdapters));
165 GetDisplayDeviceInfo(pDirect3D9);
166
167 *ppDirect3D9 = (LPDIRECT3D9)&pDirect3D9->lpVtbl;
168
169 return ERROR_SUCCESS;
170 }
171
172 HRESULT AlignedAlloc(IN OUT LPVOID *ppObject, IN SIZE_T dwSize)
173 {
174 ULONG AddressOffset;
175 ULONG AlignedMask = MEM_ALIGNMENT - 1;
176 CHAR *AlignedPtr;
177 ULONG_PTR *AlignedOffsetPtr;
178
179 if (ppObject == 0)
180 return DDERR_INVALIDPARAMS;
181
182 if (dwSize == 0)
183 {
184 *ppObject = NULL;
185 return S_OK;
186 }
187
188 dwSize += MEM_ALIGNMENT;
189
190 AlignedPtr = (CHAR *)LocalAlloc(LMEM_ZEROINIT, dwSize);
191
192 if (AlignedPtr == 0)
193 return DDERR_OUTOFMEMORY;
194
195 AddressOffset = MEM_ALIGNMENT - ((ULONG)AlignedPtr & AlignedMask);
196
197 AlignedPtr += AddressOffset;
198
199 AlignedOffsetPtr = (ULONG_PTR *)(AlignedPtr - sizeof(ULONG));
200 *AlignedOffsetPtr = AddressOffset;
201
202 *ppObject = (ULONG_PTR *)AlignedPtr;
203
204 return S_OK;
205 }
206
207 VOID AlignedFree(IN OUT LPVOID pObject)
208 {
209 CHAR *NonAlignedPtr = pObject;
210 ULONG_PTR *AlignedPtr = pObject;
211
212 if (pObject == 0)
213 return;
214
215 NonAlignedPtr -= *(AlignedPtr - 1);
216
217 LocalFree(NonAlignedPtr);
218 }