-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRenderer.cpp
223 lines (161 loc) · 7.05 KB
/
Renderer.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
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
#include "Renderer.h"
// ImGui窗口处理函数
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
namespace Renderer {
// 全局变量
WNDPROC originalWndProc = nullptr; // 游戏本身的窗口处理函数
// Hooks
InlineHook* resetHook = nullptr;
InlineHook* presentHook = nullptr;
void initImGui(HWND hwnd, IDirect3DDevice9* device) {
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
// 不生成配置文件
io.IniFilename = nullptr;
io.LogFilename = nullptr;
io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
ImGui::StyleColorsLight();
// 字体(第一个添加的是默认字体)
char buffer[1024];
RtlZeroMemory(buffer, 1024);
strcpy(buffer, Client::clientAssetsPath.c_str());
strcat(buffer, "font\\SYFont.ttf");
Client::defaultFont = io.Fonts->AddFontFromFileTTF(buffer, 13, nullptr, io.Fonts->GetGlyphRangesChineseFull());
RtlZeroMemory(buffer, 1024);
strcpy(buffer, Client::clientAssetsPath.c_str());
strcat(buffer, "font\\HanabiFont.ttf");
Client::hanabiFont = io.Fonts->AddFontFromFileTTF(buffer, 17.5f, nullptr);
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX9_Init(device);
}
bool hookDx9(HWND hwnd) {
// 创建D3D
IDirect3D9* direct3D9 = Direct3DCreate9(D3D_SDK_VERSION);
if (direct3D9 == nullptr) {
MessageBoxA(nullptr, "Direct3DCreate9 failed.", "Error:", MB_OK | MB_ICONERROR);
return false;
}
D3DPRESENT_PARAMETERS info;
memset(&info, 0, sizeof(info));
info.Windowed = true;
info.SwapEffect = D3DSWAPEFFECT_COPY;
// 创建设备,为了拿函数地址并Hook
IDirect3DDevice9* direct3DDevice9 = nullptr;
direct3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &info, &direct3DDevice9);
if (direct3DDevice9 == nullptr) {
MessageBoxA(nullptr, "CreateDevice failed.", "Error:", MB_OK | MB_ICONERROR);
return false;
}
// Hook Direct3D
DWORD* direct3DDeviceTable = (DWORD*)*(DWORD*)direct3DDevice9;
resetHook = new InlineHook(direct3DDeviceTable[16], reinterpret_cast<DWORD> (Hook_Reset));
presentHook = new InlineHook(direct3DDeviceTable[17], reinterpret_cast<DWORD> (Hook_Present));
resetHook->MotifyASM();
presentHook->MotifyASM();
// 销毁设备,因为拿到地址了
direct3D9->Release();
direct3DDevice9->Release();
return true;
}
bool startRenderer(HWND hwnd) {
bool res = true;
res = hookDx9(hwnd);
return res;
}
// Simple helper function to load an image into a DX9 texture with common settings
bool loadTextureFromFile(IDirect3DDevice9* device, const char* filename, Picture* pic) {
// Load texture from disk
PDIRECT3DTEXTURE9 texture;
HRESULT hr = D3DXCreateTextureFromFileA(device, filename, &texture);
if (hr != S_OK)
return false;
// Retrieve description of the texture surface so we can access its size
D3DSURFACE_DESC my_image_desc;
texture->GetLevelDesc(0, &my_image_desc);
pic->texture = texture;
pic->width = (int)my_image_desc.Width;
pic->height = (int)my_image_desc.Height;
return true;
}
bool isBlockHovered(Block* block) {
return Client::rendererIO->MousePos.x > block->x &&
Client::rendererIO->MousePos.y > block->y &&
Client::rendererIO->MousePos.x < (block->x + block->width) &&
Client::rendererIO->MousePos.y < (block->y + block->height);
}
void drawBlockBoundingBox(Block* block) {
ImGui::GetForegroundDrawList()->AddRect(ImVec2(block->x, block->y), ImVec2(block->x + block->width, block->y + block->height), IM_COL32(255, 0, 0, 230));
}
bool isBlockClicked(Block* block) {
if (isBlockHovered(block)) {
return ImGui::IsMouseClicked(0);
}
return false;
}
bool isBlockInAnotherBlock(Block* subBlock, Block* superBlock) {
int x1 = subBlock->x + subBlock->width;
int y1 = subBlock->y + subBlock->height;
return subBlock->x > superBlock->x &&
subBlock->y > superBlock->y &&
subBlock->x < (superBlock->x + superBlock->width) &&
subBlock->y < (superBlock->y + superBlock->height) &&
x1 > superBlock->x &&
y1 > superBlock->y &&
x1 < (superBlock->x + superBlock->width) &&
y1 < (superBlock->y + superBlock->height);
}
void addBlockBoundingBox(Block* subBlock, int xInc, int yInc, int wInc, int hInc) {
subBlock->x -= xInc;
subBlock->y -= yInc;
subBlock->width += xInc + wInc;
subBlock->height += yInc + hInc;
}
// Hooked function implements
HRESULT WINAPI Hook_Reset(IDirect3DDevice9* direct3DDevice9, D3DPRESENT_PARAMETERS* pPresentationParameters) {
resetHook->ResetASM();
// 废除设备对象
ImGui_ImplDX9_InvalidateDeviceObjects();
HRESULT res = direct3DDevice9->Reset(pPresentationParameters);
// 重新创建设备对象
ImGui_ImplDX9_CreateDeviceObjects();
resetHook->MotifyASM();
return res;
}
HRESULT WINAPI Hook_Present(IDirect3DDevice9* direct3DDevice9, RECT* pSourceRect, RECT* pDestRect, HWND hDestWindowOverride, RGNDATA* pDirtyRegion) {
presentHook->ResetASM();
static bool called = false;
if (!called) {
called = true;
// 初始化ImGui
initImGui(Client::wndGame, direct3DDevice9);
// 接管窗口消息
Renderer::originalWndProc = reinterpret_cast<WNDPROC> (SetWindowLongA(Client::wndGame, GWL_WNDPROC, reinterpret_cast<long> (SelfWndProc)));
// 初始化RendererIO
Client::rendererIO = &(ImGui::GetIO());
// 初始化Textures
Client::loadTextures(direct3DDevice9);
}
// 绘制
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
EventManager::getInstance().call(Events::EventKeyDown);
EventManager::getInstance().call(Events::EventUpdateData);
EventManager::getInstance().call(Events::EventUpdate);
EventManager::getInstance().call(Events::EventRenderOverlay);
ImGui::EndFrame();
ImGui::Render();
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
HRESULT res = direct3DDevice9->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
presentHook->MotifyASM();
// 调用原来的
return res;
}
LRESULT CALLBACK SelfWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
// ImGui接管窗口处理
if (ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam)) return true;
// 调用原先的窗口处理
return CallWindowProcA(Renderer::originalWndProc, hWnd, uMsg, wParam, lParam);
}
}