Skip to content

Commit 16ed6f5

Browse files
committed
Fixed unload crash. IFP is unloaded by checking references now.
1 parent c60a3b2 commit 16ed6f5

File tree

2 files changed

+81
-26
lines changed

2 files changed

+81
-26
lines changed

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4076,20 +4076,21 @@ bool CClientGame::AssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSA
40764076
auto pReplacedAnimation = pClientPed->getReplacedAnimation ( pOriginalAnimStaticAssoc->pAnimHeirarchy );
40774077
if ( pReplacedAnimation != nullptr )
40784078
{
4079-
SIFPAnimations * pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer ();
4080-
printf("\nAssocGroupCopyAnimationHandler: pIFPAnimations: %p\n\n", pIFPAnimations);
4081-
// Play our custom animation instead of default
4082-
*pOutIFPAnimations = pIFPAnimations;
4083-
CAnimBlendStaticAssociation_Init ( pOutAnimStaticAssoc, pClump, pReplacedAnimation->pAnimationHierarchy );
4084-
isCustomAnimationToPlay = true;
4085-
}
4086-
else
4087-
{ // Play default internal animation
4088-
CAnimBlendStaticAssociation_Init ( pOutAnimStaticAssoc, pClump, pOriginalAnimStaticAssoc->pAnimHeirarchy );
4079+
if ( pReplacedAnimation->pIFP->isIFPLoaded ( ) )
4080+
{
4081+
SIFPAnimations * pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer ();
4082+
pIFPAnimations->iReferences ++;
4083+
// Play our custom animation instead of default
4084+
*pOutIFPAnimations = pIFPAnimations;
4085+
CAnimBlendStaticAssociation_Init ( pOutAnimStaticAssoc, pClump, pReplacedAnimation->pAnimationHierarchy );
4086+
isCustomAnimationToPlay = true;
4087+
}
40894088
}
40904089
}
4091-
else
4092-
{ // Play default internal animation
4090+
4091+
if ( !isCustomAnimationToPlay )
4092+
{
4093+
// Play default internal animation
40934094
CAnimBlendStaticAssociation_Init ( pOutAnimStaticAssoc, pClump, pOriginalAnimStaticAssoc->pAnimHeirarchy );
40944095
}
40954096

@@ -4124,15 +4125,22 @@ CAnimBlendHierarchySAInterface * CClientGame::BlendAnimationHierarchyHandler ( R
41244125
auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy ( strAnimationName );
41254126
if ( pCustomAnimBlendHierarchy != nullptr )
41264127
{
4127-
pClientPed->setCurrentAnimationCustom ( true );
4128-
pClientPed->SetIFPAnimationsPointer ( pIFP->GetIFPAnimationsPointer () );
4129-
// Modifying a hierarchy like this is just bad, it's much better to create a new CAnimBlendHierarchySAInterface for every animation
4130-
// and then delete it once animation is over
4131-
pCustomAnimBlendHierarchy->iHashKey = pAnimHierarchy->iHashKey;
4132-
pCustomAnimBlendHierarchy->iAnimBlockID = pAnimHierarchy->iAnimBlockID;
4133-
pClientPed->setNextAnimationNormal ( );
4134-
printf ("BlendAnimationHierarchyHandler: Found Hierarchy, returning \n");
4135-
return pCustomAnimBlendHierarchy;
4128+
if ( pIFP->isIFPLoaded ( ) )
4129+
{
4130+
SIFPAnimations * pIFPAnimations = pIFP->GetIFPAnimationsPointer ();
4131+
pIFPAnimations->iReferences ++;
4132+
4133+
pClientPed->setCurrentAnimationCustom ( true );
4134+
pClientPed->SetIFPAnimationsPointer ( pIFPAnimations );
4135+
// Modifying a hierarchy like this is just bad, it's much better to create a new CAnimBlendHierarchySAInterface for every animation
4136+
// and then delete it once animation is over
4137+
pCustomAnimBlendHierarchy->iHashKey = pAnimHierarchy->iHashKey;
4138+
pCustomAnimBlendHierarchy->iAnimBlockID = pAnimHierarchy->iAnimBlockID;
4139+
pClientPed->setNextAnimationNormal ( );
4140+
4141+
printf ("BlendAnimationHierarchyHandler: Found Hierarchy, returning \n");
4142+
return pCustomAnimBlendHierarchy;
4143+
}
41364144
}
41374145
else
41384146
{
@@ -6953,7 +6961,7 @@ void CClientGame::OnClientIFPUnload ( const CClientIFP & IFP )
69536961
}
69546962
}
69556963

6956-
void CClientGame::UnloadIFPAnimations ( SIFPAnimations * pIFPAnimations )
6964+
void CClientGame::DeleteIFPAnimations ( SIFPAnimations * pIFPAnimations )
69576965
{
69586966
if ( pIFPAnimations->iReferences == 0 )
69596967
{
@@ -6990,6 +6998,7 @@ void CClientGame::UnloadIFPAnimations ( SIFPAnimations * pIFPAnimations )
69906998
}
69916999
delete ifpAnimation->pSequencesMemory;
69927000
}
7001+
delete pIFPAnimations;
69937002
printf("CClientGame::UnloadIFPAnimations (): IFP Animations have been unloaded successfully!\n");
69947003
}
69957004
}

Client/multiplayer_sa/CMultiplayerSA_CustomAnimations.cpp

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,58 @@ void CMultiplayerSA::SetBlendAnimationHierarchyHandler ( BlendAnimationHierarchy
6060
m_pBlendAnimationHierarchyHandler = pHandler;
6161
}
6262

63-
void InsertAnimationAssociationToMap ( CAnimBlendAssociationSAInterface * pAnimAssociation, SIFPAnimations * pIFPAnimations )
63+
void DeleteIFPAnimations ( SIFPAnimations * pIFPAnimations )
64+
{
65+
if ( pIFPAnimations->iReferences == 0 )
66+
{
67+
printf("CClientGame::UnloadIFPAnimations (): iReferences are Zero\n");
68+
69+
hCMemoryMgr_Free OLD_CMemoryMgr_Free = (hCMemoryMgr_Free)0x0072F430;
70+
auto OLD_CAnimBlendHierarchy_RemoveFromUncompressedCache = (hCAnimBlendHierarchy_RemoveFromUncompressedCache)0x004D42A0;
71+
72+
for ( size_t i = 0; i < pIFPAnimations->vecAnimations.size(); i++ )
73+
{
74+
IFP_Animation * ifpAnimation = &pIFPAnimations->vecAnimations[i];
75+
76+
OLD_CAnimBlendHierarchy_RemoveFromUncompressedCache ( (int)&ifpAnimation->Hierarchy );
77+
78+
for (unsigned short SequenceIndex = 0; SequenceIndex < ifpAnimation->Hierarchy.m_nSeqCount; SequenceIndex++)
79+
{
80+
_CAnimBlendSequence * pSequence = (_CAnimBlendSequence*)((BYTE*)ifpAnimation->Hierarchy.m_pSequences + (sizeof(_CAnimBlendSequence) * SequenceIndex));
81+
82+
if ( !( (pSequence->m_nFlags >> 3) & 1 ) ) // If ( !OneBigChunkForAllSequences )
83+
{
84+
OLD_CMemoryMgr_Free ( pSequence->m_pFrames ); //*(void **)(pThis + 8)); //pSequence->m_pFrames );
85+
}
86+
else
87+
{
88+
if ( SequenceIndex == 0 )
89+
{
90+
// All frames of all sequences are allocated on one memory block, so free that one
91+
// and break the loop
92+
OLD_CMemoryMgr_Free ( pSequence->m_pFrames );
93+
break;
94+
}
95+
}
96+
97+
}
98+
delete ifpAnimation->pSequencesMemory;
99+
}
100+
delete pIFPAnimations;
101+
printf("CClientGame::UnloadIFPAnimations (): IFP Animations have been unloaded successfully!\n");
102+
}
103+
}
104+
105+
void __cdecl InsertAnimationAssociationToMap ( CAnimBlendAssociationSAInterface * pAnimAssociation, SIFPAnimations * pIFPAnimations )
64106
{
65107
// We don't increment pIFPAnimations->iReferences here because it's done
66108
// in custom animation handler functions in CClientGame.cpp
67-
//mapOfCustomAnimationAssociations [ pAnimAssociation ] = pIFPAnimations;
109+
mapOfCustomAnimationAssociations [ pAnimAssociation ] = pIFPAnimations;
110+
68111
printf("InsertAnimationAssociationToMap: sAnimID: %d | iReferences: %d \n", pAnimAssociation->sAnimID, pIFPAnimations->iReferences);
69112
}
70113

71-
void RemoveAnimationAssociationFromMap ( CAnimBlendAssociationSAInterface * pAnimAssociation )
114+
void __cdecl RemoveAnimationAssociationFromMap ( CAnimBlendAssociationSAInterface * pAnimAssociation )
72115
{
73116
AnimAssociations_type::iterator it;
74117
it = mapOfCustomAnimationAssociations.find ( pAnimAssociation );
@@ -79,6 +122,7 @@ void RemoveAnimationAssociationFromMap ( CAnimBlendAssociationSAInterface * pAni
79122
{
80123
// iReferences are zero, custom animation hierarchies are not being used anywhere.
81124
// It's safe to unload IFP animations here.
125+
DeleteIFPAnimations ( it->second );
82126
}
83127
mapOfCustomAnimationAssociations.erase ( pAnimAssociation );
84128
}
@@ -125,7 +169,7 @@ void _declspec(naked) HOOK_CAnimBlendAssoc_Hierarchy_Constructor ()
125169
je NOT_CUSTOM_ANIMATION_CAnimBlendAssoc_Hierarchy_Constructor
126170

127171
push edx // pIFPAnimations
128-
mov ecx, [esp]
172+
mov ecx, [esp+4]
129173
push ecx // pAnimAssociation
130174
call InsertAnimationAssociationToMap
131175
add esp, 8
@@ -151,6 +195,8 @@ void _declspec(naked) HOOK_CAnimBlendAssoc_Hierarchy_Constructor ()
151195

152196
void CAnimBlendAssoc_destructor ( CAnimBlendAssociationSAInterface * pThis )
153197
{
198+
RemoveAnimationAssociationFromMap ( pThis );
199+
154200
if ( m_pCAnimBlendAssocDestructorHandler )
155201
{
156202
m_pCAnimBlendAssocDestructorHandler ( pThis );

0 commit comments

Comments
 (0)