Files
korenkonder_AFTMods/src/DivaGL/hook.cpp
T
2025-04-21 03:06:03 +03:00

435 lines
14 KiB
C++

/*
by korenkonder
GitHub/GitLab: korenkonder
*/
#include "hook.hpp"
#include "Glitter/glitter.hpp"
#include "data_test/rob_osage_test.hpp"
#include "graphics/color_change_dw.hpp"
#include "mdl/disp_manager.hpp"
#include "pv_game/pv_game.hpp"
#include "rob/rob.hpp"
#include "auth_3d.hpp"
#include "camera.hpp"
#include "effect.hpp"
#include "light_param.hpp"
#include "object.hpp"
#include "print.hpp"
#include "resource.h"
#include "render_manager.hpp"
#include "render_texture.hpp"
#include "shader_ft.hpp"
#include "sprite.hpp"
#include "stage.hpp"
#include "texture.hpp"
#include <Helpers.h>
static HGLRC FASTCALL glut_create_context(int64_t a1, int64_t a2, int64_t a3, int64_t a4, int32_t a5);
#ifdef DEBUG
static void APIENTRY gl_debug_output(GLenum source, GLenum type, uint32_t id,
GLenum severity, GLsizei length, const char* message, const void* userParam);
#endif
HOOK(int32_t, FASTCALL, data_init, 0x0000000140192FF0) {
#ifdef DEBUG
if (GL_VERSION_4_3) {
typedef void (APIENTRY* GLDEBUGPROC)(GLenum source, GLenum type, GLuint id,
GLenum severity, GLsizei length, const GLchar* message, const void* userParam);
typedef void (GLAPIENTRY* PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void* userParam);
PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback
= (PFNGLDEBUGMESSAGECALLBACKPROC)wglGetProcAddressDLL("glDebugMessageCallback");
typedef void (GLAPIENTRY* PFNGLDEBUGMESSAGECONTROLPROC)(GLenum source,
GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl
= (PFNGLDEBUGMESSAGECONTROLPROC)wglGetProcAddressDLL("glDebugMessageControl");
glEnableDLL(GL_DEBUG_OUTPUT);
glEnableDLL(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(gl_debug_output, 0);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE);
}
#endif
sprite_shared_init();
auth_3d_patch();
camera_patch();
color_change_dw_patch();
mdl::disp_manager_patch();
effect_patch();
light_param_patch();
object_patch();
pv_game_patch();
render_manager_patch();
render_texture_patch();
rob_patch();
shadow_patch();
sprite_patch();
stage_patch();
texture_patch();
Glitter::Patch();
rctx = new render_context;
reflect_full_init();
int32_t ret = originaldata_init();
extern size_t diva_handle;
diva_handle = (size_t)WindowFromDC(wglGetCurrentDC());
rctx->init();
Glitter::Init();
sprite_manager_init();
pv_game_init();
color_change_dw_init();
rob_osage_test_init();
return ret;
}
HOOK(int32_t, FASTCALL, data_free, 0x000000140192490) {
rob_osage_test_free();
color_change_dw_free();
pv_game_free();
sprite_manager_free();
Glitter::Free();
rctx->free();
int32_t ret = originaldata_free();
reflect_full_free();
delete rctx;
rctx = 0;
return ret;
}
HOOK(void, FASTCALL, sub_140194CD0, 0x000000140194CD0) {
rctx->ctrl();
originalsub_140194CD0();
}
HOOK(void, FASTCALL, _gl_state_get, 0x0000000140442DF0) {
gl_state_get();
}
HOOK(void, FASTCALL, rndr__Render__update_res, 0x00000001404A9480, rndr::Render* rend, bool set, int32_t base_downsample) {
rend->update_res(set, base_downsample);
}
HOOK(void, FASTCALL, rndr__Render__take_ss, 0x00000001404A9CD0,
rndr::Render* rend, texture* tex, bool vertical, float_t horizontal_offset) {
rend->take_ss(tex, vertical, horizontal_offset);
}
HOOK(void, FASTCALL, rndr__Render__init_tone_map_buffers, 0x00000001404A9FF0, rndr::Render* rend) {
rend->init_tone_map_buffers();
}
HOOK(void, FASTCALL, rndr__Render__init_render_buffers, 0x00000001404AB0C0, rndr::Render* rend,
int32_t width, int32_t height, int32_t ssaa, int32_t hd_res, int32_t ss_alpha_mask) {
rend->init_render_buffers(width, height, ssaa, hd_res, ss_alpha_mask);
}
HOOK(void, FASTCALL, rndr__Render__free, 0x00000001404AB900, rndr::Render* rend) {
rend->free();
}
HOOK(void, FASTCALL, rndr__Render__render_texture_set, 0x00000001404B1560,
rndr::Render* rend, texture* render_texture, bool task_photo) {
rend->render_texture_set(render_texture, task_photo);
}
HOOK(void, FASTCALL, rndr__Render__movie_texture_set, 0x00000001404B16A0,
rndr::Render* rend, texture* movie_texture) {
rend->movie_texture_set(movie_texture);
}
HOOK(void, FASTCALL, rndr__Render__render_texture_free, 0x00000001404B1880,
rndr::Render* rend, texture* render_texture, bool task_photo) {
rend->render_texture_free(render_texture, task_photo);
}
HOOK(void, FASTCALL, rndr__Render__movie_texture_free, 0x00000001404B18F0,
rndr::Render* rend, texture* movie_texture) {
rend->movie_texture_free(movie_texture);
}
HOOK(void, FASTCALL, rndr__RenderManager__rndpass_pre_proc, 0x0000000140502C90) {
gl_state_begin_event("rndpass_pre_proc");
render_manager.render->pre_proc();
Glitter::glt_particle_manager->CalcDisp();
Glitter::glt_particle_manager_x->CalcDisp();
rctx->pre_proc();
gl_state_end_event();
}
HOOK(void, FASTCALL, rndr__RenderManager__render_all, 0x0000000140502CA0) {
render_manager.render_all();
}
HOOK(void, FASTCALL, rndr__RenderManager__rndpass_post_proc, 0x0000000140502C70) {
gl_state_begin_event("rndpass_post_proc");
rctx->post_proc();
render_manager.render->post_proc();
render_manager.field_31C = false;
gl_state_end_event();
}
struct ScreenShotData {
prj::string path;
int32_t format;
bool screen_shot_4x;
int32_t width;
int32_t height;
GLuint buffer;
const void* tex_data;
};
struct ScreenShotImpl {
void* __vftable;
prj::string path;
int32_t format;
bool screen_shot_4x;
int32_t width;
int32_t height;
int32_t curr_width;
int32_t curr_height;
bool capture;
texture* tex;
GLuint data_buffers[2];
ScreenShotData ss_data[2];
int32_t data_buffer_index;
void* thread; // Thrd_t
};
HOOK(void, FASTCALL, shader_free, 0x00000001405E4DB0) {
shaders_ft.unload();
}
HOOK(void, FASTCALL, shader_load_all_shaders, 0x00000001405E4FC0) {
extern size_t dll_handle;
HRSRC res = FindResourceA((HMODULE)dll_handle, MAKEINTRESOURCEA(IDR_FT_SHADERS_FARC1), "ft_shaders_farc");
if (res) {
DWORD size = SizeofResource((HMODULE)dll_handle, res);
HGLOBAL data = LoadResource((HMODULE)dll_handle, res);
farc f;
f.read(data, size, true);
shaders_ft.load(&f, false, "ft", shader_ft_table, shader_ft_table_size,
shader_ft_bind_func_table, shader_ft_bind_func_table_size,
shader_ft_get_index_by_name);
}
}
HOOK(int32_t, FASTCALL, shader_get_index_by_name, 0x00000001405E4ED0, const char* name) {
return shaders_ft.get_index_by_name(name);
}
HOOK(void, FASTCALL, env_set_blend_color, 0x00000001405E5600, float_t r, float_t g, float_t b, float_t a) {
rctx->set_batch_blend_color({ r, g, b, a });
}
HOOK(void, FASTCALL, env_set_offset_color, 0x00000001405E5630, float_t r, float_t g, float_t b, float_t a) {
rctx->set_batch_offset_color({ r, g, b, a });
}
HOOK(void, FASTCALL, set_render_defaults, 0x00000001401948B0) {
glClearDepthDLL(1.0);
glClearStencilDLL(0);
//glShadeModelDLL(GL_SMOOTH);
glPolygonModeDLL(GL_FRONT_AND_BACK, GL_FILL);
glDisableDLL(GL_MULTISAMPLE);
glDisableDLL(GL_DITHER);
glEnableDLL(GL_DEPTH_TEST);
glDepthFuncDLL(GL_LEQUAL);
glEnableDLL(GL_CULL_FACE);
glFrontFaceDLL(GL_CCW);
glCullFaceDLL(GL_BACK);
//glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_ZERO);
//glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FIXED_ONLY_ARB);
//glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FIXED_ONLY_ARB);
glPixelStoreiDLL(GL_UNPACK_ALIGNMENT, 1);
}
HOOK(GLenum, FASTCALL, gl_check_framebuffer_status, 0x0000000140503240) {
GLenum ret = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (ret != GL_FRAMEBUFFER_COMPLETE)
return ret;
return GL_FRAMEBUFFER_COMPLETE;
}
void hook_funcs() {
WRITE_NOP_5(0x0000000140441290);
WRITE_JUMP(0x00000001404412E2, 0x00000001404413BD);
WRITE_NOP(0x00000001404412E7, 0xD6);
INSTALL_HOOK(data_init);
INSTALL_HOOK(data_free);
INSTALL_HOOK(sub_140194CD0);
INSTALL_HOOK(_gl_state_get);
INSTALL_HOOK(rndr__Render__update_res);
INSTALL_HOOK(rndr__Render__take_ss);
INSTALL_HOOK(rndr__Render__init_tone_map_buffers);
INSTALL_HOOK(rndr__Render__init_render_buffers);
INSTALL_HOOK(rndr__Render__free);
INSTALL_HOOK(rndr__Render__render_texture_set);
INSTALL_HOOK(rndr__Render__movie_texture_set);
INSTALL_HOOK(rndr__Render__render_texture_free);
INSTALL_HOOK(rndr__Render__movie_texture_free);
INSTALL_HOOK(rndr__RenderManager__rndpass_pre_proc);
INSTALL_HOOK(rndr__RenderManager__render_all);
INSTALL_HOOK(rndr__RenderManager__rndpass_post_proc);
INSTALL_HOOK(shader_free);
INSTALL_HOOK(shader_load_all_shaders);
INSTALL_HOOK(shader_get_index_by_name);
INSTALL_HOOK(env_set_blend_color);
INSTALL_HOOK(env_set_offset_color);
INSTALL_HOOK(set_render_defaults);
INSTALL_HOOK(gl_check_framebuffer_status);
uint8_t buf[0x0C] = {};
buf[0x00] = 0x48; // mov rax, 0
buf[0x01] = 0xB8;
buf[0x0A] = 0xFF; // jmp rax
buf[0x0B] = 0xE0;
*(uint64_t*)&buf[0x02] = (uint64_t)&printf_proxy;
WRITE_MEMORY_STRING(0x00000001401D3860, buf, 0x0C);
*(uint64_t*)&buf[0x02] = (uint64_t)&printf_proxy;
WRITE_MEMORY_STRING(0x00000001400DE640, buf, 0x0C);
*(uint64_t*)&buf[0x02] = (uint64_t)&gl_state_get;
WRITE_MEMORY_STRING(0x0000000140442FB4, buf, 0x0C);
extern size_t glut_handle;
*(uint64_t*)&buf[0x02] = (uint64_t)&glut_create_context;
WRITE_MEMORY_STRING(glut_handle + 0x0000A970, buf, 0x0C);
}
static HGLRC FASTCALL glut_create_context(int64_t a1, int64_t a2, int64_t a3, int64_t a4, int32_t a5) {
extern size_t glut_handle;
HDC& XHDC = *(HDC*)(glut_handle + 0x55F20);
if (true/*a5*/) {
typedef HGLRC(GLAPIENTRY* PFNWGLCREATECONTEXTGLUTPROC)(HDC hDc);
HGLRC tmp_ctx = wglCreateContextGLUT(XHDC);;
wglMakeCurrentGLUT(XHDC, tmp_ctx);
PFNWGLCREATECONTEXTATTRIBSARBPROC _wglCreateContextAttribsARB
= (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddressGLUT("wglCreateContextAttribsARB");
int32_t minor = 6;
HGLRC ctx = 0;
while (!ctx && minor >= 1) {
const int32_t attrib_list[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, minor,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
#ifdef DEBUG
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | WGL_CONTEXT_DEBUG_BIT_ARB,
#else
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
#endif
0,
};
ctx = _wglCreateContextAttribsARB(XHDC, 0, attrib_list);;
minor--;
}
wglMakeCurrentGLUT(XHDC, ctx);
wglDeleteContextGLUT(tmp_ctx);
return ctx;
}
else
return wglCreateContextGLUT(XHDC);
}
#ifdef DEBUG
static void APIENTRY gl_debug_output(GLenum source, GLenum type, uint32_t id,
GLenum severity, GLsizei length, const char* message, const void* userParam) {
if (!id && severity == GL_DEBUG_SEVERITY_NOTIFICATION
|| id == 131169 || id == 131185 || id == 131218 || id == 131204)
return;
printf_divagl("########################################\n");
switch (type) {
case GL_DEBUG_TYPE_ERROR:
printf_divagl("Type: Error; ");
break;
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
printf_divagl("Type: Deprecated Behaviour; ");
break;
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
printf_divagl("Type: Undefined Behaviour; ");
break;
case GL_DEBUG_TYPE_PORTABILITY:
printf_divagl("Type: Portability; ");
break;
case GL_DEBUG_TYPE_PERFORMANCE:
printf_divagl("Type: Performance; ");
break;
case GL_DEBUG_TYPE_MARKER:
printf_divagl("Type: Marker; ");
break;
case GL_DEBUG_TYPE_PUSH_GROUP:
printf_divagl("Type: Push Group; ");
break;
case GL_DEBUG_TYPE_POP_GROUP:
printf_divagl("Type: Pop Group; ");
break;
case GL_DEBUG_TYPE_OTHER:
printf_divagl("Type: Other; ");
break;
}
switch (severity) {
case GL_DEBUG_SEVERITY_HIGH:
printf_divagl("Severity: high; ");
break;
case GL_DEBUG_SEVERITY_MEDIUM:
printf_divagl("Severity: medium; ");
break;
case GL_DEBUG_SEVERITY_LOW:
printf_divagl("Severity: low; ");
break;
case GL_DEBUG_SEVERITY_NOTIFICATION:
printf_divagl("Severity: notif; ");
break;
}
switch (source) {
case GL_DEBUG_SOURCE_API:
printf_divagl("Source: API\n");
break;
case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
printf_divagl("Source: Window System\n");
break;
case GL_DEBUG_SOURCE_SHADER_COMPILER:
printf_divagl("Source: Shader Compiler\n");
break;
case GL_DEBUG_SOURCE_THIRD_PARTY:
printf_divagl("Source: Third Party\n");
break;
case GL_DEBUG_SOURCE_APPLICATION:
printf_divagl("Source: Application\n");
break;
case GL_DEBUG_SOURCE_OTHER:
printf_divagl("Source: Other\n");
break;
}
printf_divagl("Debug message (%d): %s\n", id, message);
printf_divagl("########################################\n\n");
}
#endif