-
Notifications
You must be signed in to change notification settings - Fork 5
/
DX9Manager.cpp
189 lines (159 loc) · 7.64 KB
/
DX9Manager.cpp
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
#include "DX9Manager.h"
namespace JungleTime{
DX9Manager* DX9Manager::singleton = NULL;
//Original funcs to call after hook
DX9Manager::DX9Manager(void):
isInitiated(false), isFirstFrame(false), isFirstInitiatedFrame(false),
statusFont(0), isDeviceReady(true), statusText(L"JT2 init..."), isRenderStatus(true), isReadyToRender(false){
LOG_DEBUG_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"Init", L"starting...");
if(singleton)
LOG_ERROR_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"Init", L"dude... you are idiot, we cant create more singletons >:(");
singleton = this;
SetRect(&statusRect, 20, 20, 100, 100);
hDXHookThread = (HANDLE)_beginthreadex(NULL, 0, DX9Manager::MainHookDX9, NULL, 0, NULL);
LOG_VERBOSE_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"Init", L"done");
}
DX9Manager::~DX9Manager(void){
LOG_DEBUG_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"Close", L"unloading...");
//Unhook functions
typedef UINT (WINAPI* D3D9DeviceFuncUnHookFunc)(UINT funcId);
D3D9DeviceFuncUnHookFunc D3D9DeviceFuncUnHook = (D3D9DeviceFuncUnHookFunc)GetProcAddress(GetModuleHandle(L"d3d9.dll"), "D3D9DeviceFuncUnHook");
if(!D3D9DeviceFuncUnHook){
LOG_VERBOSE_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"Close", L"cannot find D3D9DeviceFuncUnHook function in the d3d9.dll! Maybe broken D3D9 Proxy?");
MessageBox(NULL, L"JT2 Lib Error", L"Cannot load special functions. You need to use special d3d9.dll proxy library!", MB_OK | MB_ICONERROR);
return;
}
D3D9DeviceFuncUnHook(ENDSCENE);
D3D9DeviceFuncUnHook(PRERESET);
D3D9DeviceFuncUnHook(POSTRESET);
//Release resources only if application loop is alive, we dont need to freeze application in the process list
if(!IS_DX_LOOP_DEAD)
singleton->statusFont->Release();
CloseHandle(hDXHookThread);
LOG_VERBOSE_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"Close", L"unloaded");
}
void DX9Manager::HookEndScene(LPDIRECT3DDEVICE9 pDevice){
//I prefer to check it each time
HRESULT r = pDevice->TestCooperativeLevel();
if(r == D3DERR_DEVICELOST){
singleton->isDeviceReady = false;
//Ok, lost, now we can free our old resources
LOG_WARNING_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"HookEndScene", L"device is LOST!");
Sleep(500); //Wait a bit so we don't burn through cycles for no reason (c) http://www.drunkenhyena.com/cgi-bin/view_cpp_article.pl?chapter=2;article=10
return;
}else if(r == D3DERR_DEVICENOTRESET){
singleton->isDeviceReady = false;
LOG_WARNING_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"HookEndScene", L"device can be resetted, waiting for the main app Device->Reset call");
return;
}else if(r != D3D_OK){
LOG_WARNING_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"HookEndScene", L"unknown state of device, skip renderring");
Sleep(500); //Wait a bit so we don't burn through cycles for no reason (c) http://www.drunkenhyena.com/cgi-bin/view_cpp_article.pl?chapter=2;article=10
return;
}
//If device wasnt ready for this moment - we have nothing to do
if(!singleton->isDeviceReady)
return;
//At first frame, we need to init every dx thing from this back-end class
if(!singleton->isFirstFrame){
LOG_DEBUG_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"OnFirstFrame", L"first frame catched");
singleton->d3d9Device = pDevice;
HRESULT res = D3DXCreateFont(pDevice, 15, 0, FW_BOLD, 1, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Verdana", &singleton->statusFont);
if(res != S_OK){
LOG_ERROR_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"OnFirstFrame", L"cannot create resources");
return;
}
singleton->isFirstFrame = true;
}
if(singleton->isRenderStatus)
singleton->statusFont->DrawText(NULL, singleton->statusText.c_str(), -1, &singleton->statusRect, DT_CENTER|DT_NOCLIP, 0xFFFFFFFF);
//Touch event...
//A bit optimization. If isReadyToRender flag is true, it means all initiation was done and we can skip other checks
if(singleton->isReadyToRender){
singleton->OnDXEndScene(pDevice);
return;
}
if(singleton->isInitiated){
//First frame after initiation of the real application is complete
if(!singleton->isFirstInitiatedFrame){
LOG_DEBUG_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"OnFirstFrame", L"first initiated app frame catched");
singleton->isReadyToRender = singleton->OnDXFirstFrame(pDevice);
singleton->isFirstInitiatedFrame = true;
}
}
}
void DX9Manager::HookPreReset(){
singleton->statusFont->OnLostDevice();
singleton->OnDXLostDevice();
LOG_VERBOSE_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"HookReset", L"all resources are unloaded");
singleton->isDeviceReady = false;
}
void DX9Manager::HookPostReset(LPDIRECT3DDEVICE9 pDevice, HRESULT res){
if(!SUCCEEDED(res)){
LOG_DEBUG_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"HookPostReset", L"unsuccessfull reset of device");
return;
}
LOG_DEBUG_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"HookPostReset", L"successfull reset of device");
singleton->statusFont->OnResetDevice();
singleton->OnDXResetDevice(pDevice);
LOG_VERBOSE_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"HookPostReset", L"all resources are ready");
singleton->isDeviceReady = true;
}
unsigned int WINAPI DX9Manager::MainHookDX9(void *param){
//Waiting for d3d lib is loaded
LOG_VERBOSE_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"MainThread", L"waiting for the lib");
while(GetModuleHandle(L"d3d9.dll")==NULL)
Sleep(250);
LOG_VERBOSE_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"MainThread", L"d3d9.dll detected");
//Load library(assuming it's our proxy d3d9 lib) and functions to hook end scene.
typedef UINT (WINAPI* D3D9DeviceFuncHookFunc)(UINT funcId, void* funcRef);
D3D9DeviceFuncHookFunc D3D9DeviceFuncHook = (D3D9DeviceFuncHookFunc)GetProcAddress(GetModuleHandle(L"d3d9.dll"), "D3D9DeviceFuncHook");
if(!D3D9DeviceFuncHook){
LOG_ERROR_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"MainThread", L"cannot find D3D9DeviceFuncHook function in the d3d9.dll! Maybe broken D3D9 Proxy?");
MessageBox(NULL, L"JT2 Lib Error", L"Cannot load special functions. You need to use special d3d9.dll proxy library!", MB_OK | MB_ICONERROR);
return 0;
}
//Trying to hook
LOG_VERBOSE_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"MainThread", L"waiting for the dx proxy load and hooking things");
UINT res = NULL;
do{
Sleep(250);
res = D3D9DeviceFuncHook(ENDSCENE, &HookEndScene);
}while (!res);
do{
Sleep(250);
res = D3D9DeviceFuncHook(PRERESET, &HookPreReset);
}while (!res);
do{
Sleep(250);
res = D3D9DeviceFuncHook(POSTRESET, &HookPostReset);
}while (!res);
LOG_VERBOSE_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"MainThread", L"hooking is done");
//Touch our event...
singleton->isInitiated = singleton->OnDXInitiated();
LOG_VERBOSE_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"MainThread", L"thread work is done");
return 0;
}
void DX9Manager::SetStatusText(wstring txt){
statusText = txt;
}
void DX9Manager::SetStatusIsRender(bool isRender){
isRenderStatus = isRender;
}
bool DX9Manager::OnDXFirstFrame(LPDIRECT3DDEVICE9 pDevice){
LOG_WARNING_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"OnDXFirstFrame", L"event unhooked!");
return false;
}
bool DX9Manager::OnDXInitiated(void){
LOG_WARNING_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"OnDXInitiated", L"event unhooked!");
return false;
}
void DX9Manager::OnDXEndScene(LPDIRECT3DDEVICE9 pDevice){
LOG_WARNING_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"OnDXEndScene", L"event unhooked!");
}
void DX9Manager::OnDXResetDevice(LPDIRECT3DDEVICE9 pDevice){
LOG_WARNING_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"OnDXResetDevice", L"event unhooked!");
}
void DX9Manager::OnDXLostDevice(){
LOG_WARNING_MF(L"DX9Manager.cpp", 0, L"DirectX9Manager", L"OnDXLostDevice", L"event unhooked!");
}
}