mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-02-20 20:41:10 +01:00
feat: Add bt d3d9 hook specific imgui overlay (#318)
For now, we focus on internal overlays for bemanitools that hook into an existing d3d9 context. The current abstraction is fairly thin and should be fine as a start. Implementations are called “components” and hook up with a single frame_update function to execute and logic and drawing updates with imgui
This commit is contained in:
parent
a85ce4bc96
commit
3090b9a029
@ -161,6 +161,7 @@ include src/main/iidxio-ezusb2/Module.mk
|
||||
include src/main/iidxio/Module.mk
|
||||
include src/main/iidxiotest/Module.mk
|
||||
include src/main/imgui/Module.mk
|
||||
include src/main/imgui-bt/Module.mk
|
||||
include src/main/inject/Module.mk
|
||||
include src/main/jbio-magicbox/Module.mk
|
||||
include src/main/jbio-p4io/Module.mk
|
||||
|
10
src/main/imgui-bt/Module.mk
Normal file
10
src/main/imgui-bt/Module.mk
Normal file
@ -0,0 +1,10 @@
|
||||
libs += imgui-bt
|
||||
|
||||
libs_imgui-bt := \
|
||||
hook \
|
||||
hooklib \
|
||||
util \
|
||||
imgui \
|
||||
|
||||
src_imgui-bt := \
|
||||
imgui-d3d9-hook.c \
|
10
src/main/imgui-bt/cimgui.h
Normal file
10
src/main/imgui-bt/cimgui.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef IMGUI_BT_CIMGUI_H
|
||||
#define IMGUI_BT_CIMGUI_H
|
||||
|
||||
// Comprehensive header file for including cimgui correctly for integration in this project
|
||||
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
|
||||
#include "imgui/cimgui.h"
|
||||
#include "imgui/cimgui_impl_dx9.h"
|
||||
#include "imgui/cimgui_impl_win32.h"
|
||||
|
||||
#endif
|
12
src/main/imgui-bt/component.h
Normal file
12
src/main/imgui-bt/component.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef IMGUI_BT_COMPONENT_H
|
||||
#define IMGUI_BT_COMPONENT_H
|
||||
|
||||
#include "imgui-bt/cimgui.h"
|
||||
|
||||
typedef void (*imgui_bt_component_frame_update_t)(ImGuiContext *ctx);
|
||||
|
||||
typedef struct imgui_bt_component {
|
||||
imgui_bt_component_frame_update_t frame_update;
|
||||
} imgui_bt_component_t;
|
||||
|
||||
#endif
|
143
src/main/imgui-bt/imgui-d3d9-hook.c
Normal file
143
src/main/imgui-bt/imgui-d3d9-hook.c
Normal file
@ -0,0 +1,143 @@
|
||||
#define LOG_MODULE "imgui-d3d9-hook"
|
||||
|
||||
#include "hook/d3d9.h"
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "imgui-bt/cimgui.h"
|
||||
#include "imgui-bt/component.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/mem.h"
|
||||
|
||||
typedef LRESULT WINAPI (*RegisterClassA_t)(WNDCLASSA *lpwcx);
|
||||
typedef LRESULT WINAPI (*WndProc_t)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
static LRESULT WINAPI _imgui_d3d9_hook_RegisterClassA(WNDCLASSA *lpwcx);
|
||||
|
||||
static bool _imgui_d3d9_hook_initialized;
|
||||
static ImGuiContext *_imgui_d3d9_hook_imgui_ctx;
|
||||
static RegisterClassA_t _imgui_d3d9_hook_original_RegisterClassA;
|
||||
static WndProc_t _imgui_d3d9_hook_original_wndproc;
|
||||
static imgui_bt_component_t *_imgui_d3d9_hook_components;
|
||||
static size_t _imgui_d3d9_hook_component_count;
|
||||
|
||||
static const struct hook_symbol _imgui_d3d9_hook_syms[] = {
|
||||
{.name = "RegisterClassA",
|
||||
.patch = _imgui_d3d9_hook_RegisterClassA,
|
||||
.link = (void **) &_imgui_d3d9_hook_original_RegisterClassA},
|
||||
};
|
||||
|
||||
CIMGUI_API LRESULT igImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
static LRESULT WINAPI _imgui_d3d9_hook_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LRESULT result;
|
||||
|
||||
result = igImplWin32_WndProcHandler(hWnd, msg, wParam, lParam);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return _imgui_d3d9_hook_original_wndproc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static LRESULT WINAPI _imgui_d3d9_hook_RegisterClassA(WNDCLASSA *lpwcx)
|
||||
{
|
||||
log_info("Swapping out WndProc handler for wrapper handler in RegisterClassA %s", lpwcx->lpszClassName);
|
||||
|
||||
_imgui_d3d9_hook_original_wndproc = lpwcx->lpfnWndProc;
|
||||
lpwcx->lpfnWndProc = _imgui_d3d9_hook_WndProc;
|
||||
|
||||
return _imgui_d3d9_hook_original_RegisterClassA(lpwcx);
|
||||
}
|
||||
|
||||
void imgui_d3d9_hook_init(const imgui_bt_component_t *components, size_t component_count)
|
||||
{
|
||||
ImGuiIO *io;
|
||||
ImGuiStyle* style;
|
||||
|
||||
log_assert(components);
|
||||
log_assert(component_count > 0);
|
||||
|
||||
_imgui_d3d9_hook_components = (imgui_bt_component_t *) xmalloc(component_count * sizeof(imgui_bt_component_t));
|
||||
memcpy(_imgui_d3d9_hook_components, components, component_count * sizeof(imgui_bt_component_t));
|
||||
_imgui_d3d9_hook_component_count = component_count;
|
||||
|
||||
_imgui_d3d9_hook_imgui_ctx = igCreateContext(NULL);
|
||||
io = igGetIO();
|
||||
|
||||
io->ConfigFlags = ImGuiConfigFlags_NavEnableKeyboard
|
||||
| ImGuiConfigFlags_DockingEnable
|
||||
| ImGuiConfigFlags_ViewportsEnable;
|
||||
|
||||
io->MouseDrawCursor = true;
|
||||
io->IniFilename = NULL;
|
||||
io->FontAllowUserScaling = true;
|
||||
|
||||
hook_table_apply(NULL, "user32.dll", _imgui_d3d9_hook_syms, lengthof(_imgui_d3d9_hook_syms));
|
||||
|
||||
// Setup style
|
||||
style = igGetStyle();
|
||||
style->Colors[ImGuiCol_WindowBg] = (ImVec4){0.0f, 0.0f, 0.0f, 1.0f};
|
||||
style->Colors[ImGuiCol_PlotLines] = (ImVec4){1.0f, 1.0f, 0.0f, 1.0f};
|
||||
|
||||
_imgui_d3d9_hook_initialized = true;
|
||||
}
|
||||
|
||||
void imgui_d3d9_hook_fini()
|
||||
{
|
||||
hook_table_revert(NULL, "user32.dll", _imgui_d3d9_hook_syms, lengthof(_imgui_d3d9_hook_syms));
|
||||
|
||||
igImplDX9_Shutdown();
|
||||
igImplWin32_Shutdown();
|
||||
igDestroyContext(NULL);
|
||||
|
||||
_imgui_d3d9_hook_initialized = false;
|
||||
}
|
||||
|
||||
HRESULT imgui_hook_d3d9_irp_handler(struct hook_d3d9_irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
log_assert(irp);
|
||||
|
||||
if (!_imgui_d3d9_hook_initialized) {
|
||||
return hook_d3d9_irp_invoke_next(irp);
|
||||
}
|
||||
|
||||
switch (irp->op) {
|
||||
case HOOK_D3D9_IRP_OP_CTX_CREATE_DEVICE:
|
||||
hr = hook_d3d9_irp_invoke_next(irp);
|
||||
|
||||
if (hr == S_OK) {
|
||||
igImplWin32_Init(irp->args.ctx_create_device.hwnd);
|
||||
igImplDX9_Init(*irp->args.ctx_create_device.pdev);
|
||||
}
|
||||
|
||||
return hr;
|
||||
|
||||
case HOOK_D3D9_IRP_OP_DEV_BEGIN_SCENE:
|
||||
igImplDX9_NewFrame();
|
||||
igImplWin32_NewFrame();
|
||||
igNewFrame();
|
||||
|
||||
for (size_t i = 0; i < _imgui_d3d9_hook_component_count; i++) {
|
||||
_imgui_d3d9_hook_components[i].frame_update(_imgui_d3d9_hook_imgui_ctx);
|
||||
}
|
||||
|
||||
return hook_d3d9_irp_invoke_next(irp);
|
||||
|
||||
case HOOK_D3D9_IRP_OP_DEV_END_SCENE:
|
||||
igRender();
|
||||
igImplDX9_RenderDrawData(igGetDrawData());
|
||||
|
||||
return hook_d3d9_irp_invoke_next(irp);
|
||||
|
||||
default:
|
||||
return hook_d3d9_irp_invoke_next(irp);
|
||||
}
|
||||
|
||||
log_fatal("Illegal state");
|
||||
}
|
13
src/main/imgui-bt/imgui-d3d9-hook.h
Normal file
13
src/main/imgui-bt/imgui-d3d9-hook.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef IMGUI_D3D9_HOOK_H
|
||||
#define IMGUI_D3D9_HOOK_H
|
||||
|
||||
#include "hook/d3d9.h"
|
||||
|
||||
#include "imgui-bt/component.h"
|
||||
|
||||
void imgui_d3d9_hook_init(const imgui_bt_component_t *components, size_t component_count);
|
||||
void imgui_d3d9_hook_fini();
|
||||
|
||||
HRESULT imgui_hook_d3d9_irp_handler(struct hook_d3d9_irp *irp);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user