-
Notifications
You must be signed in to change notification settings - Fork 91
/
IDirect3DDeviceX.h
347 lines (304 loc) · 12.9 KB
/
IDirect3DDeviceX.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
#pragma once
#include <unordered_map>
#include <unordered_set>
class m_IDirect3DDeviceX : public IUnknown, public AddressLookupTableDdrawObject
{
private:
IDirect3DDevice7 *ProxyInterface = nullptr;
DWORD ProxyDirectXVersion;
ULONG RefCount1 = 0;
ULONG RefCount2 = 0;
ULONG RefCount3 = 0;
ULONG RefCount7 = 0;
REFCLSID ClassID;
// Store d3d device version wrappers
m_IDirect3DDevice* WrapperInterface = nullptr;
m_IDirect3DDevice2* WrapperInterface2 = nullptr;
m_IDirect3DDevice3* WrapperInterface3 = nullptr;
m_IDirect3DDevice7* WrapperInterface7 = nullptr;
// Convert Device
m_IDirectDrawX *ddrawParent = nullptr;
m_IDirectDrawSurfaceX* lpCurrentRenderTargetX = nullptr;
LPDIRECT3DDEVICE9 *d3d9Device = nullptr;
LPDIRECT3DPIXELSHADER9* colorkeyPixelShader = nullptr;
LPDIRECT3DVIEWPORT3 lpCurrentViewport = nullptr;
m_IDirect3DViewportX* lpCurrentViewportX = nullptr;
#ifdef ENABLE_PROFILING
std::chrono::steady_clock::time_point sceneTime;
#endif
struct {
DWORD RenderState[255] = {};
DWORD TextureState[MaxTextureStages][255] = {};
DWORD SamplerState[MaxTextureStages][14] = {};
D3DLIGHT9 lights[MAX_LIGHTS] = {};
BOOL lightEnabled[MAX_LIGHTS] = {};
D3DVIEWPORT9 viewport = {};
D3DMATERIAL9 material = {};
D3DMATRIX worldMatrix = {}, viewMatrix = {}, projectionMatrix = {};
} backup;
struct {
DWORD rsClipping = 0;
DWORD rsLighting = 0;
DWORD rsExtents = 0;
DWORD rsAlphaTestEnable = 0;
DWORD rsAlphaFunc = 0;
DWORD rsAlphaRef = 0;
DWORD ssMinFilter[MaxTextureStages] = {};
DWORD ssMagFilter[MaxTextureStages] = {};
float lowColorKey[4] = {};
float highColorKey[4] = {};
} DrawStates;
bool bSetDefaults = true;
bool IsInScene = false;
// Last clip status
D3DCLIPSTATUS D3DClipStatus;
// Light states
DWORD lsMaterialHandle;
// Render states
bool rsAntiAliasChanged;
DWORD rsAntiAlias;
DWORD rsEdgeAntiAlias;
bool rsTextureWrappingChanged;
DWORD rsTextureWrappingU;
DWORD rsTextureWrappingV;
DWORD rsTextureHandle;
DWORD rsTextureMin;
DWORD rsTextureMapBlend;
DWORD rsAlphaBlendEnabled;
DWORD rsSrcBlend;
DWORD rsDestBlend;
DWORD rsColorKeyEnabled;
DWORD ssMipFilter[MaxTextureStages] = {};
// Handle state blocks
bool IsRecordingState = false;
std::unordered_set<DWORD> StateBlockTokens;
// Default settings
D3DMATERIAL9 DefaultMaterial = {};
D3DVIEWPORT9 DefaultViewport = {};
// SetTexture array
LPDIRECTDRAWSURFACE7 CurrentRenderTarget = nullptr;
m_IDirectDrawSurfaceX* CurrentTextureSurfaceX[MaxTextureStages] = {};
LPDIRECTDRAWSURFACE7 AttachedTexture[MaxTextureStages] = {};
// Texture handle map
std::unordered_map<DWORD, m_IDirect3DTextureX*> TextureHandleMap;
// Material handle map
std::unordered_map<D3DMATERIALHANDLE, m_IDirect3DMaterialX*> MaterialHandleMap;
// Light index map
std::unordered_map<DWORD, m_IDirect3DLight*> LightIndexMap;
// Vector temporary buffer cache
std::vector<BYTE> VertexCache;
// Viewport array
std::vector<LPDIRECT3DVIEWPORT3> AttachedViewports;
bool IsViewportAttached(LPDIRECT3DVIEWPORT3 ViewportX)
{
auto it = std::find_if(AttachedViewports.begin(), AttachedViewports.end(),
[=](auto pViewport) -> bool { return pViewport == ViewportX; });
if (it != std::end(AttachedViewports))
{
return true;
}
return false;
}
bool DeleteAttachedViewport(LPDIRECT3DVIEWPORT3 ViewportX)
{
auto it = std::find_if(AttachedViewports.begin(), AttachedViewports.end(),
[=](auto pViewport) -> bool { return pViewport == ViewportX; });
if (it != std::end(AttachedViewports))
{
AttachedViewports.erase(it);
return true;
}
return false;
}
// Wrapper interface functions
inline REFIID GetWrapperType(DWORD DirectXVersion)
{
return (DirectXVersion == 1) ? IID_IDirect3DDevice :
(DirectXVersion == 2) ? IID_IDirect3DDevice2 :
(DirectXVersion == 3) ? IID_IDirect3DDevice3 :
(DirectXVersion == 7) ? IID_IDirect3DDevice7 : IID_IUnknown;
}
inline bool CheckWrapperType(REFIID IID)
{
return (IID == IID_IDirect3DDevice ||
IID == IID_IDirect3DDevice2 ||
IID == IID_IDirect3DDevice3 ||
IID == IID_IDirect3DDevice7) ? true : false;
}
inline IDirect3DDevice *GetProxyInterfaceV1() { return (IDirect3DDevice *)ProxyInterface; }
inline IDirect3DDevice2 *GetProxyInterfaceV2() { return (IDirect3DDevice2 *)ProxyInterface; }
inline IDirect3DDevice3 *GetProxyInterfaceV3() { return (IDirect3DDevice3 *)ProxyInterface; }
inline IDirect3DDevice7 *GetProxyInterfaceV7() { return ProxyInterface; }
// Interface initialization functions
void InitDevice(DWORD DirectXVersion);
void ReleaseDevice();
// Check interfaces
HRESULT CheckInterface(char *FunctionName, bool CheckD3DDevice);
// Helper functions
HRESULT BackupStates();
HRESULT RestoreStates();
void SetDefaults();
void SetDrawStates(DWORD dwVertexTypeDesc, DWORD& dwFlags, DWORD DirectXVersion);
void RestoreDrawStates(DWORD dwVertexTypeDesc, DWORD dwFlags, DWORD DirectXVersion);
void ScaleVertices(DWORD dwVertexTypeDesc, LPVOID& lpVertices, DWORD dwVertexCount);
void UpdateVertices(DWORD& dwVertexTypeDesc, LPVOID& lpVertices, DWORD dwVertexCount);
public:
m_IDirect3DDeviceX(IDirect3DDevice7 *aOriginal, DWORD DirectXVersion) : ProxyInterface(aOriginal), ClassID(IID_IDirect3DHALDevice)
{
ProxyDirectXVersion = GetGUIDVersion(ConvertREFIID(GetWrapperType(DirectXVersion)));
if (ProxyDirectXVersion != DirectXVersion)
{
LOG_LIMIT(3, "Creating interface " << __FUNCTION__ << " (" << this << ")" << " converting interface from v" << DirectXVersion << " to v" << ProxyDirectXVersion);
}
else
{
LOG_LIMIT(3, "Creating interface " << __FUNCTION__ << " (" << this << ") v" << DirectXVersion);
}
InitDevice(DirectXVersion);
}
m_IDirect3DDeviceX(m_IDirectDrawX *lpDdraw, LPDIRECTDRAWSURFACE7 pRenderTarget, REFCLSID rclsid, DWORD DirectXVersion) : ddrawParent(lpDdraw), CurrentRenderTarget(pRenderTarget), ClassID(rclsid)
{
ProxyDirectXVersion = 9;
LOG_LIMIT(3, "Creating interface " << __FUNCTION__ << " (" << this << ")" << " converting interface from v" << DirectXVersion << " to v" << ProxyDirectXVersion);
InitDevice(DirectXVersion);
}
~m_IDirect3DDeviceX()
{
LOG_LIMIT(3, __FUNCTION__ << " (" << this << ")" << " deleting interface!");
ReleaseDevice();
}
/*** IUnknown methods ***/
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) { return QueryInterface(riid, ppvObj, 0); }
STDMETHOD_(ULONG, AddRef) (THIS) { return AddRef(0); }
STDMETHOD_(ULONG, Release) (THIS) { return Release(0); }
/*** IDirect3DDevice methods ***/
STDMETHOD(Initialize)(THIS_ LPDIRECT3D, LPGUID, LPD3DDEVICEDESC);
STDMETHOD(CreateExecuteBuffer)(THIS_ LPD3DEXECUTEBUFFERDESC, LPDIRECT3DEXECUTEBUFFER*, IUnknown*);
STDMETHOD(Execute)(THIS_ LPDIRECT3DEXECUTEBUFFER, LPDIRECT3DVIEWPORT, DWORD);
STDMETHOD(Pick)(THIS_ LPDIRECT3DEXECUTEBUFFER, LPDIRECT3DVIEWPORT, DWORD, LPD3DRECT);
STDMETHOD(GetPickRecords)(THIS_ LPDWORD, LPD3DPICKRECORD);
STDMETHOD(CreateMatrix)(THIS_ LPD3DMATRIXHANDLE);
STDMETHOD(SetMatrix)(THIS_ D3DMATRIXHANDLE, const LPD3DMATRIX);
STDMETHOD(GetMatrix)(THIS_ D3DMATRIXHANDLE, LPD3DMATRIX);
STDMETHOD(DeleteMatrix)(THIS_ D3DMATRIXHANDLE);
STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE, LPD3DMATRIX);
STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE, LPD3DMATRIX);
STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE, LPD3DMATRIX);
STDMETHOD(PreLoad)(THIS_ LPDIRECTDRAWSURFACE7);
STDMETHOD(Load)(THIS_ LPDIRECTDRAWSURFACE7, LPPOINT, LPDIRECTDRAWSURFACE7, LPRECT, DWORD);
STDMETHOD(SwapTextureHandles)(THIS_ LPDIRECT3DTEXTURE2, LPDIRECT3DTEXTURE2);
STDMETHOD(EnumTextureFormats)(THIS_ LPD3DENUMTEXTUREFORMATSCALLBACK, LPVOID);
STDMETHOD(EnumTextureFormats)(THIS_ LPD3DENUMPIXELFORMATSCALLBACK, LPVOID);
STDMETHOD(GetTexture)(THIS_ DWORD, LPDIRECT3DTEXTURE2 *);
STDMETHOD(GetTexture)(THIS_ DWORD, LPDIRECTDRAWSURFACE7 *);
STDMETHOD(SetTexture)(THIS_ DWORD, LPDIRECT3DTEXTURE2);
STDMETHOD(SetTexture)(THIS_ DWORD, LPDIRECTDRAWSURFACE7);
STDMETHOD(SetRenderTarget)(THIS_ LPDIRECTDRAWSURFACE7, DWORD);
STDMETHOD(GetRenderTarget)(THIS_ LPDIRECTDRAWSURFACE7 *, DWORD);
STDMETHOD(GetTextureStageState)(THIS_ DWORD, D3DTEXTURESTAGESTATETYPE, LPDWORD);
STDMETHOD(SetTextureStageState)(THIS_ DWORD, D3DTEXTURESTAGESTATETYPE, DWORD);
STDMETHOD(GetCaps)(THIS_ LPD3DDEVICEDESC, LPD3DDEVICEDESC);
STDMETHOD(GetCaps)(THIS_ LPD3DDEVICEDESC7);
STDMETHOD(GetStats)(THIS_ LPD3DSTATS, DWORD);
STDMETHOD(AddViewport)(THIS_ LPDIRECT3DVIEWPORT3);
STDMETHOD(DeleteViewport)(THIS_ LPDIRECT3DVIEWPORT3);
STDMETHOD(NextViewport)(THIS_ LPDIRECT3DVIEWPORT3, LPDIRECT3DVIEWPORT3*, DWORD, DWORD);
STDMETHOD(SetCurrentViewport)(THIS_ LPDIRECT3DVIEWPORT3);
STDMETHOD(GetCurrentViewport)(THIS_ LPDIRECT3DVIEWPORT3 *, DWORD);
STDMETHOD(SetViewport)(THIS_ LPD3DVIEWPORT7);
STDMETHOD(GetViewport)(THIS_ LPD3DVIEWPORT7);
STDMETHOD(Begin)(THIS_ D3DPRIMITIVETYPE, DWORD, DWORD);
STDMETHOD(BeginIndexed)(THIS_ D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, DWORD);
STDMETHOD(Vertex)(THIS_ LPVOID);
STDMETHOD(Index)(THIS_ WORD);
STDMETHOD(End)(THIS_ DWORD);
STDMETHOD(BeginScene)(THIS);
STDMETHOD(EndScene)(THIS);
STDMETHOD(Clear)(THIS_ DWORD, LPD3DRECT, DWORD, D3DCOLOR, D3DVALUE, DWORD);
STDMETHOD(GetDirect3D)(THIS_ LPDIRECT3D7*, DWORD);
STDMETHOD(GetLightState)(THIS_ D3DLIGHTSTATETYPE, LPDWORD);
STDMETHOD(SetLightState)(THIS_ D3DLIGHTSTATETYPE, DWORD);
STDMETHOD(SetLight)(THIS_ m_IDirect3DLight*, LPD3DLIGHT);
STDMETHOD(SetLight)(THIS_ DWORD, LPD3DLIGHT7);
STDMETHOD(GetLight)(THIS_ DWORD, LPD3DLIGHT7);
STDMETHOD(LightEnable)(THIS_ DWORD, BOOL);
STDMETHOD(GetLightEnable)(THIS_ m_IDirect3DLight*, BOOL*);
STDMETHOD(GetLightEnable)(THIS_ DWORD, BOOL*);
STDMETHOD(SetMaterial)(THIS_ LPD3DMATERIAL);
STDMETHOD(SetMaterial)(THIS_ LPD3DMATERIAL7);
STDMETHOD(GetMaterial)(THIS_ LPD3DMATERIAL7);
STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE, DWORD);
STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE, LPDWORD);
STDMETHOD(BeginStateBlock)(THIS);
STDMETHOD(EndStateBlock)(THIS_ LPDWORD);
STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, DWORD, DWORD);
STDMETHOD(DrawPrimitiveStrided)(THIS_ D3DPRIMITIVETYPE, DWORD, LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, DWORD, DWORD);
STDMETHOD(DrawPrimitiveVB)(THIS_ D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, DWORD, DWORD);
STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, LPWORD, DWORD, DWORD, DWORD);
STDMETHOD(DrawIndexedPrimitiveStrided)(THIS_ D3DPRIMITIVETYPE, DWORD, LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, LPWORD, DWORD, DWORD, DWORD);
STDMETHOD(DrawIndexedPrimitiveVB)(THIS_ D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, LPWORD, DWORD, DWORD, DWORD);
STDMETHOD(ComputeSphereVisibility)(THIS_ LPD3DVECTOR, LPD3DVALUE, DWORD, DWORD, LPDWORD);
STDMETHOD(ValidateDevice)(THIS_ LPDWORD);
STDMETHOD(ApplyStateBlock)(THIS_ DWORD);
STDMETHOD(CaptureStateBlock)(THIS_ DWORD);
STDMETHOD(DeleteStateBlock)(THIS_ DWORD);
STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE, LPDWORD);
STDMETHOD(SetClipStatus)(THIS_ LPD3DCLIPSTATUS);
STDMETHOD(GetClipStatus)(THIS_ LPD3DCLIPSTATUS);
STDMETHOD(SetClipPlane)(THIS_ DWORD, D3DVALUE*);
STDMETHOD(GetClipPlane)(THIS_ DWORD, D3DVALUE*);
STDMETHOD(GetInfo)(THIS_ DWORD, LPVOID, DWORD);
// Helper functions
HRESULT QueryInterface(REFIID riid, LPVOID FAR * ppvObj, DWORD DirectXVersion);
void *GetWrapperInterfaceX(DWORD DirectXVersion);
ULONG AddRef(DWORD DirectXVersion);
ULONG Release(DWORD DirectXVersion);
bool IsDeviceInScene() { return IsInScene; }
// Viewport functions
inline void GetDefaultViewport(D3DVIEWPORT9& Viewport) { Viewport = DefaultViewport; }
inline bool CheckIfViewportSet(m_IDirect3DViewportX* pViewport) { return (pViewport == lpCurrentViewportX); }
// Texture handle function
void ReleaseTextureHandle(m_IDirect3DTextureX* lpTexture);
HRESULT SetTextureHandle(DWORD tHandle, m_IDirect3DTextureX* lpTexture);
// Material handle function
inline void GetDefaultMaterial(D3DMATERIAL9& Material) { Material = DefaultMaterial; }
void ReleaseMaterialHandle(m_IDirect3DMaterialX* lpMaterial);
HRESULT SetMaterialHandle(D3DMATERIALHANDLE mHandle, m_IDirect3DMaterialX* lpMaterial);
inline bool CheckIfMaterialSet(D3DMATERIALHANDLE mHandle) { return (mHandle == lsMaterialHandle); }
// Light index function
void ReleaseLightInterface(m_IDirect3DLight* lpLight);
// Functions handling the ddraw parent interface
void ClearSurface(m_IDirectDrawSurfaceX* lpSurfaceX)
{
if (lpCurrentRenderTargetX == lpSurfaceX)
{
lpCurrentRenderTargetX = nullptr;
}
for (UINT x = 1; x < MaxTextureStages; x++)
{
if (CurrentTextureSurfaceX[x] == lpSurfaceX)
{
SetTexture(x, (LPDIRECTDRAWSURFACE7)nullptr);
AttachedTexture[x] = nullptr;
CurrentTextureSurfaceX[x] = nullptr;
}
}
}
void SetDdrawParent(m_IDirectDrawX *ddraw)
{
ddrawParent = ddraw;
// Store D3DDevice
if (ddrawParent)
{
ddrawParent->SetD3DDevice(this);
if (lpCurrentRenderTargetX)
{
ddrawParent->SetRenderTargetSurface(lpCurrentRenderTargetX);
}
}
}
void ClearDdraw();
void BeforeResetDevice();
void AfterResetDevice();
void ReleaseAllStateBlocks();
};