diff --git a/DivaGL.sln b/DivaGL.sln index 127720f..89f0913 100644 --- a/DivaGL.sln +++ b/DivaGL.sln @@ -17,6 +17,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AFTModsShared", "src\AFTMod EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SpriteDrawLimit", "src\SpriteDrawLimit\SpriteDrawLimit.vcxproj", "{87D41F20-B8C6-43BB-A89D-3A1979928613}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RobTexAnim", "src\RobTexAnim\RobTexAnim.vcxproj", "{761037C2-9F05-4EB0-B28A-D666981F2725}" + ProjectSection(ProjectDependencies) = postProject + {65707AD3-568A-4FE9-A75E-BDBF3D5EFC88} = {65707AD3-568A-4FE9-A75E-BDBF3D5EFC88} + {BCF448EA-DCFF-49AF-97FF-361204C69358} = {BCF448EA-DCFF-49AF-97FF-361204C69358} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -39,6 +45,10 @@ Global {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 + {761037C2-9F05-4EB0-B28A-D666981F2725}.Debug|x64.ActiveCfg = Debug|x64 + {761037C2-9F05-4EB0-B28A-D666981F2725}.Debug|x64.Build.0 = Debug|x64 + {761037C2-9F05-4EB0-B28A-D666981F2725}.Release|x64.ActiveCfg = Release|x64 + {761037C2-9F05-4EB0-B28A-D666981F2725}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/RobTexAnim/RobTexAnim.rc b/src/RobTexAnim/RobTexAnim.rc new file mode 100644 index 0000000..3513335 --- /dev/null +++ b/src/RobTexAnim/RobTexAnim.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", "Rob Tex Anim plugin for PDAFT 7.10" + VALUE "FileVersion", "0.1.0.0" + VALUE "InternalName", "RobTexAnim" + VALUE "LegalCopyright", "korenkonder (C) 2025" + VALUE "OriginalFilename", "RobTexAnim.dll" + VALUE "ProductName", "RobTexAnim" + VALUE "ProductVersion", "0.1.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x9, 1200 + END +END diff --git a/src/RobTexAnim/RobTexAnim.vcxproj b/src/RobTexAnim/RobTexAnim.vcxproj new file mode 100644 index 0000000..31ac2b4 --- /dev/null +++ b/src/RobTexAnim/RobTexAnim.vcxproj @@ -0,0 +1,135 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {761037c2-9f05-4eb0-b28a-d666981f2725} + Win32Proj + 10.0 + + + + DynamicLibrary + false + v142 + Unicode + + + DynamicLibrary + false + v142 + Unicode + + + + + + + + + + + + false + RobTexAnim + $(SolutionDir)bin\ + $(SolutionDir)obj\debug\RobTexAnim\ + .dva + + + false + RobTexAnim + $(SolutionDir)bin\ + $(SolutionDir)obj\release\RobTexAnim\ + .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;libdeflatestatic.lib;AFTModsShared.lib;KKdLib.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;libdeflatestatic.lib;AFTModsShared.lib;KKdLib.lib;%(AdditionalDependencies) + true + /ignore:4098 /ignore:4099 /ignore:4286 %(AdditionalOptions) + true + false + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/RobTexAnim/RobTexAnim.vcxproj.user b/src/RobTexAnim/RobTexAnim.vcxproj.user new file mode 100644 index 0000000..429333d --- /dev/null +++ b/src/RobTexAnim/RobTexAnim.vcxproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/src/RobTexAnim/dllmain.cpp b/src/RobTexAnim/dllmain.cpp new file mode 100644 index 0000000..9352320 --- /dev/null +++ b/src/RobTexAnim/dllmain.cpp @@ -0,0 +1,34 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "rob/rob.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("[Rob Tex Anim] Current version - v0.1.0.0\n"); + printf("[Rob Tex Anim] Attach\n"); + printf("[Rob Tex Anim] Patching memory\n"); + rob_patch(); + break; + } + return true; +} + +extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void) { + return L"Rob Tex Anim"; +} + +extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void) { + return L"Rob Tex Anim Plugin by korenkonder"; +} + +extern "C" __declspec(dllexport) LPCWSTR GetBuildDate(void) { + return L"v0.1.0.0"; +} diff --git a/src/RobTexAnim/resource.h b/src/RobTexAnim/resource.h new file mode 100644 index 0000000..480b823 --- /dev/null +++ b/src/RobTexAnim/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/RobTexAnim/rob/rob.cpp b/src/RobTexAnim/rob/rob.cpp new file mode 100644 index 0000000..a5a422f --- /dev/null +++ b/src/RobTexAnim/rob/rob.cpp @@ -0,0 +1,193 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "rob.hpp" +#include "../../AFTModsShared/auth_3d.hpp" +#include + +#define TEXTURE_PATTERN_COUNT 24 +#define TEXTURE_TRANSFORM_COUNT 24 + +static void(FASTCALL* item_table_handler_array_get_item_objset)(::chara_index chara_index, + int32_t item_no, prj::list*& objset) + = (void(FASTCALL*)(::chara_index chara_index, + int32_t item_no, prj::list*& objset))0x000000014052C270; + +HOOK(void, FASTCALL, TaskRobLoad__UnloadCharaItem, 0x0000000140525560, + ::chara_index chara_index, int32_t item_no) { + if (!item_no) + return; + + prj::list* item_objset = 0; + item_table_handler_array_get_item_objset(chara_index, item_no, item_objset); + if (!item_objset) + return; + + for (const int32_t& i : *item_objset) + if (i != -1) { + objset_info_storage_unload_set(i); + auth_3d_data_unload_category(objset_info_storage_get_set_name(i)); + } +} + +HOOK(void, FASTCALL, TaskRobLoad__LoadCharaItem, 0x000000014052B0F0, + ::chara_index chara_index, int32_t item_no) { + if (!item_no) + return; + + prj::list* item_objset = 0; + item_table_handler_array_get_item_objset(chara_index, item_no, item_objset); + if (!item_objset) + return; + + for (const int32_t& i : *item_objset) + if (i != -1) { + objset_info_storage_load_set(i); + auth_3d_data_load_category(objset_info_storage_get_set_name(i)); + } +} + +HOOK(bool, FASTCALL, TaskRobLoad__LoadCharaItemCheckNotRead, 0x000000014052D4C0, + ::chara_index chara_index, int32_t item_no) { + if (!item_no) + return false; + + prj::list* item_objset = 0; + item_table_handler_array_get_item_objset(chara_index, item_no, item_objset); + if (!item_objset) + return true; + + for (const int32_t& i : *item_objset) + if (i != -1 && objset_info_storage_load_obj_set_check_not_read(i)) { + if (auth_3d_data_check_category_loaded(objset_info_storage_get_set_name(i))) + return true; + } + return false; +} + +HOOK(rob_chara_item_equip_object*, FASTCALL, rob_chara_item_equip_object__rob_chara_item_equip_object, + 0x00000001405ED890, rob_chara_item_equip_object* This) { + This->auth_obj_index = -1; + This->auth_3d_id = -1; + return originalrob_chara_item_equip_object__rob_chara_item_equip_object(This); +} + +HOOK(void, FASTCALL, rob_chara_item_equip_object_ctrl, 0x00000001405F2310, rob_chara_item_equip_object* itm_eq_obj) { + originalrob_chara_item_equip_object_ctrl(itm_eq_obj); + + if (itm_eq_obj->auth_3d_id != -1 && itm_eq_obj->auth_obj_index == -1 + && (*(auth_3d_id*)&itm_eq_obj->auth_3d_id).check_loaded()) { + const char* obj_name = object_database_get_obj_name(itm_eq_obj->obj_info); + + auth_3d* auth = (*(auth_3d_id*)&itm_eq_obj->auth_3d_id).get_auth_3d(); + for (auth_3d_object& i : auth->object) + if (i.uid_name.compare(obj_name)) { + itm_eq_obj->auth_obj_index = (int32_t)(&i - auth->object.data()); + break; + } + } +} + +HOOK(void, FASTCALL, rob_chara_item_equip_object_disp, 0x00000001405F2700, rob_chara_item_equip_object* itm_eq_obj) { + if (itm_eq_obj->obj_info.is_null()) + return; + + char buf[0x80]; + int32_t tex_pat_count = 0; + texture_pattern_struct tex_pat[TEXTURE_PATTERN_COUNT]; + + int32_t tex_trans_count = 0; + texture_transform_struct tex_trans[TEXTURE_TRANSFORM_COUNT]; + + static void(FASTCALL * disp_manager_set_texture_transform)(int32_t count, texture_transform_struct * data) + = (void(FASTCALL*)(int32_t count, texture_transform_struct * data))0x000000014043A600; + + auth_3d_id& id = *(auth_3d_id*)&itm_eq_obj->auth_3d_id; + if (id.check_not_empty()) { + auth_3d* auth = id.get_auth_3d(); + if (itm_eq_obj->auth_obj_index >= 0 && itm_eq_obj->auth_obj_index < auth->object.size()) { + auth_3d_object* o = &auth->object.data()[itm_eq_obj->auth_obj_index]; + + for (auth_3d_object_texture_pattern& i : o->texture_pattern) { + if (!i.pattern.curve || i.name.size() <= 3) + continue; + else if (tex_pat_count >= TEXTURE_PATTERN_COUNT) + break; + + sprintf_s(buf, sizeof(buf), "%.*s%03d", + (int32_t)(i.name.size() - 3), i.name.c_str(), (int32_t)prj::roundf(i.pattern.value)); + + tex_pat[tex_pat_count].src = texture_id(0x00, i.texture_id); + tex_pat[tex_pat_count].dst = texture_id(0x00, texture_info_get_id(buf)); + tex_pat_count++; + } + + for (auth_3d_object_texture_transform& i : o->texture_transform) { + if (tex_trans_count >= TEXTURE_TRANSFORM_COUNT || i.texture_id == -1 + || !texture_manager_get_texture(i.texture_id)) + continue; + + tex_trans[tex_trans_count].id = i.texture_id; + tex_trans[tex_trans_count].mat = i.mat; + tex_trans_count++; + } + + if (tex_trans_count > 0) + disp_manager_set_texture_transform(tex_trans_count, tex_trans); + } + } + + prj::vector& itm_tex_pat = itm_eq_obj->texture_pattern; + + if (tex_pat_count > 0) + itm_tex_pat.insert(itm_tex_pat.end(), tex_pat, tex_pat + tex_pat_count); + + originalrob_chara_item_equip_object_disp(itm_eq_obj); + + if (tex_pat_count > 0) + itm_tex_pat.resize(itm_tex_pat.size() - tex_pat_count); + + if (tex_trans_count > 0) + disp_manager_set_texture_transform(0, 0); +} + +HOOK(bool, FASTCALL, rob_chara_item_equip_object__init_members, 0x00000001405F36F0, + rob_chara_item_equip_object* This, size_t index) { + This->auth_obj_index = -1; + (*(auth_3d_id*)&This->auth_3d_id).unload(); + return originalrob_chara_item_equip_object__init_members(This, index); +} + +HOOK(bool, FASTCALL, rob_chara_item_equip_object_load_object_info_ex_data, 0x00000001405F6E30, + rob_chara_item_equip_object* itm_eq_obj, uint32_t obj_info, bone_node* bone_nodes, bool osage_reset) { + auth_3d_id id(objset_info_storage_get_set_name((*(object_info*)&obj_info).set_id)); + if (id.check_not_empty()) { + id.read_file(); + id.set_enable(true); + id.set_repeat(true); + id.set_paused(false); + id.set_visibility(false); + + itm_eq_obj->auth_obj_index = -1; + (*(auth_3d_id*)&itm_eq_obj->auth_3d_id) = id; + } + else { + itm_eq_obj->auth_obj_index = -1; + itm_eq_obj->auth_3d_id = -1; + } + + return originalrob_chara_item_equip_object_load_object_info_ex_data(itm_eq_obj, obj_info, bone_nodes, osage_reset); +} + +void rob_patch() { + INSTALL_HOOK(TaskRobLoad__UnloadCharaItem); + INSTALL_HOOK(TaskRobLoad__LoadCharaItem); + INSTALL_HOOK(TaskRobLoad__LoadCharaItemCheckNotRead); + INSTALL_HOOK(rob_chara_item_equip_object__rob_chara_item_equip_object); + INSTALL_HOOK(rob_chara_item_equip_object_ctrl); + INSTALL_HOOK(rob_chara_item_equip_object_disp); + INSTALL_HOOK(rob_chara_item_equip_object__init_members); + INSTALL_HOOK(rob_chara_item_equip_object_load_object_info_ex_data); +} diff --git a/src/RobTexAnim/rob/rob.hpp b/src/RobTexAnim/rob/rob.hpp new file mode 100644 index 0000000..6a40451 --- /dev/null +++ b/src/RobTexAnim/rob/rob.hpp @@ -0,0 +1,10 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../AFTModsShared/rob/rob.hpp" + +extern void rob_patch();