* Changed to aligned alloc of Direct3D9 object
[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 D3dDebugRegPath = "Software\\Microsoft\\Direct3D";
17
18 static const GUID DISPLAY_GUID = { 0x67685559, 0x3106, 0x11D0, { 0xB9, 0x71, 0x00, 0xAA, 0x00, 0x34, 0x2F, 0x9F } };
19
20 LPDIRECT3D9_INT impl_from_IDirect3D9(LPDIRECT3D9 iface)
21 {
22 return (LPDIRECT3D9_INT)((ULONG_PTR)iface - FIELD_OFFSET(DIRECT3D9_INT, lpVtbl));
23 }
24
25 BOOL ReadRegistryValue(IN DWORD ValueType, IN LPCSTR ValueName, OUT LPBYTE DataBuffer, IN OUT LPDWORD DataBufferSize)
26 {
27 HKEY hKey;
28 DWORD Type;
29 LONG Ret;
30
31 if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, D3dDebugRegPath, 0, KEY_QUERY_VALUE, &hKey))
32 return FALSE;
33
34 Ret = RegQueryValueEx(hKey, ValueName, 0, &Type, DataBuffer, DataBufferSize);
35
36 RegCloseKey(hKey);
37
38 if (ERROR_SUCCESS != Ret)
39 return FALSE;
40
41 if (Type != ValueType)
42 return FALSE;
43
44 return TRUE;
45 }
46
47 HRESULT FormatDebugString(IN OUT LPSTR Buffer, IN LONG BufferSize, IN LPCSTR FormatString, ... )
48 {
49 int BytesWritten;
50 va_list vargs;
51
52 if (BufferSize == 0)
53 return DDERR_INVALIDPARAMS;
54
55 va_start(vargs, FormatString);
56 BytesWritten = _vsnprintf(Buffer, BufferSize-1, FormatString, vargs);
57
58 if (BytesWritten < BufferSize)
59 return DDERR_GENERIC;
60
61 Buffer[BufferSize-1] = '\0';
62
63 return 0;
64 }
65
66 HRESULT CreateD3D9(OUT LPDIRECT3D9 *ppDirect3D9)
67 {
68 LPDIRECT3D9_INT pDirect3D9;
69
70 if (ppDirect3D9 == 0)
71 return DDERR_INVALIDPARAMS;
72
73 if (AlignedAlloc((LPVOID *)&pDirect3D9, sizeof(DIRECT3D9_INT)) != S_OK)
74 return DDERR_OUTOFMEMORY;
75
76 if (pDirect3D9 == 0)
77 return DDERR_OUTOFMEMORY;
78
79 pDirect3D9->unknown000007 = 0;
80 pDirect3D9->lpInt = 0;
81
82 pDirect3D9->lpVtbl = &Direct3D9_Vtbl;
83 pDirect3D9->dwProcessId = GetCurrentThreadId();
84 pDirect3D9->dwRefCnt = 1;
85
86 pDirect3D9->unknown004576 = 0;
87 pDirect3D9->unknown004578 = 0;
88 pDirect3D9->unknown004579 = 0;
89 pDirect3D9->unknown004580 = 0;
90 pDirect3D9->unknown004581 = 0;
91 pDirect3D9->unknown004582 = 0;
92 pDirect3D9->unknown004583 = 0;
93 pDirect3D9->unknown004589 = 0x20;
94
95 pDirect3D9->lpInt = pDirect3D9;
96 pDirect3D9->unknown000007 = 1;
97
98 InitializeCriticalSection(&pDirect3D9->d3d9_cs);
99
100 memcpy(&pDirect3D9->DisplayGuid, &DISPLAY_GUID, sizeof(GUID));
101
102 *ppDirect3D9 = (LPDIRECT3D9)&pDirect3D9->lpVtbl;
103
104 return ERROR_SUCCESS;
105 }
106
107 HRESULT AlignedAlloc(IN OUT LPVOID *ppObject, IN SIZE_T dwSize)
108 {
109 ULONG AddressOffset;
110 ULONG AlignedMask = MEM_ALIGNMENT - 1;
111 CHAR *AlignedPtr;
112 ULONG_PTR *AlignedOffsetPtr;
113
114 if (ppObject == 0)
115 return DDERR_INVALIDPARAMS;
116
117 if (dwSize == 0)
118 {
119 *ppObject = NULL;
120 return S_OK;
121 }
122
123 dwSize += MEM_ALIGNMENT;
124
125 AlignedPtr = (CHAR *)LocalAlloc(LMEM_ZEROINIT, dwSize);
126
127 if (AlignedPtr == 0)
128 return DDERR_OUTOFMEMORY;
129
130 AddressOffset = MEM_ALIGNMENT - ((ULONG)AlignedPtr & AlignedMask);
131
132 AlignedPtr += AddressOffset;
133
134 AlignedOffsetPtr = (ULONG_PTR *)(AlignedPtr - sizeof(ULONG));
135 *AlignedOffsetPtr = AddressOffset;
136
137 *ppObject = (ULONG_PTR *)AlignedPtr;
138
139 return S_OK;
140 }
141
142 VOID AlignedFree(IN OUT LPVOID pObject)
143 {
144 CHAR *NonAlignedPtr = pObject;
145 ULONG_PTR *AlignedPtr = pObject;
146
147 if (pObject == 0)
148 return;
149
150 NonAlignedPtr -= *(AlignedPtr - 1);
151
152 LocalFree(NonAlignedPtr);
153 }