diff --git a/StdPatch/src/StdPatch.cpp b/StdPatch/src/StdPatch.cpp index b530b62..cfb5132 100644 --- a/StdPatch/src/StdPatch.cpp +++ b/StdPatch/src/StdPatch.cpp @@ -22,6 +22,7 @@ void LoadConfig() if (FileExists(szBuf)) { g_nMAXSTUDIOVERTS_NEW = GetPrivateProfileIntA("Main", "MaxStudioVerts", (1024 * 512), szBuf); + g_nMAXMATERIALSCOUNT_NEW = GetPrivateProfileIntA("Main", "MaxMaterials", 127, szBuf); g_nBUFFERSIZE_NEW = GetPrivateProfileIntA("Main", "BufferSize", (1024 * 1024 * 32), szBuf); g_nMAXFLEXCONTROLLER_NEW = GetPrivateProfileIntA("Main", "FlexControllerSize", 400, szBuf); } @@ -30,9 +31,16 @@ void LoadConfig() DbgTrace("Warning! 'StdPatch.ini' configuration file could not be found, creating one with default values for patching.\n"); WritePrivateProfileStringA("Main", "MaxStudioVerts", "524288", szBuf); + WritePrivateProfileStringA("Main", "MaxMaterials", "127", szBuf); WritePrivateProfileStringA("Main", "BufferSize", "33554432", szBuf); WritePrivateProfileStringA("Main", "FlexControllerSize", "400", szBuf); } + + if (g_nMAXMATERIALSCOUNT_NEW > 127) + { + DbgTrace("Warning! Materials limit can't be more than 127, but received %d. Setting to 127...\n", g_nMAXMATERIALSCOUNT_NEW); + g_nMAXMATERIALSCOUNT_NEW = 127; + } } bool IsSFM() @@ -55,11 +63,58 @@ VOID WINAPI hkOutputDebugStringA(LPCSTR lpOutputString) void Hook_OutputDebugStringA() { orgOutputDebugStringA = decltype(orgOutputDebugStringA)(gKernelDll->HookExport("OutputDebugStringA", hkOutputDebugStringA)); +} + +bool Find_MaterialsList() +{ + ISearchPattern *pattern; + + pattern = gStudioExe->CreatePattern(g_pMaterialsList); + { + pattern->FindAnsiString("face %d references NULL texture %d\n", kPatternFlagsStringRef); + pattern->FindCall(0, true, true); + pattern->FindUInt16(0x868D); + pattern->Transpose(2); + pattern->Dereference(); + } + + if (!g_pMaterialsList) + return false; + + pattern = gStudioExe->CreatePattern(g_pMaterialsListCheck); + { + pattern->FindAnsiString("Too many materials used, max %d\n", kPatternFlagsStringRef); + } + + if (!g_pMaterialsListCheck) + return false; + g_nMAXMATERIALSCOUNT_DEF = *(uint8_t *)Transpose(g_pMaterialsListCheck, -2); + + return true; +} + +bool Patch_MaterialsList() +{ + if (!g_pMaterialsList || !g_pMaterialsListCheck) + return false; + + g_MaterialsList.SetLength(g_nMAXMATERIALSCOUNT_NEW); + + if (gStudioExe->HookRefAddr(g_pMaterialsList, g_MaterialsList.GetData(), 0x00) == 0) + { + g_MaterialsList.SetLength(0); + return false; + } + + WritePrimitive(g_pMaterialsListCheck, g_nMAXMATERIALSCOUNT_NEW, -2); + WritePrimitive(g_pMaterialsListCheck, g_nMAXMATERIALSCOUNT_NEW, -6); + return true; } + void PatchStudioMdl() { - DbgTrace("StudioMdl Patcher 2.2.0 is started.\n"); + DbgTrace("StudioMdl Patcher 2.3.0 is started.\n"); DbgTrace("Code by Alexander B. (2010kohtep) special for RED_EYE.\n"); FindModules(); @@ -123,6 +178,14 @@ void PatchStudioMdl() if (!Patch_SanityCheckVertexBoneLODFlags()) FailedToFind("SanityCheckVertexBoneLODFlags()"); + if (!Find_MaterialsList()) + FailedToPatch("MaterialsList"); + else + { + if (!Patch_MaterialsList()) + FailedToHook("MaterialsList"); + } + DbgTrace("\n"); } diff --git a/StdPatch/src/main/Global.cpp b/StdPatch/src/main/Global.cpp index 02639b3..51c2a59 100644 --- a/StdPatch/src/main/Global.cpp +++ b/StdPatch/src/main/Global.cpp @@ -6,22 +6,28 @@ IModule *gKernelDll; int g_nMAXSTUDIOVERTS_NEW = 0x00F00000; // def - $80000 int g_nBUFFERSIZE_NEW = 0x02000000; // def - $2000000 int g_nMAXFLEXCONTROLLER_NEW = 0x00000400; // def - $80 +int g_nMAXMATERIALSCOUNT_NEW = 0x0000007F; // def - $20 int g_nMAXSTUDIOVERTS_DEF; int g_nBUFFERSIZE_DEF; int g_nMAXFLEXCONTROLLER_DEF; +int g_nMAXMATERIALSCOUNT_DEF; CArrayHelper g_FlexControllerNew; CArrayHelper g_VerticesPtrsNew; CArrayHelper g_VerticesDataNew; CArrayHelper g_WeightList; +CArrayHelper g_MaterialsList; void *g_pBUFFERSIZE; void *g_pMAXSTUDIOVERTS; void *g_pMAXFLEXCONTROLLER; +void *g_pMAXMATERIALSCOUNT; TAddToVlist g_pfnAddToVlist; TIsInt24 g_pfnIsInt24; void *g_pVList; +void *g_pMaterialsList; +void *g_pMaterialsListCheck; void *g_pFlexController; \ No newline at end of file diff --git a/StdPatch/src/main/Global.h b/StdPatch/src/main/Global.h index 997b293..118ad40 100644 --- a/StdPatch/src/main/Global.h +++ b/StdPatch/src/main/Global.h @@ -11,19 +11,23 @@ extern IModule *gKernelDll; extern int g_nMAXSTUDIOVERTS_NEW; extern int g_nBUFFERSIZE_NEW; extern int g_nMAXFLEXCONTROLLER_NEW; +extern int g_nMAXMATERIALSCOUNT_NEW; extern int g_nMAXSTUDIOVERTS_DEF; extern int g_nBUFFERSIZE_DEF; extern int g_nMAXFLEXCONTROLLER_DEF; +extern int g_nMAXMATERIALSCOUNT_DEF; extern CArrayHelper g_FlexControllerNew; extern CArrayHelper g_VerticesPtrsNew; extern CArrayHelper g_VerticesDataNew; extern CArrayHelper g_WeightList; +extern CArrayHelper g_MaterialsList; extern void *g_pBUFFERSIZE; extern void *g_pMAXSTUDIOVERTS; extern void *g_pMAXFLEXCONTROLLER; +extern void *g_pMAXMATERIALSCOUNT; using TAddToVlist = void *(__cdecl *)(int a1, int a2, int a3, int a4); using TIsInt24 = bool(__cdecl *)(int nValue); @@ -32,4 +36,6 @@ extern TAddToVlist g_pfnAddToVlist; extern TIsInt24 g_pfnIsInt24; extern void *g_pVList; +extern void *g_pMaterialsList; +extern void *g_pMaterialsListCheck; extern void *g_pFlexController; \ No newline at end of file diff --git a/StdPatch/src/main/SDK.h b/StdPatch/src/main/SDK.h index 5b50942..27e8d5e 100644 --- a/StdPatch/src/main/SDK.h +++ b/StdPatch/src/main/SDK.h @@ -140,4 +140,9 @@ struct TotalMeshStats_t int m_TotalTopology; int m_TotalBoneStateChanges; int m_TotalMaterialReplacements; +}; + +struct TMaterialInfo +{ + unsigned char dummy[288]; }; \ No newline at end of file