diff --git a/extern/src/Helpers.h b/extern/src/Helpers.h index 94d1192..a4de4fa 100644 --- a/extern/src/Helpers.h +++ b/extern/src/Helpers.h @@ -165,5 +165,10 @@ const HMODULE MODULE_HANDLE = GetModuleHandle(nullptr); VirtualProtect((void*)(location), (size_t)(count), oldProtect, &oldProtect); \ } +#define WRITE_RETURN(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0xC3); \ + } + #define COUNTOFARR(arr) \ sizeof(arr) / sizeof(arr[0]) diff --git a/src/DivaGL/hook.cpp b/src/DivaGL/hook.cpp index eeeec3d..a377439 100644 --- a/src/DivaGL/hook.cpp +++ b/src/DivaGL/hook.cpp @@ -20,6 +20,7 @@ #include "resource.h" #include "render_manager.hpp" #include "render_texture.hpp" +#include "screen_shot.hpp" #include "shader_ft.hpp" #include "sprite.hpp" #include "stage.hpp" @@ -77,6 +78,7 @@ HOOK(int32_t, FASTCALL, data_init, 0x0000000140192FF0) { render_manager_patch(); render_texture_patch(); rob_patch(); + screen_shot_patch(); shadow_patch(); sprite_patch(); stage_patch(); @@ -121,10 +123,6 @@ HOOK(void, FASTCALL, display_callback, 0x000000140194CD0) { rend_data_ctx.state.update(); } -HOOK(void, FASTCALL, gl_rend_state__get, 0x0000000140442DF0) { - -} - HOOK(void, FASTCALL, rndr__Render__update_res, 0x00000001404A9480, rndr::Render* rend, bool set, int32_t base_downsample) { rend->update_res(set, base_downsample); } @@ -303,14 +301,6 @@ HOOK(int32_t, FASTCALL, shader_get_index_by_name, 0x00000001405E4ED0, const char 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) { - -} - -HOOK(void, FASTCALL, env_set_offset_color, 0x00000001405E5630, float_t r, float_t g, float_t b, float_t a) { - -} - HOOK(void, FASTCALL, set_render_defaults, 0x00000001401948B0) { glClearDepthDLL(1.0); glClearStencilDLL(0); @@ -347,8 +337,6 @@ void hook_funcs() { INSTALL_HOOK(display_callback); - INSTALL_HOOK(gl_rend_state__get); - INSTALL_HOOK(rndr__Render__update_res); INSTALL_HOOK(rndr__Render__take_ss); INSTALL_HOOK(rndr__Render__init_post_process_buffers); @@ -369,9 +357,6 @@ void hook_funcs() { 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); @@ -391,6 +376,11 @@ void hook_funcs() { extern size_t glut_handle; *(uint64_t*)&buf[0x02] = (uint64_t)&glut_create_context; WRITE_MEMORY_STRING(glut_handle + 0x0000A970, buf, 0x0C); + + WRITE_RETURN(0x0000000140442DF0); // gl_rend_state::get + + WRITE_RETURN(0x00000001405E5600); // env_set_blend_color + WRITE_RETURN(0x00000001405E5630); // env_set_offset_color } static HGLRC FASTCALL glut_create_context(int64_t a1, int64_t a2, int64_t a3, int64_t a4, int32_t a5) { diff --git a/src/DivaGL/screen_shot.cpp b/src/DivaGL/screen_shot.cpp index 86df129..07f1bd9 100644 --- a/src/DivaGL/screen_shot.cpp +++ b/src/DivaGL/screen_shot.cpp @@ -8,6 +8,7 @@ #include "gl_state.hpp" #include "render_context.hpp" #include "shader_ft.hpp" +#include "sprite.hpp" #include "texture.hpp" #include @@ -75,6 +76,128 @@ HOOK(bool, FASTCALL, sub_1401898E0, 0x00000001401898E0, __int64 a1, texture* tex return true; } +HOOK(void*, FASTCALL, ScreenShotData__read_data, 0x0000000140557A70, ScreenShotData* data) { + const int32_t pixels = data->width * data->height; + if (pixels <= 0) + return 0; + + const int32_t size = (data->format == 2 ? 4 : 3) * pixels; + void* _data = malloc(size); + if (!_data) + return 0; + + uint8_t* d = (uint8_t*)_data; + glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer); + const uint8_t* s = (const uint8_t*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + switch (data->format) { + case 0: + case 4: + for (uint32_t i = pixels; i; i--) { + d[0] = s[2]; + d[1] = s[1]; + d[2] = s[0]; + d += 3; + s += 4; + } + break; + case 1: + case 3: + for (uint32_t i = pixels; i; i--) { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d += 3; + s += 4; + } + break; + case 2: + for (uint32_t i = pixels; i; i--) { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = s[3]; + d += 4; + s += 4; + } + break; + default: + free(_data); + _data = 0; + break; + } + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + return _data; +} + +HOOK(void, FASTCALL, ScreenShotData__get_data, 0x0000000140557BE0, ScreenShotData* data) { + if (!data->screen_shot_4x) { + glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer); + glReadPixelsDLL(0, 0, data->width, data->height, GL_BGRA, GL_UNSIGNED_BYTE, 0); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + gl_get_error_print(); + return; + } + + static void* (FASTCALL * sprite_manager_sub_14063C9C0)(resolution_mode & mode, rectangle & rect, int32_t index) + = (void* (FASTCALL*)(resolution_mode & mode, rectangle & rect, int32_t index))0x000000014063C9C0; + static void* (FASTCALL * sprite_manager_sub_14063F140)(int32_t index, resolution_mode mode, const rectangle & rect) + = (void* (FASTCALL*)(int32_t index, resolution_mode mode, const rectangle & rect))0x000000014063F140; + + render_data_context rend_data_ctx(GL_REND_STATE_POST_2D); + + rndr::Render* rend = render_get(); + rend->taa_buffer[rend->taa_texture].Bind(rend_data_ctx.state, 0); + + std::pair v20[2] = {}; + for (int32_t i = 0; i < 2; i++) { + sprite_manager_sub_14063C9C0(v20[i].first, v20[i].second, i); + + std::pair v19; + v19.first = v20[i].first; + v19.second.pos = v20[i].second.pos * 2.0f; + v19.second.size = v20[i].second.size * 2.0f; + sprite_manager_sub_14063F140(i, v19.first, v19.second); + } + + sprite_manager_set_view_projection(0); + rend_data_ctx.state.disable_depth_test(); + rend_data_ctx.state.enable_blend(); + rend_data_ctx.state.disable_cull_face(); + sprite_manager_draw(rend_data_ctx, 0, 0, rend->temp_buffer.color_texture); + sprite_manager_draw(rend_data_ctx, 3, 0, rend->temp_buffer.color_texture); + + vec2 v17 = 0.0f; + resolution_mode_scale_pos(v17, v20[1].first, + v20[1].second.pos, res_window_get()->resolution_mode); + v17 *= 2.0f; + + vec2 v18 = 0.0; + resolution_mode_scale_pos(v18, v20[1].first, + v20[1].second.pos + v20[1].second.size, res_window_get()->resolution_mode); + v18 *= 2.0f; + + rend_data_ctx.state.set_viewport((int32_t)v17.x, (int32_t)v17.y, + (int32_t)(v18.x - v17.x), (int32_t)(v18.y - v17.y)); + + rend_data_ctx.state.enable_cull_face(); + rend_data_ctx.state.disable_blend(); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.bind_framebuffer(0); + + for (int32_t i = 0; i < 2; i++) + sprite_manager_sub_14063F140(i, v20[i].first, v20[i].second); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer); + texture* taa_tex = rend->taa_tex[rend->taa_texture]; + rend_data_ctx.state.bind_texture_2d(taa_tex ? taa_tex->glid : 0); + + glGetTexImageDLL(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0i64); + rend_data_ctx.state.bind_texture_2d(0); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + gl_get_error_print(); +} + HOOK(void, FASTCALL, ScreenShotImpl__copy, 0x0000000140557F50, ScreenShotImpl* impl) { render_data_context rend_data_ctx(GL_REND_STATE_POST_2D); rend_data_ctx.state.active_bind_texture_2d(0, impl->tex->glid); @@ -116,18 +239,10 @@ HOOK(void, FASTCALL, ScreenShotImpl__copy, 0x0000000140557F50, ScreenShotImpl* i rend_data_ctx.state.enable_depth_test(); } -HOOK(void, FASTCALL, ScreenShotData__get_data, 0x0000000140557BE0, ScreenShotData* data) { - if (!data->screen_shot_4x) { - glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer); - glReadPixelsDLL(0, 0, data->width, data->height, GL_BGRA, GL_UNSIGNED_BYTE, 0); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - glGetErrorDLL(); - } -} - void screen_shot_patch() { INSTALL_HOOK(sub_1401898E0); - INSTALL_HOOK(ScreenShotImpl__copy); + INSTALL_HOOK(ScreenShotData__read_data); INSTALL_HOOK(ScreenShotData__get_data); + INSTALL_HOOK(ScreenShotImpl__copy); }