Skip to content

Commit 5ba567d

Browse files
committed
Improved key frames reading logic for IFP Version 2
1 parent b5caa13 commit 5ba567d

File tree

2 files changed

+116
-70
lines changed

2 files changed

+116
-70
lines changed

Client/mods/deathmatch/logic/CClientIFP.cpp

Lines changed: 102 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void CClientIFP::ReadIFPVersion2( bool anp3)
9797
IFP_Animation & ifpAnimation = m_pVecAnimations->at ( i );
9898

9999
CAnimManager * pAnimManager = g_pGame->GetAnimManager ( );
100-
std::unique_ptr < CAnimBlendHierarchy > pAnimationHierarchy = pAnimManager->GetCustomAnimBlendHierarchy ( (CAnimBlendHierarchySAInterface *)&ifpAnimation.Hierarchy );
100+
std::unique_ptr < CAnimBlendHierarchy > pAnimationHierarchy = pAnimManager->GetCustomAnimBlendHierarchy ( &ifpAnimation.Hierarchy );
101101

102102
pAnimationHierarchy->Initialize ( );
103103

@@ -121,8 +121,9 @@ void CClientIFP::ReadIFPVersion2( bool anp3)
121121
pAnimationHierarchy->SetName ( AnimationNode.Name );
122122
pAnimationHierarchy->SetNumSequences ( AnimationNode.TotalObjects );
123123
pAnimationHierarchy->SetAnimationBlockID ( 0 );
124+
pAnimationHierarchy->SetRunningCompressed ( m_kbAllKeyFramesCompressed );
124125

125-
const unsigned short TotalSequences = cIFPSequences + pAnimationHierarchy->GetNumSequences ( );
126+
const unsigned short TotalSequences = m_kcIFPSequences + pAnimationHierarchy->GetNumSequences ( );
126127
ifpAnimation.pSequencesMemory = ( char * ) operator new ( 12 * TotalSequences + 4 ); // Allocate memory for sequences ( 12 * seq_count + 4 )
127128

128129
pAnimationHierarchy->SetSequences ( reinterpret_cast < CAnimBlendSequenceSAInterface * > ( ifpAnimation.pSequencesMemory + 4 ) );
@@ -147,7 +148,7 @@ void CClientIFP::ReadIFPVersion2( bool anp3)
147148
bool bUnknownSequence = ObjectNode.BoneID == -1;
148149
if (bUnknownSequence)
149150
{
150-
size_t UnkownSequenceIndex = cIFPSequences + wUnknownSequences;
151+
size_t UnkownSequenceIndex = m_kcIFPSequences + wUnknownSequences;
151152
pAnimationSequenceInterface = pAnimationHierarchy->GetSequence ( UnkownSequenceIndex );
152153
wUnknownSequences ++;
153154
}
@@ -157,49 +158,15 @@ void CClientIFP::ReadIFPVersion2( bool anp3)
157158
pAnimationSequence->SetName ( ObjectNode.Name );
158159
pAnimationSequence->SetBoneTag ( ObjectNode.BoneID );
159160

160-
if (bFirstSeq)
161+
IFP_FrameType iFrameType = static_cast < IFP_FrameType > ( ObjectNode.FrameType );
162+
size_t iCompressedFrameSize = GetSizeOfCompressedFrame ( iFrameType );
163+
if ( iCompressedFrameSize )
161164
{
162-
bFirstSeq = false;
163-
pAnimationHierarchy->SetRunningCompressed ( ObjectNode.FrameType == 3 || ObjectNode.FrameType == 4 );
164-
}
165-
166-
size_t data_size = 0;
167-
bool bIsRoot;
168-
bool bIsCompressed;
169-
bool bInvalidType = false;
170-
switch (ObjectNode.FrameType)
171-
{
172-
case 1:
173-
data_size = 20 * ObjectNode.TotalFrames; //sizeof(SChildKeyFrame) * seq.frames_count;
174-
bIsRoot = false;
175-
bIsCompressed = false;
176-
break;
177-
case 2:
178-
data_size = 32 * ObjectNode.TotalFrames; //sizeof(SRootKeyFrame) * seq.frames_count;
179-
bIsRoot = true;
180-
bIsCompressed = false;
181-
break;
182-
case 3:
183-
data_size = 10 * ObjectNode.TotalFrames; //sizeof(SCompressedChildKeyFrame) * seq.frames_count;
184-
bIsRoot = false;
185-
bIsCompressed = true;
186-
break;
187-
case 4:
188-
data_size = 16 * ObjectNode.TotalFrames; //sizeof(SCompressedRootKeyFrame) * seq.frames_count;
189-
bIsRoot = true;
190-
bIsCompressed = true;
191-
break;
192-
default:
193-
bInvalidType = true;
194-
break;
195-
}
196-
if (!bInvalidType)
197-
{
198-
unsigned char * pKeyFrames = (unsigned char*) OLD_CMemoryMgr_Malloc ( data_size );
165+
BYTE * pKeyFrames = static_cast < BYTE * > ( OLD_CMemoryMgr_Malloc ( iCompressedFrameSize * ObjectNode.TotalFrames ) );
199166

200-
pAnimationSequence->SetKeyFrames ( ObjectNode.TotalFrames, bIsRoot, bIsCompressed, pKeyFrames );
167+
pAnimationSequence->SetKeyFrames ( ObjectNode.TotalFrames, isKeyFramesTypeRoot ( iFrameType ), m_kbAllKeyFramesCompressed, pKeyFrames );
201168

202-
readBytes ( pKeyFrames, data_size );
169+
ReadKeyFramesAsCompressed ( iFrameType, pKeyFrames, ObjectNode.TotalFrames );
203170

204171
if ( !bUnknownSequence )
205172
{
@@ -210,10 +177,10 @@ void CClientIFP::ReadIFPVersion2( bool anp3)
210177

211178
CopySequencesWithDummies ( pAnimManager, pAnimationHierarchy, MapOfSequences );
212179

213-
*(DWORD *)ifpAnimation.pSequencesMemory = cIFPSequences + wUnknownSequences;
180+
*(DWORD *)ifpAnimation.pSequencesMemory = m_kcIFPSequences + wUnknownSequences;
214181

215182
// This order is very important. As we need support for all 32 bones, we must change the total sequences count
216-
pAnimationHierarchy->SetNumSequences ( cIFPSequences + wUnknownSequences );
183+
pAnimationHierarchy->SetNumSequences ( m_kcIFPSequences + wUnknownSequences );
217184

218185
if ( !pAnimationHierarchy->isRunningCompressed ( ) )
219186
{
@@ -227,7 +194,7 @@ void CClientIFP::ReadIFPVersion2( bool anp3)
227194
void CClientIFP::CopySequencesWithDummies ( CAnimManager * pAnimManager, std::unique_ptr < CAnimBlendHierarchy > & pAnimationHierarchy, std::map < std::string, CAnimBlendSequenceSAInterface > & mapOfSequences )
228195
{
229196
std::map < std::string, CAnimBlendSequenceSAInterface >::iterator it;
230-
for (size_t SequenceIndex = 0; SequenceIndex < cIFPSequences; SequenceIndex++)
197+
for (size_t SequenceIndex = 0; SequenceIndex < m_kcIFPSequences; SequenceIndex++)
231198
{
232199
std::string BoneName = BoneNames[SequenceIndex];
233200
DWORD BoneID = BoneIds[SequenceIndex];
@@ -304,7 +271,7 @@ void CClientIFP::ReadIFPVersion1 ( )
304271
pAnimHierarchy->m_nAnimBlockId = 0;
305272
pAnimHierarchy->field_B = 0;
306273
307-
const unsigned short TotalSequences = cIFPSequences + pAnimHierarchy->m_nSeqCount;
274+
const unsigned short TotalSequences = m_kcIFPSequences + pAnimHierarchy->m_nSeqCount;
308275
ifpAnimation.pSequencesMemory = ( char * ) operator new ( 12 * TotalSequences + 4 ); // Allocate memory for sequences ( 12 * seq_count + 4 )
309276
310277
pAnimHierarchy->m_pSequences = ( _CAnimBlendSequence * )( ifpAnimation.pSequencesMemory+ 4 );
@@ -363,7 +330,7 @@ void CClientIFP::ReadIFPVersion1 ( )
363330
_CAnimBlendSequence * pUnkownSequence = nullptr;
364331
if (bUnknownSequence)
365332
{
366-
size_t UnkownSequenceIndex = cIFPSequences + wUnknownSequences;
333+
size_t UnkownSequenceIndex = m_kcIFPSequences + wUnknownSequences;
367334
pUnkownSequence = (_CAnimBlendSequence*)((BYTE*)pAnimHierarchy->m_pSequences + (sizeof(_CAnimBlendSequence) * UnkownSequenceIndex));
368335
369336
_CAnimBlendSequence_Constructor ( pUnkownSequence );
@@ -394,11 +361,11 @@ void CClientIFP::ReadIFPVersion1 ( )
394361
bool bIsRoot = FrameType != IFP_FrameType::KR00;
395362
if (bUnknownSequence)
396363
{
397-
OLD__CAnimBlendSequence_SetNumFrames ( pUnkownSequence, Anim.Frames, bIsRoot, pAnimHierarchy->m_bRunningCompressed, pKeyFrames );
364+
OLD__CAnimBlendSequence_SetNumFrames ( pUnkownSequence, Anim.Frames, bIsRoot, m_kbAllKeyFramesCompressed, pKeyFrames );
398365
}
399366
else
400367
{
401-
OLD__CAnimBlendSequence_SetNumFrames ( &Sequence, Anim.Frames, bIsRoot, pAnimHierarchy->m_bRunningCompressed, pKeyFrames );
368+
OLD__CAnimBlendSequence_SetNumFrames ( &Sequence, Anim.Frames, bIsRoot, m_kbAllKeyFramesCompressed, pKeyFrames );
402369
}
403370
404371
if (FrameType == IFP_FrameType::KRTS)
@@ -426,7 +393,7 @@ void CClientIFP::ReadIFPVersion1 ( )
426393
}
427394
428395
std::map < std::string, _CAnimBlendSequence >::iterator it;
429-
for (size_t SequenceIndex = 0; SequenceIndex < cIFPSequences; SequenceIndex++)
396+
for (size_t SequenceIndex = 0; SequenceIndex < m_kcIFPSequences; SequenceIndex++)
430397
{
431398
std::string BoneName = BoneNames[SequenceIndex];
432399
DWORD BoneID = BoneIds[SequenceIndex];
@@ -446,10 +413,10 @@ void CClientIFP::ReadIFPVersion1 ( )
446413
}
447414
}
448415
449-
*(DWORD *)ifpAnimation.pSequencesMemory = cIFPSequences + wUnknownSequences;
416+
*(DWORD *)ifpAnimation.pSequencesMemory = m_kcIFPSequences + wUnknownSequences;
450417
451418
// This order is very important. As we need support for all 32 bones, we must change the total sequences count
452-
pAnimHierarchy->m_nSeqCount = cIFPSequences + wUnknownSequences;
419+
pAnimHierarchy->m_nSeqCount = m_kcIFPSequences + wUnknownSequences;
453420
454421
//ofs << std::endl << std::endl;
455422
@@ -463,6 +430,38 @@ void CClientIFP::ReadIFPVersion1 ( )
463430
}
464431

465432

433+
void CClientIFP::ReadKeyFramesAsCompressed ( IFP_FrameType iFrameType, BYTE * pKeyFrames, int32_t iFrames )
434+
{
435+
switch ( iFrameType )
436+
{
437+
case IFP_FrameType::KRTS:
438+
{
439+
ReadKrtsFramesAsCompressed ( pKeyFrames, iFrames );
440+
break;
441+
}
442+
case IFP_FrameType::KRT0:
443+
{
444+
ReadKrt0FramesAsCompressed ( pKeyFrames, iFrames );
445+
break;
446+
}
447+
case IFP_FrameType::KR00:
448+
{
449+
ReadKr00FramesAsCompressed ( pKeyFrames, iFrames );
450+
break;
451+
}
452+
case IFP_FrameType::KR00_COMPRESSED:
453+
{
454+
ReadKr00CompressedFrames ( pKeyFrames, iFrames );
455+
break;
456+
}
457+
case IFP_FrameType::KRT0_COMPRESSED:
458+
{
459+
ReadKrt0CompressedFrames ( pKeyFrames, iFrames );
460+
break;
461+
}
462+
}
463+
}
464+
466465
void CClientIFP::ReadKrtsFramesAsCompressed ( BYTE * pKeyFrames, int32_t TotalFrames )
467466
{
468467
for (int32_t FrameIndex = 0; FrameIndex < TotalFrames; FrameIndex++)
@@ -526,20 +525,42 @@ void CClientIFP::ReadKr00FramesAsCompressed ( BYTE * pKeyFrames, int32_t TotalF
526525
}
527526
}
528527

528+
void CClientIFP::ReadKr00CompressedFrames ( BYTE * pKeyFrames, int32_t TotalFrames )
529+
{
530+
size_t iSizeInBytes = sizeof ( IFP_Compressed_KR00 ) * TotalFrames;
531+
readBytes ( pKeyFrames, iSizeInBytes );
532+
}
529533

530-
size_t CClientIFP::GetSizeOfCompressedFrame ( IFP_FrameType FrameType )
534+
void CClientIFP::ReadKrt0CompressedFrames ( BYTE * pKeyFrames, int32_t TotalFrames )
531535
{
532-
if (FrameType == IFP_FrameType::KRTS)
533-
{
534-
return sizeof(IFP_Compressed_KRT0);
535-
}
536-
else if (FrameType == IFP_FrameType::KRT0)
537-
{
538-
return sizeof(IFP_Compressed_KRT0);
539-
}
540-
else if (FrameType == IFP_FrameType::KR00)
541-
{
542-
return sizeof(IFP_Compressed_KR00);
536+
size_t iSizeInBytes = sizeof ( IFP_Compressed_KRT0 ) * TotalFrames;
537+
readBytes ( pKeyFrames, iSizeInBytes );
538+
}
539+
540+
size_t CClientIFP::GetSizeOfCompressedFrame ( IFP_FrameType iFrameType )
541+
{
542+
switch ( iFrameType )
543+
{
544+
case IFP_FrameType::KRTS:
545+
{
546+
return sizeof ( IFP_Compressed_KRT0 );
547+
}
548+
case IFP_FrameType::KRT0:
549+
{
550+
return sizeof ( IFP_Compressed_KRT0 );
551+
}
552+
case IFP_FrameType::KR00:
553+
{
554+
return sizeof ( IFP_Compressed_KR00 );
555+
}
556+
case IFP_FrameType::KR00_COMPRESSED:
557+
{
558+
return sizeof ( IFP_Compressed_KR00 );
559+
}
560+
case IFP_FrameType::KRT0_COMPRESSED:
561+
{
562+
return sizeof ( IFP_Compressed_KRT0 );
563+
}
543564
}
544565
return 0;
545566
}
@@ -1077,6 +1098,22 @@ constexpr void CClientIFP::RoundSize ( uint32_t & u32Size )
10771098
}
10781099
}
10791100

1101+
constexpr bool CClientIFP::isKeyFramesTypeRoot ( IFP_FrameType iFrameType )
1102+
{
1103+
switch ( iFrameType )
1104+
{
1105+
case IFP_FrameType::KR00:
1106+
{
1107+
return false;
1108+
}
1109+
case IFP_FrameType::KR00_COMPRESSED:
1110+
{
1111+
return false;
1112+
}
1113+
}
1114+
return true;
1115+
}
1116+
10801117
void CClientIFP::ParseSequenceObject ( Object & ObjectNode, std::string & CorrectBoneName )
10811118
{
10821119
std::string BoneName = convertStringToMapKey ( ObjectNode.Name );

Client/mods/deathmatch/logic/CClientIFP.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,12 @@ class CClientIFP: public CClientEntity, FileLoader
123123

124124
enum IFP_FrameType
125125
{
126-
UNKNOWN_FRAME = -1,
127-
KR00 = 0,
128-
KRT0 = 1,
129-
KRTS = 2
126+
UNKNOWN_FRAME = -1,
127+
KR00 = 0,
128+
KRT0 = 1,
129+
KRTS = 2,
130+
KR00_COMPRESSED = 3,
131+
KRT0_COMPRESSED = 4,
130132
};
131133

132134
struct IFPHeaderV2
@@ -215,9 +217,12 @@ class CClientIFP: public CClientEntity, FileLoader
215217
IFP_FrameType getFrameTypeFromFourCC(char * FourCC);
216218
size_t GetSizeOfCompressedFrame ( IFP_FrameType FrameType );
217219

220+
void ReadKeyFramesAsCompressed ( IFP_FrameType iFrameType, BYTE * pKeyFrames, int32_t iFrames );
218221
void ReadKrtsFramesAsCompressed ( BYTE * pKeyFrames, int32_t TotalFrames );
219222
void ReadKrt0FramesAsCompressed ( BYTE * pKeyFrames, int32_t TotalFrames );
220223
void ReadKr00FramesAsCompressed ( BYTE * pKeyFrames, int32_t TotalFrames );
224+
void ReadKr00CompressedFrames ( BYTE * pKeyFrames, int32_t TotalFrames );
225+
void ReadKrt0CompressedFrames ( BYTE * pKeyFrames, int32_t TotalFrames );
221226

222227
void InsertAnimationDummySequence ( std::unique_ptr < CAnimBlendSequence > & pAnimationSequence, std::string & BoneName, DWORD & BoneID );
223228
int32_t getBoneIDFromName(std::string const& BoneName);
@@ -226,6 +231,7 @@ class CClientIFP: public CClientEntity, FileLoader
226231
size_t getCorrectBoneIndexFromID(int32_t & BoneID);
227232

228233
constexpr void RoundSize ( uint32_t & u32Size );
234+
constexpr bool isKeyFramesTypeRoot ( IFP_FrameType iFrameType );
229235
void ParseSequenceObject ( Object & ObjectNode, std::string & CorrectBoneName );
230236

231237
CAnimBlendHierarchySAInterface * GetAnimationHierarchy ( const SString & strAnimationName );
@@ -245,7 +251,10 @@ class CClientIFP: public CClientEntity, FileLoader
245251
IFPHeaderV2 HeaderV2;
246252

247253
// 32 because there are 32 bones in a ped model
248-
const unsigned short cIFPSequences = 32;
254+
const unsigned short m_kcIFPSequences = 32;
255+
// We'll keep all key frames compressed by default. GTA:SA will decompress
256+
// them, when it's going to play the animation. We don't need to worry about it.
257+
const bool m_kbAllKeyFramesCompressed = true;
249258

250259
};
251260

0 commit comments

Comments
 (0)