diff --git a/DivaGL.sln b/DivaGL.sln index ba3cef6..127720f 100644 --- a/DivaGL.sln +++ b/DivaGL.sln @@ -15,6 +15,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AFTModsShared", "src\AFTMod {65707AD3-568A-4FE9-A75E-BDBF3D5EFC88} = {65707AD3-568A-4FE9-A75E-BDBF3D5EFC88} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SpriteDrawLimit", "src\SpriteDrawLimit\SpriteDrawLimit.vcxproj", "{87D41F20-B8C6-43BB-A89D-3A1979928613}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -33,6 +35,10 @@ Global {BCF448EA-DCFF-49AF-97FF-361204C69358}.Debug|x64.Build.0 = Debug|x64 {BCF448EA-DCFF-49AF-97FF-361204C69358}.Release|x64.ActiveCfg = Release|x64 {BCF448EA-DCFF-49AF-97FF-361204C69358}.Release|x64.Build.0 = Release|x64 + {87D41F20-B8C6-43BB-A89D-3A1979928613}.Debug|x64.ActiveCfg = Debug|x64 + {87D41F20-B8C6-43BB-A89D-3A1979928613}.Debug|x64.Build.0 = Debug|x64 + {87D41F20-B8C6-43BB-A89D-3A1979928613}.Release|x64.ActiveCfg = Release|x64 + {87D41F20-B8C6-43BB-A89D-3A1979928613}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/SpriteDrawLimit/SpriteDrawLimit.rc b/src/SpriteDrawLimit/SpriteDrawLimit.rc new file mode 100644 index 0000000..25fb26b --- /dev/null +++ b/src/SpriteDrawLimit/SpriteDrawLimit.rc @@ -0,0 +1,37 @@ +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +#include "winres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,1,0,0 + PRODUCTVERSION 0,1,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000904b0" + BEGIN + VALUE "FileDescription", "Sprite Draw Limit plugin for PDAFT 7.10" + VALUE "FileVersion", "0.1.0.0" + VALUE "InternalName", "SpriteDrawLimit" + VALUE "LegalCopyright", "korenkonder (C) 2024" + VALUE "OriginalFilename", "SpriteDrawLimit.dll" + VALUE "ProductName", "SpriteDrawLimit" + VALUE "ProductVersion", "0.1.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x9, 1200 + END +END diff --git a/src/SpriteDrawLimit/SpriteDrawLimit.vcxproj b/src/SpriteDrawLimit/SpriteDrawLimit.vcxproj new file mode 100644 index 0000000..0e5b6d6 --- /dev/null +++ b/src/SpriteDrawLimit/SpriteDrawLimit.vcxproj @@ -0,0 +1,142 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {87d41f20-b8c6-43bb-a89d-3a1979928613} + Win32Proj + 10.0 + + + + DynamicLibrary + false + v142 + Unicode + + + DynamicLibrary + false + v142 + Unicode + + + + + + + + + + + + + + false + SpriteDrawLimit + $(SolutionDir)bin\ + $(SolutionDir)obj\debug\SpriteDrawLimit\ + .dva + + + false + SpriteDrawLimit + $(SolutionDir)bin\ + $(SolutionDir)obj\release\SpriteDrawLimit\ + .dva + + + + NotUsing + Level3 + Disabled + WIN32;DEBUG;%(PreprocessorDefinitions) + $(SolutionDir)extern\src + true + ProgramDatabase + false + OnlyExplicitInline + FastCall + true + CompileAsCpp + $(IntDir)/%(RelativeDir) + MultiThreaded + 26812 + false + true + + + MachineX64 + DebugFull + Windows + $(SolutionDir)extern\lib;$(SolutionDir)lib\debugopt\ + detours.lib;syelog.lib;%(AdditionalDependencies) + /ignore:4098 /ignore:4099 /ignore:4286 %(AdditionalOptions) + false + + + + + NotUsing + Level3 + MaxSpeed + WIN32;%(PreprocessorDefinitions) + $(SolutionDir)extern\src + true + false + ProgramDatabase + OnlyExplicitInline + true + FastCall + CompileAsCpp + + + $(IntDir)/%(RelativeDir) + Speed + + + false + MultiThreaded + 26812 + true + + + MachineX64 + true + Windows + $(SolutionDir)extern\lib;$(SolutionDir)lib\release\ + detours.lib;syelog.lib;%(AdditionalDependencies) + true + /ignore:4098 /ignore:4099 /ignore:4286 %(AdditionalOptions) + true + false + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/SpriteDrawLimit/SpriteDrawLimit.vcxproj.user b/src/SpriteDrawLimit/SpriteDrawLimit.vcxproj.user new file mode 100644 index 0000000..429333d --- /dev/null +++ b/src/SpriteDrawLimit/SpriteDrawLimit.vcxproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/src/SpriteDrawLimit/common.asm b/src/SpriteDrawLimit/common.asm new file mode 100644 index 0000000..3e9dc3e --- /dev/null +++ b/src/SpriteDrawLimit/common.asm @@ -0,0 +1,148 @@ +EXTERN ?originalspr__calc_sprite_texture_param_mid1@@3P6AXXZEA : QWORD +EXTERN ?originalspr__calc_sprite_texture_param_mid2@@3P6AXXZEA : QWORD +EXTERN ?originalspr__draw_sprite_scale_mid@@3P6AXXZEA : QWORD +EXTERN ?originalspr__draw_sprite_mid_spr_vertex_array_pos@@3P6AXXZEA : QWORD +EXTERN ?originalspr__draw_sprite_mid_spr_vertex_array_uv@@3P6AXXZEA : QWORD +EXTERN ?originalspr__draw_sprite_mid_spr_vertex_array_color@@3P6AXXZEA : QWORD +EXTERN ?originalspr__draw_sprite_mid_spr_kind_arrow_b@@3P6AXXZEA : QWORD +EXTERN ?originalspr__draw_sprite_mid_spr_kind_arrow_ab@@3P6AXXZEA : QWORD +EXTERN ?originalspr__draw_sprite_mid_spr_kind_triangle@@3P6AXXZEA : QWORD + +EXTERN ?sprite_vertex_data@@3AEAUSpriteVertexData@spr@@EA : QWORD + +.CODE +?implOfspr__calc_sprite_texture_param_mid1@@YAXXZ PROC PUBLIC + push rcx + push rdx + + mov rax, [rbx+0B0h] + lea rdx, [rax+rax*2] + mov rax, ?sprite_vertex_data@@3AEAUSpriteVertexData@spr@@EA + mov rcx, [rax+8] + lea rax, [rcx+rdx*8] + + pop rdx + pop rcx + jmp ?originalspr__calc_sprite_texture_param_mid1@@3P6AXXZEA +?implOfspr__calc_sprite_texture_param_mid1@@YAXXZ ENDP + +?implOfspr__calc_sprite_texture_param_mid2@@YAXXZ PROC PUBLIC + push rcx + push rdx + + mov rax, [rbx+0B0h] + lea rdx, [rax+rax*2] + mov rax, ?sprite_vertex_data@@3AEAUSpriteVertexData@spr@@EA + mov rcx, [rax+8] + lea rax, [rcx+rdx*8] + + pop rdx + pop rcx + jmp ?originalspr__calc_sprite_texture_param_mid2@@3P6AXXZEA +?implOfspr__calc_sprite_texture_param_mid2@@YAXXZ ENDP + +?implOfspr__draw_sprite_scale_mid@@YAXXZ PROC PUBLIC + push rax + push rdx + + mov rax, [rbx+0B0h] + lea rdx, [rax+rax*2] + mov rax, ?sprite_vertex_data@@3AEAUSpriteVertexData@spr@@EA + mov rcx, [rax+8] + lea rcx, [rcx+rdx*8] + + pop rdx + pop rax + jmp ?originalspr__draw_sprite_scale_mid@@3P6AXXZEA +?implOfspr__draw_sprite_scale_mid@@YAXXZ ENDP + +?implOfspr__draw_sprite_mid_spr_vertex_array_pos@@YAXXZ PROC PUBLIC + push rcx + push rdx + + mov r9, [rbx+0B0h] + lea rdx, [r9+r9*2] + mov r9, ?sprite_vertex_data@@3AEAUSpriteVertexData@spr@@EA + mov rcx, [r9+8] + lea r9, [rcx+rdx*8] + + pop rdx + pop rcx + jmp ?originalspr__draw_sprite_mid_spr_vertex_array_pos@@3P6AXXZEA +?implOfspr__draw_sprite_mid_spr_vertex_array_pos@@YAXXZ ENDP + +?implOfspr__draw_sprite_mid_spr_vertex_array_uv@@YAXXZ PROC PUBLIC + push rcx + push rdx + + mov r9, [rbx+0B0h] + lea rdx, [r9+r9*2] + mov r9, ?sprite_vertex_data@@3AEAUSpriteVertexData@spr@@EA + mov rcx, [r9+8] + lea r9, [rcx+rdx*8] + + pop rdx + pop rcx + jmp ?originalspr__draw_sprite_mid_spr_vertex_array_uv@@3P6AXXZEA +?implOfspr__draw_sprite_mid_spr_vertex_array_uv@@YAXXZ ENDP + +?implOfspr__draw_sprite_mid_spr_vertex_array_color@@YAXXZ PROC PUBLIC + push rcx + push rdx + + mov r9, [rbx+0B0h] + lea rdx, [r9+r9*2] + mov r9, ?sprite_vertex_data@@3AEAUSpriteVertexData@spr@@EA + mov rcx, [r9+8] + lea r9, [rcx+rdx*8] + + pop rdx + pop rcx + jmp ?originalspr__draw_sprite_mid_spr_vertex_array_color@@3P6AXXZEA +?implOfspr__draw_sprite_mid_spr_vertex_array_color@@YAXXZ ENDP + +?implOfspr__draw_sprite_mid_spr_kind_arrow_b@@YAXXZ PROC PUBLIC + push rcx + push rdx + + mov rbx, [rbx+0B0h] + lea rdx, [rbx+rbx*2] + mov rbx, ?sprite_vertex_data@@3AEAUSpriteVertexData@spr@@EA + mov rcx, [rbx+8] + lea rbx, [rcx+rdx*8] + + pop rdx + pop rcx + jmp ?originalspr__draw_sprite_mid_spr_kind_arrow_b@@3P6AXXZEA +?implOfspr__draw_sprite_mid_spr_kind_arrow_b@@YAXXZ ENDP + +?implOfspr__draw_sprite_mid_spr_kind_arrow_ab@@YAXXZ PROC PUBLIC + push rcx + push rdx + + mov rbx, [rbx+0B0h] + lea rdx, [rbx+rbx*2] + mov rbx, ?sprite_vertex_data@@3AEAUSpriteVertexData@spr@@EA + mov rcx, [rbx+8] + lea rbx, [rcx+rdx*8] + + pop rdx + pop rcx + jmp ?originalspr__draw_sprite_mid_spr_kind_arrow_ab@@3P6AXXZEA +?implOfspr__draw_sprite_mid_spr_kind_arrow_ab@@YAXXZ ENDP + +?implOfspr__draw_sprite_mid_spr_kind_triangle@@YAXXZ PROC PUBLIC + push rcx + push rdx + + mov rbx, [rbx+0B0h] + lea rdx, [rbx+rbx*2] + mov rbx, ?sprite_vertex_data@@3AEAUSpriteVertexData@spr@@EA + mov rcx, [rbx+8] + lea rbx, [rcx+rdx*8] + + pop rdx + pop rcx + jmp ?originalspr__draw_sprite_mid_spr_kind_triangle@@3P6AXXZEA +?implOfspr__draw_sprite_mid_spr_kind_triangle@@YAXXZ ENDP +END \ No newline at end of file diff --git a/src/SpriteDrawLimit/dllmain.cpp b/src/SpriteDrawLimit/dllmain.cpp new file mode 100644 index 0000000..3beb40b --- /dev/null +++ b/src/SpriteDrawLimit/dllmain.cpp @@ -0,0 +1,34 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "sprite.hpp" +#include +#include +#define WIN32_LEAN_AND_MEAN +#include + +bool APIENTRY DllMain(HMODULE handle, DWORD ul_reason_for_call, LPVOID lpReserved) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + printf("[Sprite Draw Limit] Current version - v0.1.0.0\n"); + printf("[Sprite Draw Limit] Attach\n"); + printf("[Sprite Draw Limit] Patching memory\n"); + sprite_draw_limit_patch(); + break; + } + return true; +} + +extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void) { + return L"Sprite Draw Limit"; +} + +extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void) { + return L"Sprite Draw Limit Plugin by korenkonder"; +} + +extern "C" __declspec(dllexport) LPCWSTR GetBuildDate(void) { + return L"v0.1.0.0"; +} diff --git a/src/SpriteDrawLimit/resource.h b/src/SpriteDrawLimit/resource.h new file mode 100644 index 0000000..480b823 --- /dev/null +++ b/src/SpriteDrawLimit/resource.h @@ -0,0 +1,8 @@ +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/SpriteDrawLimit/sprite.cpp b/src/SpriteDrawLimit/sprite.cpp new file mode 100644 index 0000000..3558100 --- /dev/null +++ b/src/SpriteDrawLimit/sprite.cpp @@ -0,0 +1,108 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "sprite.hpp" +#include +#include +#define WIN32_LEAN_AND_MEAN +#include +#include + +#define FASTCALL __fastcall + +namespace spr { + struct SpriteVertex { + float_t pos[3]; // vec3 + float_t uv[2]; // vec2 + uint32_t color; // color4u8 + }; + + static_assert(sizeof(spr::SpriteVertex) == 0x18, "\"spr::SpriteVertex\" struct should have a size of 0x18"); + + struct SpriteVertexData { + size_t max_count; + spr::SpriteVertex* array; + }; +} + +static void* (*_operator_new)(size_t) = (void* (*)(size_t))0x000000014084530C; +static void(*_operator_delete)(void*) = (void(*)(void*))0x0000000140845378; + +spr::SpriteVertexData& sprite_vertex_data = *(spr::SpriteVertexData*)0x000000014CC62480; + +const size_t sprite_vertex_array_max_count = 0x2000; +spr::SpriteVertex* sprite_vertex_array = (spr::SpriteVertex*)0x000000014CC62480; + +size_t& sprite_vertex_array_count = *(size_t*)0x000000014CC611B0; + +HOOK(void, FASTCALL, spr__calc_sprite_texture_param_mid1, 0x0000000140638DD0); +HOOK(void, FASTCALL, spr__calc_sprite_texture_param_mid2, 0x0000000140638DF6); +HOOK(void, FASTCALL, spr__draw_sprite_scale_mid, 0x0000000140639DB7); +HOOK(void, FASTCALL, spr__draw_sprite_mid_spr_vertex_array_pos, 0x000000014063A961); +HOOK(void, FASTCALL, spr__draw_sprite_mid_spr_vertex_array_uv, 0x000000014063A97C); +HOOK(void, FASTCALL, spr__draw_sprite_mid_spr_vertex_array_color, 0x000000014063A99B); +HOOK(void, FASTCALL, spr__draw_sprite_mid_spr_kind_arrow_b, 0x000000014063AB7B); +HOOK(void, FASTCALL, spr__draw_sprite_mid_spr_kind_arrow_ab, 0x000000014063ABCC); +HOOK(void, FASTCALL, spr__draw_sprite_mid_spr_kind_triangle, 0x000000014063AC8D); + +HOOK(void, FASTCALL, spr__SprArgs__SetVertexArray, 0x000000014063F040, + __int64 This, spr::SpriteVertex* vertex_array, size_t num_vertex) { + if (!sprite_vertex_data.array) + sprite_vertex_data.array = (spr::SpriteVertex*)_operator_new( + sizeof(spr::SpriteVertex) * sprite_vertex_data.max_count); + + if (sprite_vertex_array_count + num_vertex >= sprite_vertex_data.max_count) { + while (sprite_vertex_array_count + num_vertex >= sprite_vertex_data.max_count) + sprite_vertex_data.max_count *= 2; + + spr::SpriteVertex* _sprite_vertex_array = (spr::SpriteVertex*)_operator_new( + sizeof(spr::SpriteVertex) * sprite_vertex_data.max_count); + memmove(_sprite_vertex_array, sprite_vertex_data.array, + sizeof(spr::SpriteVertex) * sprite_vertex_array_count); + _operator_delete(sprite_vertex_data.array); + sprite_vertex_data.array = _sprite_vertex_array; + } + + *(size_t*)(This + 0xB8) = num_vertex; + + *(size_t*)(This + 0xB0) = sprite_vertex_array_count; + memmove(sprite_vertex_data.array + *(size_t*)(This + 0xB0), + vertex_array, sizeof(spr::SpriteVertex) * num_vertex); + + sprite_vertex_array_count += num_vertex; +} + +HOOK(void, FASTCALL, sprite_manager_clear, 0x000000014063F860) { + if (sprite_vertex_data.array) + _operator_delete(sprite_vertex_data.array); + originalsprite_manager_clear(); +} + +void sprite_draw_limit_patch() { + sprite_vertex_data.array = 0; + sprite_vertex_data.max_count = sprite_vertex_array_max_count; + + WRITE_NOP_7(0x0000000140638DD0); + WRITE_NOP_7(0x0000000140638DF6); + WRITE_NOP_7(0x0000000140639DB7); + WRITE_NOP_7(0x000000014063A961); + WRITE_NOP_7(0x000000014063A97C); + WRITE_NOP_7(0x000000014063A99B); + WRITE_NOP_7(0x000000014063AB7B); + WRITE_NOP_7(0x000000014063ABCC); + WRITE_NOP_7(0x000000014063AC8D); + + INSTALL_HOOK(spr__calc_sprite_texture_param_mid1); + INSTALL_HOOK(spr__calc_sprite_texture_param_mid2); + INSTALL_HOOK(spr__draw_sprite_scale_mid); + INSTALL_HOOK(spr__draw_sprite_mid_spr_vertex_array_pos); + INSTALL_HOOK(spr__draw_sprite_mid_spr_vertex_array_uv); + INSTALL_HOOK(spr__draw_sprite_mid_spr_vertex_array_color); + INSTALL_HOOK(spr__draw_sprite_mid_spr_kind_arrow_b); + INSTALL_HOOK(spr__draw_sprite_mid_spr_kind_arrow_ab); + INSTALL_HOOK(spr__draw_sprite_mid_spr_kind_triangle); + INSTALL_HOOK(spr__SprArgs__SetVertexArray); + INSTALL_HOOK(sprite_manager_clear); +} diff --git a/src/SpriteDrawLimit/sprite.hpp b/src/SpriteDrawLimit/sprite.hpp new file mode 100644 index 0000000..771748e --- /dev/null +++ b/src/SpriteDrawLimit/sprite.hpp @@ -0,0 +1,8 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +extern void sprite_draw_limit_patch();