88
99#include " StdInc.h"
1010#include " CGameSA.h"
11+ #include " CDirectorySA.h"
1112#include " gamesa_renderware.h"
1213
1314extern CGameSA* pGame;
@@ -28,8 +29,10 @@ namespace
2829 uint uiLoadflag; // 0-not loaded 2-requested 3-loaded 1-processed
2930 };
3031
31- std::map<ushort, char *> ms_ReplacementClothesFileDataMap;
32- bool bClothesReplacementChanged = false ;
32+ std::unordered_map<ushort, char *> ms_ReplacementClothesFileDataMap;
33+ std::unordered_map<ushort, std::uint16_t > ms_OriginalStreamingSizesMap;
34+
35+ bool bClothesReplacementChanged = false ;
3336
3437 struct SPlayerImgItem
3538 {
@@ -46,44 +49,64 @@ namespace
4649 };
4750
4851 DWORD FUNC_CStreamingConvertBufferToObject = 0x40C6B0 ;
52+ auto g_clothesDirectory = reinterpret_cast <CDirectorySAInterface*>(0xBC12C0 );
4953 int iReturnFileId;
5054 char * pReturnBuffer;
55+
56+ size_t GetSizeInBlocks (size_t size)
57+ {
58+ auto blockDiv = std::div (size, 2048 );
59+ return (blockDiv.quot + (blockDiv.rem ? 1 : 0 ));
60+ }
5161} // namespace
5262
5363// //////////////////////////////////////////////////////////////
5464//
55- // CRenderWareSA::ClothesAddReplacementTxd
65+ // CRenderWareSA::ClothesAddReplacement
5666//
57- // Add replacement txd for a clothing component
67+ // Add replacement txd/dff for a clothing component
5868//
5969// //////////////////////////////////////////////////////////////
60- void CRenderWareSA::ClothesAddReplacementTxd (char * pFileData, ushort usFileId)
70+ void CRenderWareSA::ClothesAddReplacement (char * pFileData, size_t fileSize , ushort usFileId)
6171{
6272 if (!pFileData)
6373 return ;
74+
6475 if (pFileData != MapFindRef (ms_ReplacementClothesFileDataMap, usFileId))
6576 {
6677 MapSet (ms_ReplacementClothesFileDataMap, usFileId, pFileData);
78+ MapSet (ms_OriginalStreamingSizesMap, usFileId, g_clothesDirectory->GetModelStreamingSize (usFileId));
79+ g_clothesDirectory->SetModelStreamingSize (usFileId, GetSizeInBlocks (fileSize));
80+
6781 bClothesReplacementChanged = true ;
6882 }
6983}
7084
7185// //////////////////////////////////////////////////////////////
7286//
73- // CRenderWareSA::ClothesRemoveReplacementTxd
87+ // CRenderWareSA::ClothesRemoveReplacement
7488//
75- // Remove replacement txd for a clothing component
89+ // Remove replacement txd/dff for a clothing component
7690//
7791// //////////////////////////////////////////////////////////////
78- void CRenderWareSA::ClothesRemoveReplacementTxd (char * pFileData)
92+ void CRenderWareSA::ClothesRemoveReplacement (char * pFileData)
7993{
8094 if (!pFileData)
8195 return ;
82- for (std::map<ushort, char *>::iterator iter = ms_ReplacementClothesFileDataMap.begin (); iter != ms_ReplacementClothesFileDataMap.end ();)
96+
97+ for (auto iter = ms_ReplacementClothesFileDataMap.begin (); iter != ms_ReplacementClothesFileDataMap.end ();)
8398 {
8499 if (iter->second == pFileData)
85100 {
86- ms_ReplacementClothesFileDataMap.erase (iter++);
101+ auto it = ms_OriginalStreamingSizesMap.find (iter->first );
102+
103+ if (it != ms_OriginalStreamingSizesMap.end ())
104+ {
105+ std::uint16_t originalStreamingSize = it->second ;
106+ g_clothesDirectory->SetModelStreamingSize (iter->first , originalStreamingSize);
107+ }
108+
109+ iter = ms_ReplacementClothesFileDataMap.erase (iter);
87110 bClothesReplacementChanged = true ;
88111 }
89112 else
@@ -110,7 +133,7 @@ bool CRenderWareSA::HasClothesReplacementChanged()
110133// CStreaming_RequestModel_Mid
111134//
112135// If request is for a file inside player.img (imgId 5)
113- // then maybe switch to replacement txd file data
136+ // then maybe switch to replacement txd/dff file data
114137//
115138// //////////////////////////////////////////////////////////////
116139__declspec (noinline) bool _cdecl OnCStreaming_RequestModel_Mid(int flags, SImgGTAItemInfo* pImgGTAInfo)
0 commit comments