mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-02-26 22:49:28 +01:00
feat: Add bt d3d9 hook specific imgui overlay
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
ce1a004bf6
commit
95f792f655
@ -159,6 +159,8 @@ include src/main/iidxio-ezusb/Module.mk
|
||||
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