summaryrefslogtreecommitdiffstats
path: root/src/animation
diff options
context:
space:
mode:
Diffstat (limited to 'src/animation')
-rw-r--r--src/animation/AnimBlendAssocGroup.cpp53
-rw-r--r--src/animation/AnimBlendAssocGroup.h4
-rw-r--r--src/animation/AnimBlendAssociation.cpp45
-rw-r--r--src/animation/AnimBlendAssociation.h26
-rw-r--r--src/animation/AnimBlendClumpData.cpp1
-rw-r--r--src/animation/AnimBlendClumpData.h18
-rw-r--r--src/animation/AnimBlendHierarchy.cpp67
-rw-r--r--src/animation/AnimBlendHierarchy.h5
-rw-r--r--src/animation/AnimBlendNode.cpp55
-rw-r--r--src/animation/AnimBlendNode.h2
-rw-r--r--src/animation/AnimBlendSequence.cpp135
-rw-r--r--src/animation/AnimBlendSequence.h27
-rw-r--r--src/animation/AnimManager.cpp1073
-rw-r--r--src/animation/AnimManager.h59
-rw-r--r--src/animation/AnimationId.h169
-rw-r--r--src/animation/Bones.cpp73
-rw-r--r--src/animation/Bones.h38
-rw-r--r--src/animation/CutsceneMgr.cpp530
-rw-r--r--src/animation/CutsceneMgr.h12
-rw-r--r--src/animation/FrameUpdate.cpp33
-rw-r--r--src/animation/RpAnimBlend.cpp105
-rw-r--r--src/animation/RpAnimBlend.h5
22 files changed, 1746 insertions, 789 deletions
diff --git a/src/animation/AnimBlendAssocGroup.cpp b/src/animation/AnimBlendAssocGroup.cpp
index fe419f2a..83c1742a 100644
--- a/src/animation/AnimBlendAssocGroup.cpp
+++ b/src/animation/AnimBlendAssocGroup.cpp
@@ -8,16 +8,22 @@
#include "General.h"
#include "RwHelper.h"
+#include "ModelIndices.h"
#include "ModelInfo.h"
#include "AnimManager.h"
#include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
#include "AnimBlendAssocGroup.h"
+//--MIAMI: file done
+
CAnimBlendAssocGroup::CAnimBlendAssocGroup(void)
{
+ animBlock = nil;
assocList = nil;
numAssociations = 0;
+ firstAnimId = 0;
+ groupId = -1;
}
CAnimBlendAssocGroup::~CAnimBlendAssocGroup(void)
@@ -38,7 +44,7 @@ CAnimBlendAssocGroup::DestroyAssociations(void)
CAnimBlendAssociation*
CAnimBlendAssocGroup::GetAnimation(uint32 id)
{
- return &assocList[id];
+ return &assocList[id - firstAnimId];
}
CAnimBlendAssociation*
@@ -48,6 +54,7 @@ CAnimBlendAssocGroup::GetAnimation(const char *name)
for(i = 0; i < numAssociations; i++)
if(!CGeneral::faststricmp(assocList[i].hierarchy->name, name))
return &assocList[i];
+ debug("\n\nCan't find the fucking animation %s\n\n\n", name);
return nil;
}
@@ -97,7 +104,7 @@ strcmpIgnoringDigits(const char *s1, const char *s2)
c2 = toupper(c2);
#endif
- if(c1 != c2)
+ if(c1 && c2 && c1 != c2)
return false;
}
}
@@ -107,6 +114,15 @@ GetModelFromName(const char *name)
{
int i;
CBaseModelInfo *mi;
+ char playername[32];
+
+ if(strncasecmp(name, "CSplay", 6) == 0 &&
+ strncasecmp(CModelInfo::GetModelInfo(MI_PLAYER)->GetName(), "ig", 2) == 0){
+ strcpy(playername, CModelInfo::GetModelInfo(MI_PLAYER)->GetName());
+ playername[0] = 'C';
+ playername[1] = 'S';
+ name = playername;
+ }
for(i = 0; i < MODELINFOSIZE; i++){
mi = CModelInfo::GetModelInfo(i);
@@ -123,8 +139,7 @@ CAnimBlendAssocGroup::CreateAssociations(const char *name)
int i;
CAnimBlock *animBlock;
- if(assocList)
- DestroyAssociations();
+ DestroyAssociations();
animBlock = CAnimManager::GetAnimationBlock(name);
assocList = new CAnimBlendAssociation[animBlock->numAnims];
@@ -133,17 +148,18 @@ CAnimBlendAssocGroup::CreateAssociations(const char *name)
for(i = 0; i < animBlock->numAnims; i++){
CAnimBlendHierarchy *anim = CAnimManager::GetAnimation(animBlock->firstIndex + i);
CBaseModelInfo *model = GetModelFromName(anim->name);
- assert(model);
- printf("Associated anim %s with model %s\n", anim->name, model->GetName());
- RpClump *clump = (RpClump*)model->CreateInstance();
-#ifdef PED_SKIN
- if(IsClumpSkinned(clump))
- RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil);
-#endif
- RpAnimBlendClumpInit(clump);
- assocList[i].Init(clump, anim);
- RpClumpDestroy(clump);
- assocList[i].animId = i;
+ if(model){
+ debug("Associated anim %s with model %s\n", anim->name, model->GetName());
+ RpClump *clump = (RpClump*)model->CreateInstance();
+ RpAnimBlendClumpInit(clump);
+ assocList[i].Init(clump, anim);
+ if(IsClumpSkinned(clump))
+ RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil);
+ RpClumpDestroy(clump);
+ assocList[i].animId = firstAnimId + i;
+ assocList[i].groupId = groupId;
+ }else
+ debug("\n\nCANNOT FIND MODELINFO WITH NAME %s\n\n\n", anim->name);
}
numAssociations = animBlock->numAnims;
}
@@ -153,10 +169,8 @@ void
CAnimBlendAssocGroup::CreateAssociations(const char *blockName, RpClump *clump, const char **animNames, int numAssocs)
{
int i;
- CAnimBlock *animBlock;
- if(assocList)
- DestroyAssociations();
+ DestroyAssociations();
animBlock = CAnimManager::GetAnimationBlock(blockName);
assocList = new CAnimBlendAssociation[numAssocs];
@@ -164,7 +178,8 @@ CAnimBlendAssocGroup::CreateAssociations(const char *blockName, RpClump *clump,
numAssociations = 0;
for(i = 0; i < numAssocs; i++){
assocList[i].Init(clump, CAnimManager::GetAnimation(animNames[i], animBlock));
- assocList[i].animId = i;
+ assocList[i].animId = firstAnimId + i;
+ assocList[i].groupId = groupId;
}
numAssociations = numAssocs;
}
diff --git a/src/animation/AnimBlendAssocGroup.h b/src/animation/AnimBlendAssocGroup.h
index aa58b0d3..86f0ca18 100644
--- a/src/animation/AnimBlendAssocGroup.h
+++ b/src/animation/AnimBlendAssocGroup.h
@@ -1,12 +1,16 @@
#pragma once
class CAnimBlendAssociation;
+struct CAnimBlock;
class CAnimBlendAssocGroup
{
public:
+ CAnimBlock *animBlock;
CAnimBlendAssociation *assocList;
int32 numAssociations;
+ int32 firstAnimId;
+ int32 groupId; // id of self in ms_aAnimAssocGroups
CAnimBlendAssocGroup(void);
~CAnimBlendAssocGroup(void);
diff --git a/src/animation/AnimBlendAssociation.cpp b/src/animation/AnimBlendAssociation.cpp
index b03571b0..2f4739a6 100644
--- a/src/animation/AnimBlendAssociation.cpp
+++ b/src/animation/AnimBlendAssociation.cpp
@@ -7,8 +7,11 @@
#include "AnimBlendAssociation.h"
#include "MemoryMgr.h"
+//--MIAMI: file done
+
CAnimBlendAssociation::CAnimBlendAssociation(void)
{
+ groupId = -1;
nodes = nil;
blendAmount = 1.0f;
blendDelta = 0.0f;
@@ -54,8 +57,8 @@ CAnimBlendAssociation::AllocateAnimBlendNodeArray(int n)
void
CAnimBlendAssociation::FreeAnimBlendNodeArray(void)
{
- assert(nodes != nil);
- RwFreeAlign(nodes);
+ if(nodes)
+ RwFreeAlign(nodes);
}
void
@@ -75,7 +78,10 @@ CAnimBlendAssociation::Init(RpClump *clump, CAnimBlendHierarchy *hier)
// NB: This is where the order of nodes is defined
for(i = 0; i < hier->numSequences; i++){
CAnimBlendSequence *seq = &hier->sequences[i];
- frame = RpAnimBlendClumpFindFrame(clump, seq->name);
+ if(seq->boneTag == -1)
+ frame = RpAnimBlendClumpFindFrame(clump, seq->name);
+ else
+ frame = RpAnimBlendClumpFindBone(clump, seq->boneTag);
if(frame && seq->numFrames > 0)
nodes[frame - clumpData->frames].sequence = seq;
}
@@ -90,6 +96,7 @@ CAnimBlendAssociation::Init(CAnimBlendAssociation &assoc)
numNodes = assoc.numNodes;
flags = assoc.flags;
animId = assoc.animId;
+ groupId = assoc.groupId;
AllocateAnimBlendNodeArray(numNodes);
for(i = 0; i < numNodes; i++){
nodes[i] = assoc.nodes[i];
@@ -126,12 +133,21 @@ CAnimBlendAssociation::SetCurrentTime(float time)
int i;
for(currentTime = time; currentTime >= hierarchy->totalLength; currentTime -= hierarchy->totalLength)
- if(!IsRepeating())
- return;
+ if (!IsRepeating()) {
+ currentTime = hierarchy->totalLength;
+ break;
+ }
+
CAnimManager::UncompressAnimation(hierarchy);
- for(i = 0; i < numNodes; i++)
- if(nodes[i].sequence)
- nodes[i].FindKeyFrame(currentTime);
+ if(hierarchy->compressed2){
+ for(i = 0; i < numNodes; i++)
+ if(nodes[i].sequence)
+ nodes[i].SetupKeyFrameCompressed();
+ }else{
+ for(i = 0; i < numNodes; i++)
+ if(nodes[i].sequence)
+ nodes[i].FindKeyFrame(currentTime);
+ }
}
void
@@ -147,13 +163,23 @@ CAnimBlendAssociation::Start(float time)
SetCurrentTime(time);
}
+void
+CAnimBlendAssociation::UpdateTimeStep(float timeDelta, float relSpeed)
+{
+ if(IsRunning())
+ timeStep = (flags & ASSOC_MOVEMENT ? relSpeed*hierarchy->totalLength : speed) * timeDelta;
+}
+
bool
CAnimBlendAssociation::UpdateTime(float timeDelta, float relSpeed)
{
if(!IsRunning())
return true;
+ if(currentTime >= hierarchy->totalLength){
+ flags &= ~ASSOC_RUNNING;
+ return true;
+ }
- timeStep = (flags & ASSOC_MOVEMENT ? relSpeed*hierarchy->totalLength : speed) * timeDelta;
currentTime += timeStep;
if(currentTime >= hierarchy->totalLength){
@@ -163,7 +189,6 @@ CAnimBlendAssociation::UpdateTime(float timeDelta, float relSpeed)
currentTime -= hierarchy->totalLength;
else{
currentTime = hierarchy->totalLength;
- flags &= ~ASSOC_RUNNING;
if(flags & ASSOC_FADEOUTWHENDONE){
flags |= ASSOC_DELETEFADEDOUT;
blendDelta = -4.0f;
diff --git a/src/animation/AnimBlendAssociation.h b/src/animation/AnimBlendAssociation.h
index 80927da2..dbfcb722 100644
--- a/src/animation/AnimBlendAssociation.h
+++ b/src/animation/AnimBlendAssociation.h
@@ -12,12 +12,13 @@ enum {
ASSOC_PARTIAL = 0x10,
ASSOC_MOVEMENT = 0x20, // ???
ASSOC_HAS_TRANSLATION = 0x40,
- ASSOC_WALK = 0x80, // for CPed::PlayFootSteps(void)
- ASSOC_IDLE = 0x100, // only used by xpress scratch, see CPed::Chat(void)
- ASSOC_NOWALK = 0x200, // see CPed::PlayFootSteps(void)
- ASSOC_BLOCK = 0x400, // unused in assoc description, blocks other anims from being played
- ASSOC_FRONTAL = 0x800, // anims that we fall to front
- ASSOC_HAS_X_TRANSLATION = 0x1000, // for 2d velocity extraction
+ ASSOC_HAS_X_TRANSLATION = 0x80, // for 2d velocity extraction
+ ASSOC_WALK = 0x100, // for CPed::PlayFootSteps(void)
+ ASSOC_IDLE = 0x200, // only xpress scratch has it by default, but game adds it to player's idle animations later
+ ASSOC_NOWALK = 0x400, // see CPed::PlayFootSteps(void)
+ ASSOC_BLOCK = 0x800, // unused in assoc description, blocks other anims from being played
+ ASSOC_FRONTAL = 0x1000, // anims that we fall to front
+ ASSOC_DRIVING = 0x2000, // new in VC
};
// Anim hierarchy associated with a clump
@@ -35,7 +36,8 @@ public:
CAnimBlendLink link;
- int numNodes; // taken from CAnimBlendClumpData::numFrames
+ int16 numNodes; // taken from CAnimBlendClumpData::numFrames
+ int16 groupId; // ID of CAnimBlendAssocGroup this is in
// NB: Order of these depends on order of nodes in Clump this was built from
CAnimBlendNode *nodes;
CAnimBlendHierarchy *hierarchy;
@@ -44,8 +46,8 @@ public:
float currentTime;
float speed;
float timeStep;
- int32 animId;
- int32 flags;
+ int16 animId;
+ int16 flags;
int32 callbackType;
void (*callback)(CAnimBlendAssociation*, void*);
void *callbackArg;
@@ -76,16 +78,16 @@ public:
void SetCurrentTime(float time);
void SyncAnimation(CAnimBlendAssociation *other);
void Start(float time);
+ void UpdateTimeStep(float timeDelta, float relSpeed);
bool UpdateTime(float timeDelta, float relSpeed);
bool UpdateBlend(float timeDelta);
void SetRun(void) { flags |= ASSOC_RUNNING; }
- inline float GetTimeLeft() { return hierarchy->totalLength - currentTime; }
+ float GetTimeLeft() { return hierarchy->totalLength - currentTime; }
+ float GetProgress() { return currentTime / hierarchy->totalLength; }
static CAnimBlendAssociation *FromLink(CAnimBlendLink *l) {
return (CAnimBlendAssociation*)((uint8*)l - offsetof(CAnimBlendAssociation, link));
}
};
-
-VALIDATE_SIZE(CAnimBlendAssociation, 0x40);
diff --git a/src/animation/AnimBlendClumpData.cpp b/src/animation/AnimBlendClumpData.cpp
index 92515427..4e8f3153 100644
--- a/src/animation/AnimBlendClumpData.cpp
+++ b/src/animation/AnimBlendClumpData.cpp
@@ -3,6 +3,7 @@
#include "AnimBlendClumpData.h"
#include "MemoryMgr.h"
+//--MIAMI: file done
CAnimBlendClumpData::CAnimBlendClumpData(void)
{
diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h
index fc74b42d..315cbd8a 100644
--- a/src/animation/AnimBlendClumpData.h
+++ b/src/animation/AnimBlendClumpData.h
@@ -11,23 +11,19 @@ struct AnimBlendFrameData
IGNORE_TRANSLATION = 4,
VELOCITY_EXTRACTION = 8,
VELOCITY_EXTRACTION_3D = 0x10,
+ UPDATE_KEYFRAMES = 0x20,
+ UNK_COMPRESSED = 0x40,
};
uint8 flag;
RwV3d resetPos;
-#ifdef PED_SKIN
union {
RwFrame *frame;
RpHAnimStdInterpFrame *hanimFrame;
};
int32 nodeID;
-#else
- RwFrame *frame;
-#endif
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(AnimBlendFrameData, 0x14);
-#endif
+VALIDATE_SIZE(AnimBlendFrameData, 0x18);
class CAnimBlendClumpData
@@ -35,9 +31,6 @@ class CAnimBlendClumpData
public:
CAnimBlendLink link;
int32 numFrames;
-#ifdef PED_SKIN
- int32 modelNumber; // doesn't seem to be used
-#endif
CVector *velocity;
// order of frames is determined by RW hierarchy
AnimBlendFrameData *frames;
@@ -45,11 +38,6 @@ public:
CAnimBlendClumpData(void);
~CAnimBlendClumpData(void);
void SetNumberOfFrames(int n);
-#ifdef PED_SKIN
void SetNumberOfBones(int n) { SetNumberOfFrames(n); }
-#endif
void ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *arg);
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CAnimBlendClumpData, 0x14);
-#endif
diff --git a/src/animation/AnimBlendHierarchy.cpp b/src/animation/AnimBlendHierarchy.cpp
index c7800de5..f3e90818 100644
--- a/src/animation/AnimBlendHierarchy.cpp
+++ b/src/animation/AnimBlendHierarchy.cpp
@@ -2,6 +2,9 @@
#include "AnimBlendSequence.h"
#include "AnimBlendHierarchy.h"
+#include "AnimManager.h"
+
+//--MIAMI: file done
CAnimBlendHierarchy::CAnimBlendHierarchy(void)
{
@@ -15,9 +18,10 @@ CAnimBlendHierarchy::CAnimBlendHierarchy(void)
void
CAnimBlendHierarchy::Shutdown(void)
{
+ CAnimManager::RemoveFromUncompressedCache(this);
RemoveAnimSequences();
+ totalLength = 0.0f;
compressed = 0;
- linkPtr = nil;
}
void
@@ -30,13 +34,43 @@ void
CAnimBlendHierarchy::CalcTotalTime(void)
{
int i, j;
+
+ totalLength = 0.0f;
+
+ for(i = 0; i < numSequences; i++){
+#ifdef FIX_BUGS
+ if(sequences[i].numFrames == 0)
+ continue;
+#endif
+
+ totalLength = Max(totalLength, sequences[i].GetKeyFrame(sequences[i].numFrames-1)->deltaTime);
+ for(j = sequences[i].numFrames-1; j >= 1; j--){
+ KeyFrame *kf1 = sequences[i].GetKeyFrame(j);
+ KeyFrame *kf2 = sequences[i].GetKeyFrame(j-1);
+ kf1->deltaTime -= kf2->deltaTime;
+ }
+ }
+}
+
+void
+CAnimBlendHierarchy::CalcTotalTimeCompressed(void)
+{
+ int i, j;
+
totalLength = 0.0f;
for(i = 0; i < numSequences; i++){
- float seqTime = 0.0f;
- for(j = 0; j < sequences[i].numFrames; j++)
- seqTime += sequences[i].GetKeyFrame(j)->deltaTime;
- totalLength = Max(totalLength, seqTime);
+#ifdef FIX_BUGS
+ if(sequences[i].numFrames == 0)
+ continue;
+#endif
+
+ totalLength = Max(totalLength, sequences[i].GetKeyFrameCompressed(sequences[i].numFrames-1)->deltaTime/60.0f);
+ for(j = sequences[i].numFrames-1; j >= 1; j--){
+ KeyFrame *kf1 = sequences[i].GetKeyFrameCompressed(j);
+ KeyFrame *kf2 = sequences[i].GetKeyFrameCompressed(j-1);
+ kf1->deltaTime -= kf2->deltaTime;
+ }
}
}
@@ -52,34 +86,25 @@ CAnimBlendHierarchy::RemoveQuaternionFlips(void)
void
CAnimBlendHierarchy::RemoveAnimSequences(void)
{
- if(sequences)
- delete[] sequences;
+ delete[] sequences;
+ sequences = nil;
numSequences = 0;
}
void
CAnimBlendHierarchy::Uncompress(void)
{
-#ifdef ANIM_COMPRESSION
- int i;
- assert(compressed);
- for(i = 0; i < numSequences; i++)
- sequences[i].Uncompress();
-#endif
- if(totalLength == 0.0f)
- CalcTotalTime();
compressed = 0;
+ if(totalLength == 0.0f){
+ RemoveQuaternionFlips();
+ CalcTotalTime();
+ }
}
void
CAnimBlendHierarchy::RemoveUncompressedData(void)
{
-#ifdef ANIM_COMPRESSION
- int i;
- assert(!compressed);
- for(i = 0; i < numSequences; i++)
- sequences[i].RemoveUncompressedData();
-#endif
+ // useless
compressed = 1;
}
diff --git a/src/animation/AnimBlendHierarchy.h b/src/animation/AnimBlendHierarchy.h
index e35b4925..424a925d 100644
--- a/src/animation/AnimBlendHierarchy.h
+++ b/src/animation/AnimBlendHierarchy.h
@@ -15,7 +15,8 @@ public:
char name[24];
CAnimBlendSequence *sequences;
int16 numSequences;
- int16 compressed; // not really used
+ bool compressed; // not really used
+ bool compressed2; // not really used
float totalLength;
CLink<CAnimBlendHierarchy*> *linkPtr;
@@ -23,11 +24,13 @@ public:
void Shutdown(void);
void SetName(char *name);
void CalcTotalTime(void);
+ void CalcTotalTimeCompressed(void);
void RemoveQuaternionFlips(void);
void RemoveAnimSequences(void);
void Uncompress(void);
void RemoveUncompressedData(void);
void MoveMemory(bool onlyone = false);
+ bool IsCompressed() { return !!compressed; };
};
VALIDATE_SIZE(CAnimBlendHierarchy, 0x28); \ No newline at end of file
diff --git a/src/animation/AnimBlendNode.cpp b/src/animation/AnimBlendNode.cpp
index df6cd1d5..ac1328eb 100644
--- a/src/animation/AnimBlendNode.cpp
+++ b/src/animation/AnimBlendNode.cpp
@@ -3,6 +3,8 @@
#include "AnimBlendAssociation.h"
#include "AnimBlendNode.h"
+//--MIAMI: file done
+
void
CAnimBlendNode::Init(void)
{
@@ -92,20 +94,22 @@ CAnimBlendNode::FindKeyFrame(float t)
frameA = 0;
frameB = frameA;
- if(sequence->numFrames >= 2){
- frameA++;
-
+ if(sequence->numFrames == 1){
+ remainingTime = 0.0f;
+ }else{
// advance until t is between frameB and frameA
- while(t > sequence->GetKeyFrame(frameA)->deltaTime){
+ while (t > sequence->GetKeyFrame(++frameA)->deltaTime) {
t -= sequence->GetKeyFrame(frameA)->deltaTime;
- frameB = frameA++;
- if(frameA >= sequence->numFrames){
+ if (frameA + 1 >= sequence->numFrames) {
// reached end of animation
- if(!association->IsRepeating())
+ if (!association->IsRepeating()) {
+ CalcDeltas();
+ remainingTime = 0.0f;
return false;
+ }
frameA = 0;
- frameB = 0;
}
+ frameB = frameA;
}
remainingTime = sequence->GetKeyFrame(frameA)->deltaTime - t;
@@ -115,6 +119,25 @@ CAnimBlendNode::FindKeyFrame(float t)
return true;
}
+bool
+CAnimBlendNode::SetupKeyFrameCompressed(void)
+{
+ if(sequence->numFrames < 1)
+ return false;
+
+ frameA = 1;
+ frameB = 0;
+
+ if(sequence->numFrames == 1){
+ frameA = 0;
+ remainingTime = 0.0f;
+ }else
+ remainingTime = sequence->GetKeyFrameCompressed(frameA)->deltaTime/60.0f;
+
+ CalcDeltasCompressed();
+ return true;
+}
+
void
CAnimBlendNode::CalcDeltas(void)
{
@@ -130,6 +153,20 @@ CAnimBlendNode::CalcDeltas(void)
}
void
+CAnimBlendNode::CalcDeltasCompressed(void)
+{
+ if((sequence->type & CAnimBlendSequence::KF_ROT) == 0)
+ return;
+ KeyFrame *kfA = sequence->GetKeyFrameCompressed(frameA);
+ KeyFrame *kfB = sequence->GetKeyFrameCompressed(frameB);
+ float cos = DotProduct(kfA->rotation, kfB->rotation);
+ if(cos > 1.0f)
+ cos = 1.0f;
+ theta = Acos(cos);
+ invSin = theta == 0.0f ? 0.0f : 1.0f/Sin(theta);
+}
+
+void
CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
{
trans = CVector(0.0f, 0.0f, 0.0f);
@@ -138,7 +175,7 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
if(blend > 0.0f){
KeyFrameTrans *kfA = (KeyFrameTrans*)sequence->GetKeyFrame(frameA);
KeyFrameTrans *kfB = (KeyFrameTrans*)sequence->GetKeyFrame(frameB);
- float t = (kfA->deltaTime - remainingTime)/kfA->deltaTime;
+ float t = kfA->deltaTime == 0.0f ? 0.0f : (kfA->deltaTime - remainingTime)/kfA->deltaTime;
if(sequence->type & CAnimBlendSequence::KF_TRANS){
trans = kfB->translation + t*(kfA->translation - kfB->translation);
trans *= blend;
diff --git a/src/animation/AnimBlendNode.h b/src/animation/AnimBlendNode.h
index 89924d6a..9446e1ae 100644
--- a/src/animation/AnimBlendNode.h
+++ b/src/animation/AnimBlendNode.h
@@ -22,7 +22,9 @@ public:
bool Update(CVector &trans, CQuaternion &rot, float weight);
bool NextKeyFrame(void);
bool FindKeyFrame(float t);
+ bool SetupKeyFrameCompressed(void);
void CalcDeltas(void);
+ void CalcDeltasCompressed(void);
void GetCurrentTranslation(CVector &trans, float weight);
void GetEndTranslation(CVector &trans, float weight);
};
diff --git a/src/animation/AnimBlendSequence.cpp b/src/animation/AnimBlendSequence.cpp
index c958b71a..3c675d4e 100644
--- a/src/animation/AnimBlendSequence.cpp
+++ b/src/animation/AnimBlendSequence.cpp
@@ -3,22 +3,23 @@
#include "AnimBlendSequence.h"
#include "MemoryHeap.h"
+//--MIAMI: file done
+
CAnimBlendSequence::CAnimBlendSequence(void)
{
type = 0;
numFrames = 0;
keyFrames = nil;
keyFramesCompressed = nil;
-#ifdef PED_SKIN
boneTag = -1;
-#endif
}
CAnimBlendSequence::~CAnimBlendSequence(void)
{
- assert(keyFramesCompressed == nil);
if(keyFrames)
RwFree(keyFrames);
+ if(keyFramesCompressed)
+ RwFree(keyFramesCompressed);
}
void
@@ -28,18 +29,21 @@ CAnimBlendSequence::SetName(char *name)
}
void
-CAnimBlendSequence::SetNumFrames(int numFrames, bool translation)
+CAnimBlendSequence::SetNumFrames(int numFrames, bool translation, bool compressed)
{
- int sz;
-
if(translation){
- sz = sizeof(KeyFrameTrans);
type |= KF_ROT | KF_TRANS;
+ if(compressed)
+ keyFramesCompressed = RwMalloc(sizeof(KeyFrameTrans) * numFrames);
+ else
+ keyFrames = RwMalloc(sizeof(KeyFrameTrans) * numFrames);
}else{
- sz = sizeof(KeyFrame);
type |= KF_ROT;
+ if(compressed)
+ keyFramesCompressed = RwMalloc(sizeof(KeyFrame) * numFrames);
+ else
+ keyFrames = RwMalloc(sizeof(KeyFrame) * numFrames);
}
- keyFrames = RwMalloc(sz * numFrames);
this->numFrames = numFrames;
}
@@ -63,119 +67,6 @@ CAnimBlendSequence::RemoveQuaternionFlips(void)
}
}
-void
-CAnimBlendSequence::Uncompress(void)
-{
- int i;
-
- if(numFrames == 0)
- return;
-
- PUSH_MEMID(MEMID_ANIMATION);
-
- float rotScale = 1.0f/4096.0f;
- float timeScale = 1.0f/60.0f;
- float transScale = 1.0f/128.0f;
- if(type & KF_TRANS){
- void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTrans));
- KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)keyFramesCompressed;
- KeyFrameTrans *kf = (KeyFrameTrans*)newKfs;
- for(i = 0; i < numFrames; i++){
- kf->rotation.x = ckf->rot[0]*rotScale;
- kf->rotation.y = ckf->rot[1]*rotScale;
- kf->rotation.z = ckf->rot[2]*rotScale;
- kf->rotation.w = ckf->rot[3]*rotScale;
- kf->deltaTime = ckf->deltaTime*timeScale;
- kf->translation.x = ckf->trans[0]*transScale;
- kf->translation.y = ckf->trans[1]*transScale;
- kf->translation.z = ckf->trans[2]*transScale;
- kf++;
- ckf++;
- }
- keyFrames = newKfs;
- }else{
- void *newKfs = RwMalloc(numFrames * sizeof(KeyFrame));
- KeyFrameCompressed *ckf = (KeyFrameCompressed*)keyFramesCompressed;
- KeyFrame *kf = (KeyFrame*)newKfs;
- for(i = 0; i < numFrames; i++){
- kf->rotation.x = ckf->rot[0]*rotScale;
- kf->rotation.y = ckf->rot[1]*rotScale;
- kf->rotation.z = ckf->rot[2]*rotScale;
- kf->rotation.w = ckf->rot[3]*rotScale;
- kf->deltaTime = ckf->deltaTime*timeScale;
- kf++;
- ckf++;
- }
- keyFrames = newKfs;
- }
- REGISTER_MEMPTR(&keyFrames);
-
- RwFree(keyFramesCompressed);
- keyFramesCompressed = nil;
-
- POP_MEMID();
-}
-
-void
-CAnimBlendSequence::CompressKeyframes(void)
-{
- int i;
-
- if(numFrames == 0)
- return;
-
- PUSH_MEMID(MEMID_ANIMATION);
-
- float rotScale = 4096.0f;
- float timeScale = 60.0f;
- float transScale = 128.0f;
- if(type & KF_TRANS){
- void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTransCompressed));
- KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)newKfs;
- KeyFrameTrans *kf = (KeyFrameTrans*)keyFrames;
- for(i = 0; i < numFrames; i++){
- ckf->rot[0] = kf->rotation.x*rotScale;
- ckf->rot[1] = kf->rotation.y*rotScale;
- ckf->rot[2] = kf->rotation.z*rotScale;
- ckf->rot[3] = kf->rotation.w*rotScale;
- ckf->deltaTime = kf->deltaTime*timeScale + 0.5f;
- ckf->trans[0] = kf->translation.x*transScale;
- ckf->trans[1] = kf->translation.y*transScale;
- ckf->trans[2] = kf->translation.z*transScale;
- kf++;
- ckf++;
- }
- keyFramesCompressed = newKfs;
- }else{
- void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameCompressed));
- KeyFrameCompressed *ckf = (KeyFrameCompressed*)newKfs;
- KeyFrame *kf = (KeyFrame*)keyFrames;
- for(i = 0; i < numFrames; i++){
- ckf->rot[0] = kf->rotation.x*rotScale;
- ckf->rot[1] = kf->rotation.y*rotScale;
- ckf->rot[2] = kf->rotation.z*rotScale;
- ckf->rot[3] = kf->rotation.w*rotScale;
- ckf->deltaTime = kf->deltaTime*timeScale + 0.5f;
- kf++;
- ckf++;
- }
- keyFramesCompressed = newKfs;
- }
- REGISTER_MEMPTR(&keyFramesCompressed);
-
- POP_MEMID();
-}
-
-void
-CAnimBlendSequence::RemoveUncompressedData(void)
-{
- if(numFrames == 0)
- return;
- CompressKeyframes();
- RwFree(keyFrames);
- keyFrames = nil;
-}
-
#ifdef USE_CUSTOM_ALLOCATOR
bool
CAnimBlendSequence::MoveMemory(void)
diff --git a/src/animation/AnimBlendSequence.h b/src/animation/AnimBlendSequence.h
index c6e70f22..1c2531ce 100644
--- a/src/animation/AnimBlendSequence.h
+++ b/src/animation/AnimBlendSequence.h
@@ -16,15 +16,6 @@ struct KeyFrameTrans : KeyFrame {
CVector translation;
};
-struct KeyFrameCompressed {
- int16 rot[4]; // 4096
- int16 deltaTime; // 60
-};
-
-struct KeyFrameTransCompressed : KeyFrameCompressed {
- int16 trans[3]; // 128
-};
-
// The sequence of key frames of one animated node
class CAnimBlendSequence
@@ -37,32 +28,28 @@ public:
int32 type;
char name[24];
int32 numFrames;
-#ifdef PED_SKIN
int16 boneTag;
-#endif
void *keyFrames;
void *keyFramesCompressed;
CAnimBlendSequence(void);
virtual ~CAnimBlendSequence(void);
void SetName(char *name);
- void SetNumFrames(int numFrames, bool translation);
+ void SetNumFrames(int numFrames, bool translation, bool compressed);
void RemoveQuaternionFlips(void);
KeyFrame *GetKeyFrame(int n) {
return type & KF_TRANS ?
&((KeyFrameTrans*)keyFrames)[n] :
&((KeyFrame*)keyFrames)[n];
}
+ KeyFrame *GetKeyFrameCompressed(int n) {
+ return type & KF_TRANS ?
+ &((KeyFrameTrans*)keyFramesCompressed)[n] :
+ &((KeyFrame*)keyFramesCompressed)[n];
+ }
bool HasTranslation(void) { return !!(type & KF_TRANS); }
- void Uncompress(void);
- void CompressKeyframes(void);
- void RemoveUncompressedData(void);
bool MoveMemory(void);
-#ifdef PED_SKIN
void SetBoneTag(int tag) { boneTag = tag; }
-#endif
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CAnimBlendSequence, 0x2C);
-#endif
+VALIDATE_SIZE(CAnimBlendSequence, 0x30);
diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp
index 877dcd76..0aa6486b 100644
--- a/src/animation/AnimManager.cpp
+++ b/src/animation/AnimManager.cpp
@@ -10,6 +10,9 @@
#include "AnimBlendAssociation.h"
#include "AnimBlendAssocGroup.h"
#include "AnimManager.h"
+#include "Streaming.h"
+
+//--MIAMI: file done
CAnimBlock CAnimManager::ms_aAnimBlocks[NUMANIMBLOCKS];
CAnimBlendHierarchy CAnimManager::ms_aAnimations[NUMANIMATIONS];
@@ -32,26 +35,26 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_IDLE_ARMED, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_IDLE_CHAT, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_IDLE_TAXI, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_KO_SHOT_FRONT1, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_KO_SHOT_FRONT2, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_KO_SHOT_FRONT3, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_KO_SHOT_FRONT4, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_KO_SHOT_FACE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_FRONT1, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_FRONT2, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_FRONT3, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_FRONT4, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_FACE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
{ ANIM_KO_SHOT_STOM, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_KO_SHOT_ARML, ASSOC_PARTIAL | ASSOC_FRONTAL },
- { ANIM_KO_SHOT_ARMR, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_ARML, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_ARMR, ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_KO_SHOT_LEGL, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_KO_SHOT_LEGR, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_KD_LEFT, ASSOC_PARTIAL | ASSOC_FRONTAL },
- { ANIM_KD_RIGHT, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_KD_LEFT, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_KD_RIGHT, ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_KO_SKID_FRONT, ASSOC_PARTIAL },
{ ANIM_KO_SPIN_R, ASSOC_PARTIAL },
- { ANIM_KO_SKID_BACK, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_KO_SKID_BACK, ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_KO_SPIN_L, ASSOC_PARTIAL },
- { ANIM_SHOT_FRONT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_SHOT_LEFT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_SHOT_BACK_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_SHOT_RIGHT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_SHOT_FRONT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_SHOT_LEFT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_SHOT_BACK_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_SHOT_RIGHT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
{ ANIM_HIT_FRONT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_HIT_LEFT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_HIT_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
@@ -62,29 +65,8 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_HIT_HEAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_HIT_WALK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_HIT_WALL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_FLOOR_HIT_F, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_FLOOR_HIT_F, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_HIT_BEHIND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_PUNCH_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_KICK_FLOOR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_BAT_H, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_BAT_V, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_HGUN_BODY, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_WEAPON_AK_BODY, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_PUMP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_SNIPER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_THROW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_THROWU, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_START_THROW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_BOMBER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_HGUN_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_AK_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_FPS_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_BAT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_UZI, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_PUMP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_AK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_M16, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_ROCKET, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_IDLE, ASSOC_REPEAT },
{ ANIM_FIGHT2_IDLE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_SH_F, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
@@ -96,7 +78,18 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_FIGHT_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_ROUNDHOUSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_FIGHT_LONGKICK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_FIGHT_PPUNCH, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_FIGHT_PPUNCH, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_FIGHT_JAB, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_ELBOW_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_ELBOW_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_BKICK_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_BKICK_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BOMBER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_PUNCH_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_PPUNCH2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_KICK_FLOOR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_WEAPON_THROWU, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_SH_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_CAR_JACKED_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_CAR_LJACKED_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_CAR_JACKED_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
@@ -115,6 +108,7 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_CAR_CLOSEDOOR_LOW_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_ROLLDOOR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_ROLLDOOR_LOW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_CAR_JUMPIN_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_GETOUT_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_GETOUT_LOW_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CLOSE_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
@@ -130,39 +124,41 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_CAR_CLOSEDOOR_LOW_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_SHUFFLE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_LSHUFFLE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_CAR_SIT, ASSOC_DELETEFADEDOUT },
- { ANIM_CAR_LSIT, ASSOC_DELETEFADEDOUT },
- { ANIM_CAR_SITP, ASSOC_DELETEFADEDOUT },
- { ANIM_CAR_SITPLO, ASSOC_DELETEFADEDOUT },
- { ANIM_DRIVE_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVE_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVE_LOW_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVE_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVEBY_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVEBY_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_CAR_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVE_BOAT, ASSOC_DELETEFADEDOUT },
+ { ANIM_CAR_SIT, ASSOC_DELETEFADEDOUT},
+ { ANIM_CAR_LSIT, ASSOC_DELETEFADEDOUT},
+ { ANIM_CAR_SITP, ASSOC_DELETEFADEDOUT},
+ { ANIM_CAR_SITPLO, ASSOC_DELETEFADEDOUT},
+ { ANIM_DRIVE_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVE_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVE_LOW_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVE_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVEBY_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVEBY_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVEBY_LOW_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVEBY_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_CAR_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVE_BOAT, ASSOC_DELETEFADEDOUT | ASSOC_DRIVING },
+ { ANIM_DRIVE_BOAT_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVE_BOAT_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BOAT_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_PICKUP_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_PICKUP_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_PULLUP_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_PULLUP_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_ELBOW_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_ELBOW_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_FALL_OFF, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+ { ANIM_BIKE_FALL_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_CAR_GETOUT_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_GETOUT_LOW_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CLOSE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_HOOKERTALK, ASSOC_REPEAT | ASSOC_PARTIAL },
- { ANIM_COACH_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_COACH_OPEN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_COACH_IN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_COACH_IN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_COACH_OUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_TRAIN_GETIN, ASSOC_PARTIAL },
- { ANIM_TRAIN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_IDLE_STANCE2, ASSOC_PARTIAL },
+ { ANIM_IDLE_STANCE3, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CRAWLOUT_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CRAWLOUT_RHS2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_GETIN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_CLOSE_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_GETOUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_OPEN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_GETIN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_CLOSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_CAR_ROLLOUT_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
+ { ANIM_CAR_ROLLOUT_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
{ ANIM_GETUP1, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_GETUP2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_GETUP3, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
@@ -174,33 +170,132 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_FALL_GLIDE, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_FALL_LAND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_FALL_COLLAPSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+ { ANIM_FALL_BACK, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+ { ANIM_FALL_FRONT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_EV_STEP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_EV_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_IDLE },
+ { ANIM_EV_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_IDLE },
{ ANIM_ROAD_CROSS, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_TURN_180, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_ARREST_GUN, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_DROWN, ASSOC_PARTIAL },
- { ANIM_CPR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_DUCK_DOWN, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_DUCK_LOW, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+ { ANIM_WEAPON_CROUCH, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_RBLOCK_CSHOOT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_WEAPON_THROWU2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_HANDSUP, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_HANDSCOWER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_FUCKU, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_PHONE_IN, ASSOC_PARTIAL },
+ { ANIM_FUCKU, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_PHONE_IN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_PHONE_OUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_PHONE_TALK, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+ { ANIM_SEAT_DOWN, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_SEAT_UP, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_SEAT_IDLE, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_SEAT_DOWN2, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_ATM, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_ABSEIL, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+};
+AnimAssocDesc aVanAnimDescs[] = {
+ { ANIM_VAN_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_GETIN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_CLOSE_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_GETOUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_OPEN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_GETIN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_CLOSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aCoachAnimDescs[] = {
+ { ANIM_COACH_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_COACH_OPEN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_COACH_IN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_COACH_IN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_COACH_OUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aBikeAnimDescs[] = {
+ { ANIM_BIKE_RIDE, ASSOC_DELETEFADEDOUT},
+ { ANIM_BIKE_STILL, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_LEFT, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_RIGHT, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_BACK, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_FWD, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_PUSHES, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_JUMPON_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_JUMPON_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_KICK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_HIT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_GETOFF_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_GETOFF_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_GETOFF_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+ { ANIM_BIKE_DRIVEBY_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_DRIVEBY_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_DRIVEBY_FT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_PASSENGER, ASSOC_DELETEFADEDOUT | ASSOC_DRIVING },
+};
+AnimAssocDesc aMeleeAnimDescs[] = {
+ { ANIM_MELEE_ATTACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_MELEE_ATTACK_2ND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_MELEE_ATTACK_START, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_MELEE_IDLE_FIGHTMODE, ASSOC_REPEAT },
+ { ANIM_MELEE_ATTACK_FINISH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+};
+AnimAssocDesc aSwingAnimDescs[] = {
+ { ANIM_MELEE_ATTACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_MELEE_ATTACK_2ND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_MELEE_ATTACK_START, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_MELEE_IDLE_FIGHTMODE, ASSOC_REPEAT },
+ { ANIM_MELEE_ATTACK_FINISH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aWeaponAnimDescs[] = {
+ { ANIM_WEAPON_FIRE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_WEAPON_CROUCHFIRE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_WEAPON_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_WEAPON_CROUCHRELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_WEAPON_SPECIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aMedicAnimDescs[] = {
+ { ANIM_CPR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aSunbatheAnimDescs[] = {
+ { ANIM_SUNBATHE, ASSOC_REPEAT | ASSOC_PARTIAL },
+ { ANIM_SUNBATHE_DOWN, ASSOC_REPEAT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
+ { ANIM_SUNBATHE_UP, ASSOC_REPEAT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
+ { ANIM_SUNBATHE_ESCAPE, ASSOC_REPEAT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
+};
+AnimAssocDesc aPlayerIdleAnimDescs[] = {
+ { ANIM_IDLE_STRETCH, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_IDLE_TIME, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_IDLE_SHOULDER, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_IDLE_STRETCH_LEG, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aRiotAnimDescs[] = {
+ { ANIM_RIOT_ANGRY, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_ANGRY_B, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_CHANT, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_PUNCHES, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_SHOUT, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_CHALLENGE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_FUKU, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aStripAnimDescs[] = {
+ { ANIM_STRIP_A, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_B, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_C, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_D, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_E, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_F, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_G, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
AnimAssocDesc aStdAnimDescsSide[] = {
- { ANIM_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
- { ANIM_RUN, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
- { ANIM_SPRINT, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
+ { ANIM_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
+ { ANIM_RUN, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
+ { ANIM_SPRINT, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
{ ANIM_IDLE_STANCE, ASSOC_REPEAT },
{ ANIM_WALK_START, ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
};
-char const *aStdAnimations[] = {
+
+char const* aStdAnimations[] = {
"walk_civi",
"run_civi",
"sprint_panic",
@@ -208,7 +303,7 @@ char const *aStdAnimations[] = {
"walk_start",
"run_stop",
"run_stopR",
- "idle_cam",
+ "idle_hbhb",
"idle_hbhb",
"idle_tired",
"idle_armed",
@@ -246,27 +341,6 @@ char const *aStdAnimations[] = {
"HIT_wall",
"FLOOR_hit_f",
"HIT_behind",
- "punchR",
- "KICK_floor",
- "WEAPON_bat_h",
- "WEAPON_bat_v",
- "WEAPON_hgun_body",
- "WEAPON_AK_body",
- "WEAPON_pump",
- "WEAPON_sniper",
- "WEAPON_throw",
- "WEAPON_throwu",
- "WEAPON_start_throw",
- "bomber",
- "WEAPON_hgun_rload",
- "WEAPON_AK_rload",
- "FPS_PUNCH",
- "FPS_BAT",
- "FPS_UZI",
- "FPS_PUMP",
- "FPS_AK",
- "FPS_M16",
- "FPS_ROCKET",
"FIGHTIDLE",
"FIGHT2IDLE",
"FIGHTsh_F",
@@ -279,6 +353,17 @@ char const *aStdAnimations[] = {
"FIGHTrndhse",
"FIGHTlngkck",
"FIGHTppunch",
+ "FIGHTjab",
+ "FIGHTelbowL",
+ "FIGHTelbowR",
+ "FIGHTbkickL",
+ "FIGHTbkickR",
+ "bomber",
+ "punchR",
+ "FIGHTppunch",
+ "KICK_floor",
+ "WEAPON_throwu",
+ "FIGHTsh_back",
"car_jackedRHS",
"car_LjackedRHS",
"car_jackedLHS",
@@ -297,6 +382,7 @@ char const *aStdAnimations[] = {
"CAR_closedoorL_LHS",
"CAR_rolldoor",
"CAR_rolldoorLO",
+ "CAR_jumpin_LHS",
"CAR_getout_LHS",
"CAR_getoutL_LHS",
"CAR_close_LHS",
@@ -322,29 +408,31 @@ char const *aStdAnimations[] = {
"Drive_LO_R",
"Driveby_L",
"Driveby_R",
+ "DrivebyL_L",
+ "DrivebyL_R",
"CAR_LB",
"DRIVE_BOAT",
+ "DRIVE_BOAT_L",
+ "DRIVE_BOAT_R",
+ "DRIVE_BOAT_back",
+ "BIKE_pickupR",
+ "BIKE_pickupL",
+ "BIKE_pullupR",
+ "BIKE_pullupL",
+ "BIKE_elbowR",
+ "BIKE_elbowL",
+ "BIKE_fall_off",
+ "BIKE_fallR",
"CAR_getout_RHS",
"CAR_getoutL_RHS",
"CAR_close_RHS",
"car_hookertalk",
- "COACH_opnL",
- "COACH_opnR",
- "COACH_inL",
- "COACH_inR",
- "COACH_outL",
- "TRAIN_getin",
- "TRAIN_getout",
+ "idle_stance",
+ "idle_stance",
"CAR_crawloutRHS",
"CAR_crawloutRHS",
- "VAN_openL",
- "VAN_getinL",
- "VAN_closeL",
- "VAN_getoutL",
- "VAN_open",
- "VAN_getin",
- "VAN_close",
- "VAN_getout",
+ "CAR_rollout_LHS",
+ "CAR_rollout_LHS",
"Getup",
"Getup",
"Getup",
@@ -356,6 +444,8 @@ char const *aStdAnimations[] = {
"FALL_glide",
"FALL_land",
"FALL_collapse",
+ "FALL_back",
+ "FALL_front",
"EV_step",
"EV_dive",
"XPRESSscratch",
@@ -363,201 +453,515 @@ char const *aStdAnimations[] = {
"TURN_180",
"ARRESTgun",
"DROWN",
- "CPR",
"DUCK_down",
"DUCK_low",
+ "WEAPON_crouch",
"RBLOCK_Cshoot",
- "WEAPON_throwu",
"handsup",
"handsCOWER",
"FUCKU",
"PHONE_in",
"PHONE_out",
"PHONE_talk",
+ "SEAT_down",
+ "SEAT_up",
+ "SEAT_idle",
+ "SEAT_down",
+ "ATM",
+ "abseil",
+};
+char const* aVanAnimations[] = {
+ "VAN_openL",
+ "VAN_getinL",
+ "VAN_closeL",
+ "VAN_getoutL",
+ "VAN_open",
+ "VAN_getin",
+ "VAN_close",
+ "VAN_getout",
+};
+char const* aCoachAnimations[] = {
+ "COACH_opnL",
+ "COACH_opnL",
+ "COACH_inL",
+ "COACH_inL",
+ "COACH_outL",
+};
+char const* aBikesAnimations[] = {
+ "BIKEs_Ride",
+ "BIKEs_Still",
+ "BIKEs_Left",
+ "BIKEs_Right",
+ "BIKEs_Back",
+ "BIKEs_Fwd",
+ "BIKEs_pushes",
+ "BIKEs_jumponR",
+ "BIKEs_jumponL",
+ "BIKEs_kick",
+ "BIKEs_hit",
+ "BIKEs_getoffRHS",
+ "BIKEs_getoffLHS",
+ "BIKEs_getoffBACK",
+ "BIKEs_drivebyLHS",
+ "BIKEs_drivebyRHS",
+ "BIKEs_drivebyFT",
+ "BIKEs_passenger",
+};
+char const* aBikevAnimations[] = {
+ "BIKEv_Ride",
+ "BIKEv_Still",
+ "BIKEv_Left",
+ "BIKEv_Right",
+ "BIKEv_Back",
+ "BIKEv_Fwd",
+ "BIKEv_pushes",
+ "BIKEv_jumponR",
+ "BIKEv_jumponL",
+ "BIKEv_kick",
+ "BIKEv_hit",
+ "BIKEv_getoffRHS",
+ "BIKEv_getoffLHS",
+ "BIKEv_getoffBACK",
+ "BIKEv_drivebyLHS",
+ "BIKEv_drivebyRHS",
+ "BIKEv_drivebyFT",
+ "BIKEv_passenger",
+};
+char const* aBikehAnimations[] = {
+ "BIKEh_Ride",
+ "BIKEh_Still",
+ "BIKEh_Left",
+ "BIKEh_Right",
+ "BIKEh_Back",
+ "BIKEh_Fwd",
+ "BIKEh_pushes",
+ "BIKEh_jumponR",
+ "BIKEh_jumponL",
+ "BIKEh_kick",
+ "BIKEh_hit",
+ "BIKEh_getoffRHS",
+ "BIKEh_getoffLHS",
+ "BIKEh_getoffBACK",
+ "BIKEh_drivebyLHS",
+ "BIKEh_drivebyRHS",
+ "BIKEh_drivebyFT",
+ "BIKEh_passenger",
+};
+char const* aBikedAnimations[] = {
+ "BIKEd_Ride",
+ "BIKEd_Still",
+ "BIKEd_Left",
+ "BIKEd_Right",
+ "BIKEd_Back",
+ "BIKEd_Fwd",
+ "BIKEd_pushes",
+ "BIKEd_jumponR",
+ "BIKEd_jumponL",
+ "BIKEd_kick",
+ "BIKEd_hit",
+ "BIKEd_getoffRHS",
+ "BIKEd_getoffLHS",
+ "BIKEd_getoffBACK",
+ "BIKEd_drivebyLHS",
+ "BIKEd_drivebyRHS",
+ "BIKEd_drivebyFT",
+ "BIKEd_passenger",
+};
+char const* aUnarmedAnimations[] = {
+ "punchR",
+ "KICK_floor",
+ "FIGHTppunch",
+};
+char const* aScrewdriverAnimations[] = {
+ "FIGHTbodyblow",
+ "FIGHTbodyblow",
+ "FIGHTppunch",
+ "FIGHTIDLE",
+ "FIGHTbodyblow",
+};
+char const* aKnifeAnimations[] = {
+ "WEAPON_knife_1",
+ "WEAPON_knife_2",
+ "knife_part",
+ "WEAPON_knifeidle",
+ "WEAPON_knife_3",
+};
+char const* aBaseballbatAnimations[] = {
+ "WEAPON_bat_h",
+ "WEAPON_bat_v",
+ "BAT_PART",
+ "WEAPON_bat_h",
+ "WEAPON_golfclub",
+};
+char const* aGolfclubAnimations[] = {
+ "WEAPON_bat_h",
+ "WEAPON_golfclub",
+ "BAT_PART",
+ "WEAPON_bat_h",
+ "WEAPON_bat_v",
+};
+char const* aChainsawAnimations[] = {
+ "WEAPON_csaw",
+ "WEAPON_csawlo",
+ "csaw_part",
};
-char const *aPlayerAnimations[] = {
+char const* aPythonAnimations[] = {
+ "python_fire",
+ "python_crouchfire",
+ "python_reload",
+ "python_crouchreload",
+};
+char const* aColtAnimations[] = {
+ "colt45_fire",
+ "colt45_crouchfire",
+ "colt45_reload",
+ "colt45_crouchreload",
+ "colt45_cop",
+};
+char const* aShotgunAnimations[] = {
+ "shotgun_fire",
+ "shotgun_crouchfire",
+};
+char const* aBuddyAnimations[] = {
+ "buddy_fire",
+ "buddy_crouchfire",
+};
+char const* aTecAnimations[] = {
+ "TEC_fire",
+ "TEC_crouchfire",
+ "TEC_reload",
+ "TEC_crouchreload",
+};
+char const* aUziAnimations[] = {
+ "UZI_fire",
+ "UZI_crouchfire",
+ "UZI_reload",
+ "UZI_crouchreload",
+};
+char const* aRifleAnimations[] = {
+ "RIFLE_fire",
+ "RIFLE_crouchfire",
+ "RIFLE_load",
+ "RIFLE_crouchload",
+};
+char const* aM60Animations[] = {
+ "M60_fire",
+ "M60_fire",
+ "M60_reload",
+};
+char const* aSniperAnimations[] = {
+ "WEAPON_sniper",
+};
+char const* aThrowAnimations[] = {
+ "WEAPON_throw",
+ "WEAPON_throwu",
+ "WEAPON_start_throw",
+};
+char const* aFlamethrowerAnimations[] = {
+ "FLAME_fire",
+};
+char const* aMedicAnimations[] = {
+ "CPR",
+};
+char const* aSunbatheAnimations[] = {
+ "bather",
+ "batherdown",
+ "batherup",
+ "batherscape",
+};
+char const* aPlayerIdleAnimations[] = {
+ "stretch",
+ "time",
+ "shldr",
+ "strleg",
+};
+char const* aRiotAnimations[] = {
+ "riot_angry",
+ "riot_angry_b",
+ "riot_chant",
+ "riot_punches",
+ "riot_shout",
+ "riot_challenge",
+ "riot_fuku",
+};
+char const* aStripAnimations[] = {
+ "strip_A",
+ "strip_B",
+ "strip_C",
+ "strip_D",
+ "strip_E",
+ "strip_F",
+ "strip_G",
+};
+char const* aLanceAnimations[] = {
+ "lance",
+};
+char const* aPlayerAnimations[] = {
"walk_player",
"run_player",
"SPRINT_civi",
"IDLE_STANCE",
"walk_start",
};
-char const *aPlayerWithRocketAnimations[] = {
+char const* aPlayerWithRocketAnimations[] = {
"walk_rocket",
"run_rocket",
"run_rocket",
"idle_rocket",
"walk_start_rocket",
};
-char const *aPlayer1ArmedAnimations[] = {
+char const* aPlayer1ArmedAnimations[] = {
"walk_player",
"run_1armed",
"SPRINT_civi",
"IDLE_STANCE",
"walk_start",
};
-char const *aPlayer2ArmedAnimations[] = {
- "walk_player",
+char const* aPlayer2ArmedAnimations[] = {
+ "walk_armed",
"run_armed",
"run_armed",
- "idle_stance",
- "walk_start",
+ "idle_armed",
+ "walk_start_armed",
};
-char const *aPlayerBBBatAnimations[] = {
+char const* aPlayerBBBatAnimations[] = {
"walk_player",
"run_player",
"run_player",
"IDLE_STANCE",
"walk_start",
};
-char const *aShuffleAnimations[] = {
+char const* aPlayerChainsawAnimations[] = {
+ "walk_csaw",
+ "run_csaw",
+ "run_csaw",
+ "IDLE_csaw",
+ "walk_start_csaw",
+};
+char const* aShuffleAnimations[] = {
"WALK_shuffle",
"RUN_civi",
"SPRINT_civi",
"IDLE_STANCE",
};
-char const *aOldAnimations[] = {
+char const* aOldAnimations[] = {
"walk_old",
"run_civi",
"sprint_civi",
"idle_stance",
};
-char const *aGang1Animations[] = {
+char const* aGang1Animations[] = {
"walk_gang1",
"run_gang1",
"sprint_civi",
"idle_stance",
};
-char const *aGang2Animations[] = {
+char const* aGang2Animations[] = {
"walk_gang2",
"run_gang1",
"sprint_civi",
"idle_stance",
};
-char const *aFatAnimations[] = {
+char const* aFatAnimations[] = {
"walk_fat",
"run_civi",
"woman_runpanic",
"idle_stance",
};
-char const *aOldFatAnimations[] = {
+char const* aOldFatAnimations[] = {
"walk_fatold",
"run_fatold",
"woman_runpanic",
"idle_stance",
};
-char const *aStdWomanAnimations[] = {
+char const* aJoggerAnimations[] = {
+ "JOG_maleA",
+ "run_civi",
+ "sprint_civi",
+ "idle_stance",
+};
+char const* aStdWomanAnimations[] = {
"woman_walknorm",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
-char const *aWomanShopAnimations[] = {
+char const* aWomanShopAnimations[] = {
"woman_walkshop",
"woman_run",
"woman_run",
"woman_idlestance",
};
-char const *aBusyWomanAnimations[] = {
+char const* aBusyWomanAnimations[] = {
"woman_walkbusy",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
-char const *aSexyWomanAnimations[] = {
+char const* aSexyWomanAnimations[] = {
"woman_walksexy",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
-char const *aOldWomanAnimations[] = {
+char const* aFatWomanAnimations[] = {
+ "walk_fat",
+ "woman_run",
+ "woman_runpanic",
+ "woman_idlestance",
+};
+char const* aOldWomanAnimations[] = {
"woman_walkold",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
-char const *aFatWomanAnimations[] = {
- "walk_fat",
+char const* aJoggerWomanAnimations[] = {
+ "JOG_maleB",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
-char const *aPanicChunkyAnimations[] = {
+char const* aPanicChunkyAnimations[] = {
"run_fatold",
"woman_runpanic",
"woman_runpanic",
"idle_stance",
};
-char const *aPlayerStrafeBackAnimations[] = {
- "walk_player_back",
- "run_player_back",
- "run_player_back",
+char const* aSkateAnimations[] = {
+ "skate_run",
+ "skate_sprint",
+ "skate_sprint",
+ "skate_idle",
+};
+char const* aPlayerStrafeBackAnimations[] = {
+ "walk_back",
+ "run_back",
+ "run_back",
"IDLE_STANCE",
"walk_start_back",
};
-char const *aPlayerStrafeLeftAnimations[] = {
- "walk_player_left",
+char const* aPlayerStrafeLeftAnimations[] = {
+ "walk_left",
"run_left",
"run_left",
"IDLE_STANCE",
"walk_start_left",
};
-char const *aPlayerStrafeRightAnimations[] = {
- "walk_player_right",
+char const* aPlayerStrafeRightAnimations[] = {
+ "walk_right",
"run_right",
"run_right",
"IDLE_STANCE",
"walk_start_right",
};
-char const *aRocketStrafeBackAnimations[] = {
+char const* aRocketStrafeBackAnimations[] = {
"walk_rocket_back",
"run_rocket_back",
"run_rocket_back",
"idle_rocket",
"walkst_rocket_back",
};
-char const *aRocketStrafeLeftAnimations[] = {
+char const* aRocketStrafeLeftAnimations[] = {
"walk_rocket_left",
"run_rocket_left",
"run_rocket_left",
"idle_rocket",
"walkst_rocket_left",
};
-char const *aRocketStrafeRightAnimations[] = {
+char const* aRocketStrafeRightAnimations[] = {
"walk_rocket_right",
"run_rocket_right",
"run_rocket_right",
"idle_rocket",
"walkst_rocket_right",
};
+char const* aChainsawStrafeBackAnimations[] = {
+ "walk_csaw_back",
+ "run_csaw_back",
+ "run_csaw_back",
+ "idle_csaw",
+ "walkst_csaw_back",
+};
+char const* aChainsawStrafeLeftAnimations[] = {
+ "walk_csaw_left",
+ "run_csaw_left",
+ "run_csaw_left",
+ "idle_csaw",
+ "walkst_csaw_left",
+};
+char const* aChainsawStrafeRightAnimations[] = {
+ "walk_csaw_right",
+ "run_csaw_right",
+ "run_csaw_right",
+ "idle_csaw",
+ "walkst_csaw_right",
+};
+
#define awc(a) ARRAY_SIZE(a), a
const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_GROUPS] = {
{ "man", "ped", MI_COP, awc(aStdAnimations), aStdAnimDescs },
+ { "van", "van", MI_COP, awc(aVanAnimations), aVanAnimDescs },
+ { "coach", "coach", MI_COP, awc(aCoachAnimations), aCoachAnimDescs },
+ { "bikes", "bikes", MI_COP, awc(aBikesAnimations), aBikeAnimDescs },
+ { "bikev", "bikev", MI_COP, awc(aBikevAnimations), aBikeAnimDescs },
+ { "bikeh", "bikeh", MI_COP, awc(aBikehAnimations), aBikeAnimDescs },
+ { "biked", "biked", MI_COP, awc(aBikedAnimations), aBikeAnimDescs },
+ { "unarmed", "ped", MI_COP, awc(aUnarmedAnimations), aMeleeAnimDescs },
+ { "screwdrv", "ped", MI_COP, awc(aScrewdriverAnimations), aMeleeAnimDescs },
+ { "knife", "knife", MI_COP, awc(aKnifeAnimations), aMeleeAnimDescs },
+ { "baseball", "baseball", MI_COP, awc(aBaseballbatAnimations), aSwingAnimDescs },
+ { "golfclub", "baseball", MI_COP, awc(aGolfclubAnimations), aSwingAnimDescs },
+ { "chainsaw", "chainsaw", MI_COP, awc(aChainsawAnimations), aMeleeAnimDescs },
+ { "python", "python", MI_COP, awc(aPythonAnimations), aWeaponAnimDescs },
+ { "colt45", "colt45", MI_COP, awc(aColtAnimations), aWeaponAnimDescs },
+ { "shotgun", "shotgun", MI_COP, awc(aShotgunAnimations), aWeaponAnimDescs },
+ { "buddy", "buddy", MI_COP, awc(aBuddyAnimations), aWeaponAnimDescs },
+ { "tec", "tec", MI_COP, awc(aTecAnimations), aWeaponAnimDescs },
+ { "uzi", "uzi", MI_COP, awc(aUziAnimations), aWeaponAnimDescs },
+ { "rifle", "rifle", MI_COP, awc(aRifleAnimations), aWeaponAnimDescs },
+ { "m60", "m60", MI_COP, awc(aM60Animations), aWeaponAnimDescs },
+ { "sniper", "sniper", MI_COP, awc(aSniperAnimations), aWeaponAnimDescs },
+ { "grenade", "grenade", MI_COP, awc(aThrowAnimations), aWeaponAnimDescs },
+ { "flame", "flame", MI_COP, awc(aFlamethrowerAnimations), aWeaponAnimDescs },
+ { "medic", "medic", MI_COP, awc(aMedicAnimations), aMedicAnimDescs },
+ { "sunbathe", "sunbathe", MI_COP, 1, aSunbatheAnimations, aSunbatheAnimDescs }, // NB: not using awc here!
+ { "playidles", "playidles", MI_COP, awc(aPlayerIdleAnimations), aPlayerIdleAnimDescs },
+ { "riot", "riot", MI_COP, awc(aRiotAnimations), aRiotAnimDescs },
+ { "strip", "strip", MI_COP, awc(aStripAnimations), aStripAnimDescs },
+ { "lance", "lance", MI_COP, awc(aLanceAnimations), aSunbatheAnimDescs },
{ "player", "ped", MI_COP, awc(aPlayerAnimations), aStdAnimDescs },
{ "playerrocket", "ped", MI_COP, awc(aPlayerWithRocketAnimations), aStdAnimDescs },
{ "player1armed", "ped", MI_COP, awc(aPlayer1ArmedAnimations), aStdAnimDescs },
{ "player2armed", "ped", MI_COP, awc(aPlayer2ArmedAnimations), aStdAnimDescs },
{ "playerBBBat", "ped", MI_COP, awc(aPlayerBBBatAnimations), aStdAnimDescs },
+ { "playercsaw", "ped", MI_COP, awc(aPlayerChainsawAnimations), aStdAnimDescs },
{ "shuffle", "ped", MI_COP, awc(aShuffleAnimations), aStdAnimDescs },
{ "oldman", "ped", MI_COP, awc(aOldAnimations), aStdAnimDescs },
{ "gang1", "ped", MI_COP, awc(aGang1Animations), aStdAnimDescs },
{ "gang2", "ped", MI_COP, awc(aGang2Animations), aStdAnimDescs },
{ "fatman", "ped", MI_COP, awc(aFatAnimations), aStdAnimDescs },
{ "oldfatman", "ped", MI_COP, awc(aOldFatAnimations), aStdAnimDescs },
+ { "jogger", "ped", MI_COP, awc(aJoggerAnimations), aStdAnimDescs },
{ "woman", "ped", MI_COP, awc(aStdWomanAnimations), aStdAnimDescs },
{ "shopping", "ped", MI_COP, awc(aWomanShopAnimations), aStdAnimDescs },
{ "busywoman", "ped", MI_COP, awc(aBusyWomanAnimations), aStdAnimDescs },
{ "sexywoman", "ped", MI_COP, awc(aSexyWomanAnimations), aStdAnimDescs },
- { "oldwoman", "ped", MI_COP, awc(aOldWomanAnimations), aStdAnimDescs },
{ "fatwoman", "ped", MI_COP, awc(aFatWomanAnimations), aStdAnimDescs },
+ { "oldwoman", "ped", MI_COP, awc(aOldWomanAnimations), aStdAnimDescs },
+ { "jogwoman", "ped", MI_COP, awc(aJoggerWomanAnimations), aStdAnimDescs },
{ "panicchunky", "ped", MI_COP, awc(aPanicChunkyAnimations), aStdAnimDescs },
+ { "skate", "skate", MI_COP, awc(aSkateAnimations), aStdAnimDescs },
{ "playerback", "ped", MI_COP, awc(aPlayerStrafeBackAnimations), aStdAnimDescs },
{ "playerleft", "ped", MI_COP, awc(aPlayerStrafeLeftAnimations), aStdAnimDescsSide },
{ "playerright", "ped", MI_COP, awc(aPlayerStrafeRightAnimations), aStdAnimDescsSide },
{ "rocketback", "ped", MI_COP, awc(aRocketStrafeBackAnimations), aStdAnimDescs },
{ "rocketleft", "ped", MI_COP, awc(aRocketStrafeLeftAnimations), aStdAnimDescsSide },
{ "rocketright", "ped", MI_COP, awc(aRocketStrafeRightAnimations), aStdAnimDescsSide },
+ { "csawback", "ped", MI_COP, awc(aChainsawStrafeBackAnimations), aStdAnimDescs },
+ { "csawleft", "ped", MI_COP, awc(aChainsawStrafeLeftAnimations), aStdAnimDescsSide },
+ { "csawright", "ped", MI_COP, awc(aChainsawStrafeRightAnimations), aStdAnimDescsSide },
};
#undef awc
@@ -567,8 +971,6 @@ CAnimManager::Initialise(void)
ms_numAnimations = 0;
ms_numAnimBlocks = 0;
ms_animCache.Init(25);
-
-// dumpanimdata();
}
void
@@ -576,31 +978,50 @@ CAnimManager::Shutdown(void)
{
int i;
- ms_animCache.Shutdown();
+ for(i = 0; i < NUMANIMBLOCKS; i++)
+ CStreaming::RemoveAnim(i);
for(i = 0; i < ms_numAnimations; i++)
ms_aAnimations[i].Shutdown();
+ ms_animCache.Shutdown();
+
delete[] ms_aAnimAssocGroups;
}
void
CAnimManager::UncompressAnimation(CAnimBlendHierarchy *hier)
{
- if(!hier->compressed){
- if(hier->linkPtr){
- hier->linkPtr->Remove();
- ms_animCache.head.Insert(hier->linkPtr);
- }
+ if(hier->compressed2){
+ if(hier->totalLength == 0.0f)
+ hier->CalcTotalTimeCompressed();
}else{
- CLink<CAnimBlendHierarchy*> *link = ms_animCache.Insert(hier);
- if(link == nil){
- ms_animCache.tail.prev->item->RemoveUncompressedData();
- ms_animCache.Remove(ms_animCache.tail.prev);
- link = ms_animCache.Insert(hier);
+ if(!hier->compressed){
+ if(hier->linkPtr){
+ hier->linkPtr->Remove();
+ ms_animCache.head.Insert(hier->linkPtr);
+ }
+ }else{
+ CLink<CAnimBlendHierarchy*> *link = ms_animCache.Insert(hier);
+ if(link == nil){
+ CAnimBlendHierarchy *lastHier = ms_animCache.tail.prev->item;
+ lastHier->RemoveUncompressedData();
+ ms_animCache.Remove(ms_animCache.tail.prev);
+ lastHier->linkPtr = nil;
+ link = ms_animCache.Insert(hier);
+ }
+ hier->linkPtr = link;
+ hier->Uncompress();
}
- hier->linkPtr = link;
- hier->Uncompress();
+ }
+}
+
+void
+CAnimManager::RemoveFromUncompressedCache(CAnimBlendHierarchy *hier)
+{
+ if(hier->linkPtr){
+ ms_animCache.Remove(hier->linkPtr);
+ hier->linkPtr = nil;
}
}
@@ -615,6 +1036,73 @@ CAnimManager::GetAnimationBlock(const char *name)
return nil;
}
+int32
+CAnimManager::GetAnimationBlockIndex(const char *name)
+{
+ int i;
+
+ for(i = 0; i < ms_numAnimBlocks; i++)
+ if(strcasecmp(ms_aAnimBlocks[i].name, name) == 0)
+ return i;
+ return -1;
+}
+
+int32
+CAnimManager::RegisterAnimBlock(const char *name)
+{
+ CAnimBlock *animBlock = GetAnimationBlock(name);
+ if(animBlock == nil){
+ animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++];
+ strncpy(animBlock->name, name, MAX_ANIMBLOCK_NAME);
+ animBlock->numAnims = 0;
+ assert(animBlock->refCount == 0);
+ }
+ return animBlock - ms_aAnimBlocks;
+}
+
+int32
+CAnimManager::GetNumRefsToAnimBlock(int32 block)
+{
+ return ms_aAnimBlocks[block].refCount;
+}
+
+void
+CAnimManager::AddAnimBlockRef(int32 block)
+{
+ ms_aAnimBlocks[block].refCount++;
+}
+
+void
+CAnimManager::RemoveAnimBlockRefWithoutDelete(int32 block)
+{
+ ms_aAnimBlocks[block].refCount--;
+}
+
+void
+CAnimManager::RemoveAnimBlockRef(int32 block)
+{
+ ms_aAnimBlocks[block].refCount--;
+ if(ms_aAnimBlocks[block].refCount == 0)
+ CStreaming::RemoveAnim(block);
+}
+
+void
+CAnimManager::RemoveAnimBlock(int32 block)
+{
+ int i;
+ CAnimBlock *animblock;
+
+ animblock = &ms_aAnimBlocks[block];
+ debug("Removing ANIMS %s\n", animblock->name);
+ for(i = 0; i < NUM_ANIM_ASSOC_GROUPS; i++)
+ if(ms_aAnimAssocGroups[i].animBlock == animblock)
+ ms_aAnimAssocGroups[i].DestroyAssociations();
+ for(i = 0; i < animblock->numAnims; i++)
+ ms_aAnimations[animblock->firstIndex + i].Shutdown();
+ animblock->isLoaded = false;
+ animblock->refCount = 0;
+}
+
CAnimBlendHierarchy*
CAnimManager::GetAnimation(const char *name, CAnimBlock *animBlock)
{
@@ -622,7 +1110,7 @@ CAnimManager::GetAnimation(const char *name, CAnimBlock *animBlock)
CAnimBlendHierarchy *hier = &ms_aAnimations[animBlock->firstIndex];
for(i = 0; i < animBlock->numAnims; i++){
- if(!CGeneral::faststricmp(hier->name, name))
+ if(strcasecmp(hier->name, name) == 0)
return hier;
hier++;
}
@@ -743,26 +1231,34 @@ CAnimManager::BlendAnimation(RpClump *clump, AssocGroupId groupId, AnimationId a
void
CAnimManager::LoadAnimFiles(void)
{
- int i, j;
-
LoadAnimFile("ANIM\\PED.IFP");
-
- // Create all assoc groups
ms_aAnimAssocGroups = new CAnimBlendAssocGroup[NUM_ANIM_ASSOC_GROUPS];
+ CreateAnimAssocGroups();
+}
+
+void
+CAnimManager::CreateAnimAssocGroups(void)
+{
+ int i, j;
+
for(i = 0; i < NUM_ANIM_ASSOC_GROUPS; i++){
+ CAnimBlock *block = GetAnimationBlock(ms_aAnimAssocDefinitions[i].blockName);
+ if(block == nil || !block->isLoaded || ms_aAnimAssocGroups[i].assocList)
+ continue;
+
CBaseModelInfo *mi = CModelInfo::GetModelInfo(ms_aAnimAssocDefinitions[i].modelIndex);
RpClump *clump = (RpClump*)mi->CreateInstance();
RpAnimBlendClumpInit(clump);
CAnimBlendAssocGroup *group = &ms_aAnimAssocGroups[i];
const AnimAssocDefinition *def = &ms_aAnimAssocDefinitions[i];
+ group->groupId = i;
+ group->firstAnimId = def->animDescs[0].animId;
group->CreateAssociations(def->blockName, clump, def->animNames, def->numAnims);
for(j = 0; j < group->numAssociations; j++)
- group->GetAnimation(j)->flags |= def->animDescs[j].flags;
-#ifdef PED_SKIN
- // forgot on xbox/android
+ // GetAnimation(i) in III (but it's in LoadAnimFiles), GetAnimation(group->animDesc[j].animId) in VC
+ group->GetAnimation(def->animDescs[j].animId)->flags |= def->animDescs[j].flags;
if(IsClumpSkinned(clump))
RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil);
-#endif
RpClumpDestroy(clump);
}
}
@@ -770,15 +1266,16 @@ CAnimManager::LoadAnimFiles(void)
void
CAnimManager::LoadAnimFile(const char *filename)
{
- int fd;
- fd = CFileMgr::OpenFile(filename, "rb");
- assert(fd > 0);
- LoadAnimFile(fd, true);
- CFileMgr::CloseFile(fd);
+ RwStream *stream;
+ stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
+ assert(stream);
+ LoadAnimFile(stream, true);
+ RwStreamClose(stream, nil);
}
+//--MIAMI: done
void
-CAnimManager::LoadAnimFile(int fd, bool compress)
+CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32])
{
#define ROUNDSIZE(x) if((x) & 3) (x) += 4 - ((x)&3)
struct IfpHeader {
@@ -786,127 +1283,136 @@ CAnimManager::LoadAnimFile(int fd, bool compress)
uint32 size;
};
IfpHeader anpk, info, name, dgan, cpan, anim;
- int numANPK;
char buf[256];
- int i, j, k, l;
+ int j, k, l;
float *fbuf = (float*)buf;
- CFileMgr::Read(fd, (char*)&anpk, sizeof(IfpHeader));
- if(strncmp(anpk.ident, "ANLF", 4) == 0){
- ROUNDSIZE(anpk.size);
- CFileMgr::Read(fd, buf, anpk.size);
- numANPK = *(int*)buf;
- }else if(strncmp(anpk.ident, "ANPK", 4) == 0){
- CFileMgr::Seek(fd, -8, 1);
- numANPK = 1;
+ // block name
+ RwStreamRead(stream, &anpk, sizeof(IfpHeader));
+ ROUNDSIZE(anpk.size);
+ RwStreamRead(stream, &info, sizeof(IfpHeader));
+ ROUNDSIZE(info.size);
+ RwStreamRead(stream, buf, info.size);
+ CAnimBlock *animBlock = GetAnimationBlock(buf+4);
+ if(animBlock){
+ if(animBlock->numAnims == 0){
+ animBlock->numAnims = *(int*)buf;
+ animBlock->firstIndex = ms_numAnimations;
+ }
+ }else{
+ animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++];
+ strncpy(animBlock->name, buf+4, MAX_ANIMBLOCK_NAME);
+ animBlock->numAnims = *(int*)buf;
+ animBlock->firstIndex = ms_numAnimations;
}
- for(i = 0; i < numANPK; i++){
- // block name
- CFileMgr::Read(fd, (char*)&anpk, sizeof(IfpHeader));
- ROUNDSIZE(anpk.size);
- CFileMgr::Read(fd, (char*)&info, sizeof(IfpHeader));
- ROUNDSIZE(info.size);
- CFileMgr::Read(fd, buf, info.size);
- CAnimBlock *animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++];
- strncpy(animBlock->name, buf+4, 24);
- animBlock->numAnims = *(int*)buf;
+ debug("Loading ANIMS %s\n", animBlock->name);
+ animBlock->isLoaded = true;
- animBlock->firstIndex = ms_numAnimations;
+ int animIndex = animBlock->firstIndex;
+ for(j = 0; j < animBlock->numAnims; j++){
+ assert(animIndex < ARRAY_SIZE(ms_aAnimations));
+ CAnimBlendHierarchy *hier = &ms_aAnimations[animIndex++];
+
+ // animation name
+ RwStreamRead(stream, &name, sizeof(IfpHeader));
+ ROUNDSIZE(name.size);
+ RwStreamRead(stream, buf, name.size);
+ hier->SetName(buf);
+
+ // Unimplemented uncompressed anim thing
+ if (somename) {
+ for (int i = 0; somename[i][0]; i++) {
+ if (!CGeneral::faststricmp(somename[i], hier->name))
+ debug("Loading %s uncompressed\n", hier->name);
+ }
+ }
- for(j = 0; j < animBlock->numAnims; j++){
- CAnimBlendHierarchy *hier = &ms_aAnimations[ms_numAnimations++];
+ hier->compressed = false;
+ hier->compressed2 = false;
- // animation name
- CFileMgr::Read(fd, (char*)&name, sizeof(IfpHeader));
- ROUNDSIZE(name.size);
- CFileMgr::Read(fd, buf, name.size);
- hier->SetName(buf);
+ // DG info has number of nodes/sequences
+ RwStreamRead(stream, (char*)&dgan, sizeof(IfpHeader));
+ ROUNDSIZE(dgan.size);
+ RwStreamRead(stream, (char*)&info, sizeof(IfpHeader));
+ ROUNDSIZE(info.size);
+ RwStreamRead(stream, buf, info.size);
+ hier->numSequences = *(int*)buf;
+ hier->sequences = new CAnimBlendSequence[hier->numSequences];
- // DG info has number of nodes/sequences
- CFileMgr::Read(fd, (char*)&dgan, sizeof(IfpHeader));
+ CAnimBlendSequence *seq = hier->sequences;
+ for(k = 0; k < hier->numSequences; k++, seq++){
+ // Each node has a name and key frames
+ RwStreamRead(stream, &cpan, sizeof(IfpHeader));
ROUNDSIZE(dgan.size);
- CFileMgr::Read(fd, (char*)&info, sizeof(IfpHeader));
- ROUNDSIZE(info.size);
- CFileMgr::Read(fd, buf, info.size);
- hier->numSequences = *(int*)buf;
- hier->sequences = new CAnimBlendSequence[hier->numSequences];
-
- CAnimBlendSequence *seq = hier->sequences;
- for(k = 0; k < hier->numSequences; k++, seq++){
- // Each node has a name and key frames
- CFileMgr::Read(fd, (char*)&cpan, sizeof(IfpHeader));
- ROUNDSIZE(dgan.size);
- CFileMgr::Read(fd, (char*)&anim, sizeof(IfpHeader));
- ROUNDSIZE(anim.size);
- CFileMgr::Read(fd, buf, anim.size);
- int numFrames = *(int*)(buf+28);
-#ifdef PED_SKIN
- if(anim.size == 44)
- seq->SetBoneTag(*(int*)(buf+40));
-#endif
- seq->SetName(buf);
- if(numFrames == 0)
- continue;
-
- CFileMgr::Read(fd, (char*)&info, sizeof(info));
- if(strncmp(info.ident, "KR00", 4) == 0){
- seq->SetNumFrames(numFrames, false);
- KeyFrame *kf = seq->GetKeyFrame(0);
- for(l = 0; l < numFrames; l++, kf++){
- CFileMgr::Read(fd, buf, 0x14);
- kf->rotation.x = -fbuf[0];
- kf->rotation.y = -fbuf[1];
- kf->rotation.z = -fbuf[2];
- kf->rotation.w = fbuf[3];
- kf->deltaTime = fbuf[4]; // absolute time here
- }
- }else if(strncmp(info.ident, "KRT0", 4) == 0){
- seq->SetNumFrames(numFrames, true);
- KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0);
- for(l = 0; l < numFrames; l++, kf++){
- CFileMgr::Read(fd, buf, 0x20);
- kf->rotation.x = -fbuf[0];
- kf->rotation.y = -fbuf[1];
- kf->rotation.z = -fbuf[2];
- kf->rotation.w = fbuf[3];
- kf->translation.x = fbuf[4];
- kf->translation.y = fbuf[5];
- kf->translation.z = fbuf[6];
- kf->deltaTime = fbuf[7]; // absolute time here
- }
- }else if(strncmp(info.ident, "KRTS", 4) == 0){
- seq->SetNumFrames(numFrames, true);
- KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0);
- for(l = 0; l < numFrames; l++, kf++){
- CFileMgr::Read(fd, buf, 0x2C);
- kf->rotation.x = -fbuf[0];
- kf->rotation.y = -fbuf[1];
- kf->rotation.z = -fbuf[2];
- kf->rotation.w = fbuf[3];
- kf->translation.x = fbuf[4];
- kf->translation.y = fbuf[5];
- kf->translation.z = fbuf[6];
- // scaling ignored
- kf->deltaTime = fbuf[10]; // absolute time here
- }
+ RwStreamRead(stream, &anim, sizeof(IfpHeader));
+ ROUNDSIZE(anim.size);
+ RwStreamRead(stream, buf, anim.size);
+ int numFrames = *(int*)(buf+28);
+ if(anim.size == 44)
+ seq->SetBoneTag(*(int*)(buf+40));
+ seq->SetName(buf);
+ if(numFrames == 0)
+ continue;
+
+ RwStreamRead(stream, &info, sizeof(info));
+ if(strncmp(info.ident, "KR00", 4) == 0){
+ seq->SetNumFrames(numFrames, false, false);
+ KeyFrame *kf = seq->GetKeyFrame(0);
+ if (strstr(seq->name, "L Toe"))
+ debug("anim %s has toe keyframes\n", hier->name); // , seq->name);
+
+ for(l = 0; l < numFrames; l++, kf++){
+ RwStreamRead(stream, buf, 0x14);
+ kf->rotation.x = -fbuf[0];
+ kf->rotation.y = -fbuf[1];
+ kf->rotation.z = -fbuf[2];
+ kf->rotation.w = fbuf[3];
+ kf->deltaTime = fbuf[4]; // absolute time here
}
+ }else if(strncmp(info.ident, "KRT0", 4) == 0){
+ seq->SetNumFrames(numFrames, true, false);
+ KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0);
+ if (strstr(seq->name, "L Toe"))
+ debug("anim %s has toe keyframes\n", hier->name); // , seq->name);
- // convert absolute time to deltas
- for(l = seq->numFrames-1; l > 0; l--){
- KeyFrame *kf1 = seq->GetKeyFrame(l);
- KeyFrame *kf2 = seq->GetKeyFrame(l-1);
- kf1->deltaTime -= kf2->deltaTime;
+ for(l = 0; l < numFrames; l++, kf++){
+ RwStreamRead(stream, buf, 0x20);
+ kf->rotation.x = -fbuf[0];
+ kf->rotation.y = -fbuf[1];
+ kf->rotation.z = -fbuf[2];
+ kf->rotation.w = fbuf[3];
+ kf->translation.x = fbuf[4];
+ kf->translation.y = fbuf[5];
+ kf->translation.z = fbuf[6];
+ kf->deltaTime = fbuf[7]; // absolute time here
}
- }
+ }else if(strncmp(info.ident, "KRTS", 4) == 0){
+ seq->SetNumFrames(numFrames, true, false);
+ KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0);
+ if (strstr(seq->name, "L Toe"))
+ debug("anim %s has toe keyframes\n", hier->name); // , seq->name);
- hier->RemoveQuaternionFlips();
- if(compress)
- hier->RemoveUncompressedData();
- else
- hier->CalcTotalTime();
+ for(l = 0; l < numFrames; l++, kf++){
+ RwStreamRead(stream, buf, 0x2C);
+ kf->rotation.x = -fbuf[0];
+ kf->rotation.y = -fbuf[1];
+ kf->rotation.z = -fbuf[2];
+ kf->rotation.w = fbuf[3];
+ kf->translation.x = fbuf[4];
+ kf->translation.y = fbuf[5];
+ kf->translation.z = fbuf[6];
+ // scaling ignored
+ kf->deltaTime = fbuf[10]; // absolute time here
+ }
+ }
}
+
+ hier->RemoveQuaternionFlips();
+ hier->CalcTotalTime();
}
+ if(animIndex > ms_numAnimations)
+ ms_numAnimations = animIndex;
}
void
@@ -916,5 +1422,6 @@ CAnimManager::RemoveLastAnimFile(void)
ms_numAnimBlocks--;
ms_numAnimations = ms_aAnimBlocks[ms_numAnimBlocks].firstIndex;
for(i = 0; i < ms_aAnimBlocks[ms_numAnimBlocks].numAnims; i++)
- ms_aAnimations[ms_aAnimBlocks[ms_numAnimBlocks].firstIndex + i].RemoveAnimSequences();
+ ms_aAnimations[ms_aAnimBlocks[ms_numAnimBlocks].firstIndex + i].Shutdown();
+ ms_aAnimBlocks[ms_numAnimBlocks].isLoaded = false;
}
diff --git a/src/animation/AnimManager.h b/src/animation/AnimManager.h
index de15602c..a55577b1 100644
--- a/src/animation/AnimManager.h
+++ b/src/animation/AnimManager.h
@@ -6,30 +6,66 @@
enum AssocGroupId
{
ASSOCGRP_STD,
+ ASSOCGRP_VAN,
+ ASSOCGRP_COACH,
+ ASSOCGRP_BIKE_STANDARD,
+ ASSOCGRP_BIKE_VESPA,
+ ASSOCGRP_BIKE_HARLEY,
+ ASSOCGRP_BIKE_DIRT,
+ ASSOCGRP_UNARMED,
+ ASSOCGRP_SCREWDRIVER,
+ ASSOCGRP_KNIFE,
+ ASSOCGRP_BASEBALLBAT,
+ ASSOCGRP_GOLFCLUB,
+ ASSOCGRP_CHAINSAW,
+ ASSOCGRP_PYTHON,
+ ASSOCGRP_COLT,
+ ASSOCGRP_SHOTGUN,
+ ASSOCGRP_BUDDY,
+ ASSOCGRP_TEC,
+ ASSOCGRP_UZI,
+ ASSOCGRP_RIFLE,
+ ASSOCGRP_M60,
+ ASSOCGRP_SNIPER,
+ ASSOCGRP_THROW,
+ ASSOCGRP_FLAMETHROWER,
+ ASSOCGRP_MEDIC,
+ ASSOCGRP_SUNBATHE,
+ ASSOCGRP_PLAYER_IDLE,
+ ASSOCGRP_RIOT,
+ ASSOCGRP_STRIP,
+ ASSOCGRP_LANCE,
ASSOCGRP_PLAYER,
ASSOCGRP_PLAYERROCKET,
ASSOCGRP_PLAYER1ARMED,
ASSOCGRP_PLAYER2ARMED,
ASSOCGRP_PLAYERBBBAT,
+ ASSOCGRP_PLAYERCHAINSAW,
ASSOCGRP_SHUFFLE,
ASSOCGRP_OLD,
ASSOCGRP_GANG1,
ASSOCGRP_GANG2,
ASSOCGRP_FAT,
ASSOCGRP_OLDFAT,
+ ASSOCGRP_JOGGER,
ASSOCGRP_WOMAN,
ASSOCGRP_WOMANSHOP,
ASSOCGRP_BUSYWOMAN,
ASSOCGRP_SEXYWOMAN,
- ASSOCGRP_OLDWOMAN,
ASSOCGRP_FATWOMAN,
+ ASSOCGRP_OLDWOMAN,
+ ASSOCGRP_JOGWOMAN,
ASSOCGRP_PANICCHUNKY,
+ ASSOCGRP_SKATE,
ASSOCGRP_PLAYERBACK,
ASSOCGRP_PLAYERLEFT,
ASSOCGRP_PLAYERRIGHT,
ASSOCGRP_ROCKETBACK,
ASSOCGRP_ROCKETLEFT,
ASSOCGRP_ROCKETRIGHT,
+ ASSOCGRP_CHAINSAWBACK,
+ ASSOCGRP_CHAINSAWLEFT,
+ ASSOCGRP_CHAINSAWRIGHT,
NUM_ANIM_ASSOC_GROUPS
};
@@ -37,11 +73,15 @@ enum AssocGroupId
class CAnimBlendAssociation;
class CAnimBlendAssocGroup;
+#define MAX_ANIMBLOCK_NAME 20
+
// A block of hierarchies
struct CAnimBlock
{
- char name[24];
- int32 firstIndex;
+ char name[MAX_ANIMBLOCK_NAME];
+ bool isLoaded;
+ int16 refCount;
+ int32 firstIndex; // first animtion in ms_aAnimations
int32 numAnims;
};
@@ -75,7 +115,16 @@ public:
static void Initialise(void);
static void Shutdown(void);
static void UncompressAnimation(CAnimBlendHierarchy *anim);
+ static void RemoveFromUncompressedCache(CAnimBlendHierarchy *hier);
+ static CAnimBlock *GetAnimationBlock(int32 block) { return &ms_aAnimBlocks[block]; }
static CAnimBlock *GetAnimationBlock(const char *name);
+ static int32 GetAnimationBlockIndex(const char *name);
+ static int32 RegisterAnimBlock(const char *name);
+ static int32 GetNumRefsToAnimBlock(int32 block);
+ static void AddAnimBlockRef(int32 block);
+ static void RemoveAnimBlockRefWithoutDelete(int32 block);
+ static void RemoveAnimBlockRef(int32 block);
+ static void RemoveAnimBlock(int32 block);
static CAnimBlendHierarchy *GetAnimation(const char *name, CAnimBlock *animBlock);
static CAnimBlendHierarchy *GetAnimation(int32 n) { return &ms_aAnimations[n]; }
static const char *GetAnimGroupName(AssocGroupId groupId);
@@ -87,6 +136,8 @@ public:
static CAnimBlendAssociation *BlendAnimation(RpClump *clump, AssocGroupId groupId, AnimationId animId, float delta);
static void LoadAnimFiles(void);
static void LoadAnimFile(const char *filename);
- static void LoadAnimFile(int fd, bool compress);
+ static void LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32] = nil);
+ static void CreateAnimAssocGroups(void);
static void RemoveLastAnimFile(void);
+ static CAnimBlendAssocGroup* GetAnimAssocGroups(void) { return ms_aAnimAssocGroups; }
};
diff --git a/src/animation/AnimationId.h b/src/animation/AnimationId.h
index 82fed8bd..f2ef3dfd 100644
--- a/src/animation/AnimationId.h
+++ b/src/animation/AnimationId.h
@@ -47,27 +47,6 @@ enum AnimationId
ANIM_HIT_WALL,
ANIM_FLOOR_HIT_F,
ANIM_HIT_BEHIND,
- ANIM_PUNCH_R,
- ANIM_KICK_FLOOR,
- ANIM_WEAPON_BAT_H,
- ANIM_WEAPON_BAT_V,
- ANIM_WEAPON_HGUN_BODY,
- ANIM_WEAPON_AK_BODY,
- ANIM_WEAPON_PUMP,
- ANIM_WEAPON_SNIPER,
- ANIM_WEAPON_THROW,
- ANIM_WEAPON_THROWU,
- ANIM_WEAPON_START_THROW,
- ANIM_BOMBER,
- ANIM_HGUN_RELOAD,
- ANIM_AK_RELOAD,
- ANIM_FPS_PUNCH,
- ANIM_FPS_BAT,
- ANIM_FPS_UZI,
- ANIM_FPS_PUMP,
- ANIM_FPS_AK,
- ANIM_FPS_M16,
- ANIM_FPS_ROCKET,
ANIM_FIGHT_IDLE,
ANIM_FIGHT2_IDLE,
ANIM_FIGHT_SH_F,
@@ -80,6 +59,21 @@ enum AnimationId
ANIM_FIGHT_ROUNDHOUSE,
ANIM_FIGHT_LONGKICK,
ANIM_FIGHT_PPUNCH,
+
+ ANIM_FIGHT_JAB,
+ ANIM_FIGHT_ELBOW_L,
+ ANIM_FIGHT_ELBOW_R,
+ ANIM_FIGHT_BKICK_L,
+ ANIM_FIGHT_BKICK_R,
+
+ ANIM_BOMBER,
+ ANIM_PUNCH_R,
+ ANIM_FIGHT_PPUNCH2,
+ ANIM_KICK_FLOOR,
+
+ ANIM_WEAPON_THROWU,
+ ANIM_FIGHT_SH_BACK,
+
ANIM_CAR_JACKED_RHS,
ANIM_CAR_LJACKED_RHS,
ANIM_CAR_JACKED_LHS,
@@ -98,6 +92,7 @@ enum AnimationId
ANIM_CAR_CLOSEDOOR_LOW_LHS,
ANIM_CAR_ROLLDOOR,
ANIM_CAR_ROLLDOOR_LOW,
+ ANIM_CAR_JUMPIN_LHS,
ANIM_CAR_GETOUT_LHS,
ANIM_CAR_GETOUT_LOW_LHS,
ANIM_CAR_CLOSE_LHS,
@@ -123,29 +118,36 @@ enum AnimationId
ANIM_DRIVE_LOW_R,
ANIM_DRIVEBY_L,
ANIM_DRIVEBY_R,
+ ANIM_DRIVEBY_LOW_L,
+ ANIM_DRIVEBY_LOW_R,
ANIM_CAR_LB,
ANIM_DRIVE_BOAT,
+ ANIM_DRIVE_BOAT_L,
+ ANIM_DRIVE_BOAT_R,
+ ANIM_BOAT_LB,
+
+ ANIM_BIKE_PICKUP_R,
+ ANIM_BIKE_PICKUP_L,
+ ANIM_BIKE_PULLUP_R,
+ ANIM_BIKE_PULLUP_L,
+ ANIM_BIKE_ELBOW_R,
+ ANIM_BIKE_ELBOW_L,
+ ANIM_BIKE_FALL_OFF,
+ ANIM_BIKE_FALL_R,
+
ANIM_CAR_GETOUT_RHS,
ANIM_CAR_GETOUT_LOW_RHS,
ANIM_CAR_CLOSE_RHS,
ANIM_CAR_HOOKERTALK,
- ANIM_COACH_OPEN_L,
- ANIM_COACH_OPEN_R,
- ANIM_COACH_IN_L,
- ANIM_COACH_IN_R,
- ANIM_COACH_OUT_L,
- ANIM_TRAIN_GETIN,
- ANIM_TRAIN_GETOUT,
+
+ ANIM_IDLE_STANCE2,
+ ANIM_IDLE_STANCE3,
+
ANIM_CAR_CRAWLOUT_RHS,
ANIM_CAR_CRAWLOUT_RHS2,
- ANIM_VAN_OPEN_L,
- ANIM_VAN_GETIN_L,
- ANIM_VAN_CLOSE_L,
- ANIM_VAN_GETOUT_L,
- ANIM_VAN_OPEN,
- ANIM_VAN_GETIN,
- ANIM_VAN_CLOSE,
- ANIM_VAN_GETOUT,
+ ANIM_CAR_ROLLOUT_LHS,
+ ANIM_CAR_ROLLOUT_RHS,
+
ANIM_GETUP1,
ANIM_GETUP2,
ANIM_GETUP3,
@@ -157,6 +159,9 @@ enum AnimationId
ANIM_FALL_GLIDE,
ANIM_FALL_LAND,
ANIM_FALL_COLLAPSE,
+ ANIM_FALL_BACK,
+ ANIM_FALL_FRONT,
+
ANIM_EV_STEP,
ANIM_EV_DIVE,
ANIM_XPRESS_SCRATCH,
@@ -164,11 +169,12 @@ enum AnimationId
ANIM_TURN_180,
ANIM_ARREST_GUN,
ANIM_DROWN,
- ANIM_CPR,
ANIM_DUCK_DOWN,
ANIM_DUCK_LOW,
+
+ ANIM_WEAPON_CROUCH,
+
ANIM_RBLOCK_CSHOOT,
- ANIM_WEAPON_THROWU2,
ANIM_HANDSUP,
ANIM_HANDSCOWER,
ANIM_FUCKU,
@@ -176,5 +182,92 @@ enum AnimationId
ANIM_PHONE_OUT,
ANIM_PHONE_TALK,
+ ANIM_SEAT_DOWN,
+ ANIM_SEAT_UP,
+ ANIM_SEAT_IDLE,
+ ANIM_SEAT_DOWN2,
+ ANIM_ATM,
+ ANIM_ABSEIL,
+
+ NUM_STD_ANIMS,
+
+ ANIM_VAN_OPEN_L,
+ ANIM_VAN_GETIN_L,
+ ANIM_VAN_CLOSE_L,
+ ANIM_VAN_GETOUT_L,
+ ANIM_VAN_OPEN,
+ ANIM_VAN_GETIN,
+ ANIM_VAN_CLOSE,
+ ANIM_VAN_GETOUT,
+
+ ANIM_COACH_OPEN_L,
+ ANIM_COACH_OPEN_R,
+ ANIM_COACH_IN_L,
+ ANIM_COACH_IN_R,
+ ANIM_COACH_OUT_L,
+
+ ANIM_BIKE_RIDE,
+ ANIM_BIKE_STILL,
+ ANIM_BIKE_LEFT,
+ ANIM_BIKE_RIGHT,
+ ANIM_BIKE_BACK,
+ ANIM_BIKE_FWD,
+ ANIM_BIKE_PUSHES,
+ ANIM_BIKE_JUMPON_R,
+ ANIM_BIKE_JUMPON_L,
+ ANIM_BIKE_KICK,
+ ANIM_BIKE_HIT,
+ ANIM_BIKE_GETOFF_RHS,
+ ANIM_BIKE_GETOFF_LHS,
+ ANIM_BIKE_GETOFF_BACK,
+ ANIM_BIKE_DRIVEBY_RHS,
+ ANIM_BIKE_DRIVEBY_LHS,
+ ANIM_BIKE_DRIVEBY_FT,
+ ANIM_BIKE_PASSENGER,
+
+ ANIM_WEAPON_FIRE,
+ ANIM_WEAPON_CROUCHFIRE,
+ ANIM_WEAPON_RELOAD,
+ ANIM_WEAPON_CROUCHRELOAD,
+ ANIM_WEAPON_SPECIAL,
+ ANIM_MELEE_ATTACK = ANIM_WEAPON_FIRE,
+ ANIM_MELEE_ATTACK_2ND,
+ ANIM_MELEE_ATTACK_START,
+ ANIM_MELEE_IDLE_FIGHTMODE,
+ ANIM_MELEE_ATTACK_FINISH,
+ ANIM_THROWABLE_THROW = ANIM_WEAPON_FIRE,
+ ANIM_THROWABLE_THROWU,
+ ANIM_THROWABLE_START_THROW,
+ ANIM_WEAPON_FIRE_2ND = ANIM_WEAPON_CROUCHFIRE,
+ ANIM_WEAPON_FIRE_3RD = ANIM_WEAPON_SPECIAL,
+
+ ANIM_SUNBATHE,
+ ANIM_SUNBATHE_DOWN,
+ ANIM_SUNBATHE_UP,
+ ANIM_SUNBATHE_ESCAPE,
+
+ ANIM_CPR,
+
+ ANIM_IDLE_STRETCH,
+ ANIM_IDLE_TIME,
+ ANIM_IDLE_SHOULDER,
+ ANIM_IDLE_STRETCH_LEG,
+
+ ANIM_RIOT_ANGRY,
+ ANIM_RIOT_ANGRY_B,
+ ANIM_RIOT_CHANT,
+ ANIM_RIOT_PUNCHES,
+ ANIM_RIOT_SHOUT,
+ ANIM_RIOT_CHALLENGE,
+ ANIM_RIOT_FUKU,
+
+ ANIM_STRIP_A,
+ ANIM_STRIP_B,
+ ANIM_STRIP_C,
+ ANIM_STRIP_D,
+ ANIM_STRIP_E,
+ ANIM_STRIP_F,
+ ANIM_STRIP_G,
+
NUM_ANIMS
}; \ No newline at end of file
diff --git a/src/animation/Bones.cpp b/src/animation/Bones.cpp
index 1608449d..87f3b6e7 100644
--- a/src/animation/Bones.cpp
+++ b/src/animation/Bones.cpp
@@ -2,26 +2,29 @@
#include "PedModelInfo.h"
#include "Bones.h"
-#ifdef PED_SKIN
-
int
ConvertPedNode2BoneTag(int node)
{
switch(node){
- case PED_TORSO: return BONE_waist;
- case PED_MID: return BONE_torso; // this is what Xbox/Mobile use
- // return BONE_mid; // this is what PS2/PC use
- case PED_HEAD: return BONE_head;
- case PED_UPPERARML: return BONE_upperarml;
- case PED_UPPERARMR: return BONE_upperarmr;
- case PED_HANDL: return BONE_Lhand;
- case PED_HANDR: return BONE_Rhand;
- case PED_UPPERLEGL: return BONE_upperlegl;
- case PED_UPPERLEGR: return BONE_upperlegr;
- case PED_FOOTL: return BONE_footl;
- case PED_FOOTR: return BONE_footr;
- case PED_LOWERLEGR: return BONE_lowerlegl;
+ case PED_MID: return BONE_spine1;
+ case PED_HEAD: return BONE_head;
+ case PED_UPPERARML: return BONE_l_upperarm;
+ case PED_UPPERARMR: return BONE_r_upperarm;
+ case PED_HANDL: return BONE_l_hand;
+ case PED_HANDR: return BONE_r_hand;
+ case PED_UPPERLEGL: return BONE_l_thigh;
+ case PED_UPPERLEGR: return BONE_r_thigh;
+ case PED_FOOTL: return BONE_l_foot;
+ case PED_FOOTR: return BONE_r_foot;
+ case PED_LOWERLEGR: return BONE_r_calf;
+ case PED_LOWERLEGL: return BONE_l_calf;
+ case PED_FOREARML: return BONE_l_forearm;
+ case PED_FOREARMR: return BONE_r_forearm;
+ case PED_CLAVICLEL: return BONE_l_clavicle;
+ case PED_CLAVICLER: return BONE_r_clavicle;
+ case PED_NECK: return BONE_neck;
}
+ assert(0 && "this node has no bone");
return -1;
}
@@ -29,24 +32,28 @@ const char*
ConvertBoneTag2BoneName(int tag)
{
switch(tag){
- case BONE_waist: return "Swaist";
- case BONE_upperlegr: return "Supperlegr";
- case BONE_lowerlegr: return "Slowerlegr";
- case BONE_footr: return "Sfootr";
- case BONE_upperlegl: return "Supperlegl";
- case BONE_lowerlegl: return "Slowerlegl";
- case BONE_footl: return "Sfootl";
- case BONE_mid: return "Smid";
- case BONE_torso: return "Storso";
- case BONE_head: return "Shead";
- case BONE_upperarmr: return "Supperarmr";
- case BONE_lowerarmr: return "Slowerarmr";
- case BONE_Rhand: return "SRhand";
- case BONE_upperarml: return "Supperarml";
- case BONE_lowerarml: return "Slowerarml";
- case BONE_Lhand: return "SLhand";
+ case BONE_root: return "Root";
+ case BONE_pelvis: return "Pelvis";
+ case BONE_spine: return "Spine";
+ case BONE_spine1: return "Spine1";
+ case BONE_neck: return "Neck";
+ case BONE_head: return "Head";
+ case BONE_r_clavicle: return "Bip01 R Clavicle";
+ case BONE_r_upperarm: return "R UpperArm";
+ case BONE_r_forearm: return "R Forearm";
+ case BONE_r_hand: return "R Hand";
+ case BONE_r_finger: return "R Fingers";
+ case BONE_l_clavicle: return "Bip01 L Clavicle";
+ case BONE_l_upperarm: return "L UpperArm";
+ case BONE_l_forearm: return "L Forearm";
+ case BONE_l_hand: return "L Hand";
+ case BONE_l_finger: return "L Fingers";
+ case BONE_l_thigh: return "L Thigh";
+ case BONE_l_calf: return "L Calf";
+ case BONE_l_foot: return "L Foot";
+ case BONE_r_thigh: return "R Thigh";
+ case BONE_r_calf: return "R Calf";
+ case BONE_r_foot: return "R Foot";
}
return nil;
}
-
-#endif
diff --git a/src/animation/Bones.h b/src/animation/Bones.h
index 38d91ba3..e133fd7f 100644
--- a/src/animation/Bones.h
+++ b/src/animation/Bones.h
@@ -2,22 +2,28 @@
enum BoneTag
{
- BONE_waist,
- BONE_upperlegr,
- BONE_lowerlegr,
- BONE_footr,
- BONE_upperlegl,
- BONE_lowerlegl,
- BONE_footl,
- BONE_mid,
- BONE_torso,
- BONE_head,
- BONE_upperarmr,
- BONE_lowerarmr,
- BONE_Rhand,
- BONE_upperarml,
- BONE_lowerarml,
- BONE_Lhand,
+ BONE_root = 0,
+ BONE_pelvis = 1,
+ BONE_spine = 2,
+ BONE_spine1 = 3,
+ BONE_neck = 4,
+ BONE_head = 5,
+ BONE_l_clavicle = 31,
+ BONE_l_upperarm = 32,
+ BONE_l_forearm = 33,
+ BONE_l_hand = 34,
+ BONE_l_finger = 35,
+ BONE_r_clavicle = 21,
+ BONE_r_upperarm = 22,
+ BONE_r_forearm = 23,
+ BONE_r_hand = 24,
+ BONE_r_finger = 25,
+ BONE_l_thigh = 41,
+ BONE_l_calf = 42,
+ BONE_l_foot = 43,
+ BONE_r_thigh = 51,
+ BONE_r_calf = 52,
+ BONE_r_foot = 53,
};
int ConvertPedNode2BoneTag(int node);
diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp
index 83c4dbcb..64951a87 100644
--- a/src/animation/CutsceneMgr.cpp
+++ b/src/animation/CutsceneMgr.cpp
@@ -16,94 +16,94 @@
#include "World.h"
#include "PlayerPed.h"
#include "Wanted.h"
-#include "CutsceneHead.h"
#include "RpAnimBlend.h"
#include "ModelIndices.h"
#include "TempColModels.h"
+#include "ColStore.h"
+#include "Radar.h"
+#include "Pools.h"
+
+//--MIAMI: file done
const struct {
const char *szTrackName;
int iTrackId;
} musicNameIdAssoc[] = {
- { "JB", STREAMED_SOUND_NEWS_INTRO },
- { "BET", STREAMED_SOUND_BANK_INTRO },
- { "L1_LG", STREAMED_SOUND_CUTSCENE_LUIGI1_LG },
- { "L2_DSB", STREAMED_SOUND_CUTSCENE_LUIGI2_DSB },
- { "L3_DM", STREAMED_SOUND_CUTSCENE_LUIGI3_DM },
- { "L4_PAP", STREAMED_SOUND_CUTSCENE_LUIGI4_PAP },
- { "L5_TFB", STREAMED_SOUND_CUTSCENE_LUIGI5_TFB },
- { "J0_DM2", STREAMED_SOUND_CUTSCENE_JOEY0_DM2 },
- { "J1_LFL", STREAMED_SOUND_CUTSCENE_JOEY1_LFL },
- { "J2_KCL", STREAMED_SOUND_CUTSCENE_JOEY2_KCL },
- { "J3_VH", STREAMED_SOUND_CUTSCENE_JOEY3_VH },
- { "J4_ETH", STREAMED_SOUND_CUTSCENE_JOEY4_ETH },
- { "J5_DST", STREAMED_SOUND_CUTSCENE_JOEY5_DST },
- { "J6_TBJ", STREAMED_SOUND_CUTSCENE_JOEY6_TBJ },
- { "T1_TOL", STREAMED_SOUND_CUTSCENE_TONI1_TOL },
- { "T2_TPU", STREAMED_SOUND_CUTSCENE_TONI2_TPU },
- { "T3_MAS", STREAMED_SOUND_CUTSCENE_TONI3_MAS },
- { "T4_TAT", STREAMED_SOUND_CUTSCENE_TONI4_TAT },
- { "T5_BF", STREAMED_SOUND_CUTSCENE_TONI5_BF },
- { "S0_MAS", STREAMED_SOUND_CUTSCENE_SAL0_MAS },
- { "S1_PF", STREAMED_SOUND_CUTSCENE_SAL1_PF },
- { "S2_CTG", STREAMED_SOUND_CUTSCENE_SAL2_CTG },
- { "S3_RTC", STREAMED_SOUND_CUTSCENE_SAL3_RTC },
- { "S5_LRQ", STREAMED_SOUND_CUTSCENE_SAL5_LRQ },
- { "S4_BDBA", STREAMED_SOUND_CUTSCENE_SAL4_BDBA },
- { "S4_BDBB", STREAMED_SOUND_CUTSCENE_SAL4_BDBB },
- { "S2_CTG2", STREAMED_SOUND_CUTSCENE_SAL2_CTG2 },
- { "S4_BDBD", STREAMED_SOUND_CUTSCENE_SAL4_BDBD },
- { "S5_LRQB", STREAMED_SOUND_CUTSCENE_SAL5_LRQB },
- { "S5_LRQC", STREAMED_SOUND_CUTSCENE_SAL5_LRQC },
- { "A1_SS0", STREAMED_SOUND_CUTSCENE_ASUKA_1_SSO },
- { "A2_PP", STREAMED_SOUND_CUTSCENE_ASUKA_2_PP },
- { "A3_SS", STREAMED_SOUND_CUTSCENE_ASUKA_3_SS },
- { "A4_PDR", STREAMED_SOUND_CUTSCENE_ASUKA_4_PDR },
- { "A5_K2FT", STREAMED_SOUND_CUTSCENE_ASUKA_5_K2FT},
- { "K1_KBO", STREAMED_SOUND_CUTSCENE_KENJI1_KBO },
- { "K2_GIS", STREAMED_SOUND_CUTSCENE_KENJI2_GIS },
- { "K3_DS", STREAMED_SOUND_CUTSCENE_KENJI3_DS },
- { "K4_SHI", STREAMED_SOUND_CUTSCENE_KENJI4_SHI },
- { "K5_SD", STREAMED_SOUND_CUTSCENE_KENJI5_SD },
- { "R0_PDR2", STREAMED_SOUND_CUTSCENE_RAY0_PDR2 },
- { "R1_SW", STREAMED_SOUND_CUTSCENE_RAY1_SW },
- { "R2_AP", STREAMED_SOUND_CUTSCENE_RAY2_AP },
- { "R3_ED", STREAMED_SOUND_CUTSCENE_RAY3_ED },
- { "R4_GF", STREAMED_SOUND_CUTSCENE_RAY4_GF },
- { "R5_PB", STREAMED_SOUND_CUTSCENE_RAY5_PB },
- { "R6_MM", STREAMED_SOUND_CUTSCENE_RAY6_MM },
- { "D1_STOG", STREAMED_SOUND_CUTSCENE_DONALD1_STOG },
- { "D2_KK", STREAMED_SOUND_CUTSCENE_DONALD2_KK },
- { "D3_ADO", STREAMED_SOUND_CUTSCENE_DONALD3_ADO },
- { "D5_ES", STREAMED_SOUND_CUTSCENE_DONALD5_ES },
- { "D7_MLD", STREAMED_SOUND_CUTSCENE_DONALD7_MLD },
- { "D4_GTA", STREAMED_SOUND_CUTSCENE_DONALD4_GTA },
- { "D4_GTA2", STREAMED_SOUND_CUTSCENE_DONALD4_GTA2 },
- { "D6_STS", STREAMED_SOUND_CUTSCENE_DONALD6_STS },
- { "A6_BAIT", STREAMED_SOUND_CUTSCENE_ASUKA6_BAIT },
- { "A7_ETG", STREAMED_SOUND_CUTSCENE_ASUKA7_ETG },
- { "A8_PS", STREAMED_SOUND_CUTSCENE_ASUKA8_PS },
- { "A9_ASD", STREAMED_SOUND_CUTSCENE_ASUKA9_ASD },
- { "K4_SHI2", STREAMED_SOUND_CUTSCENE_KENJI4_SHI2 },
- { "C1_TEX", STREAMED_SOUND_CUTSCENE_CATALINA1_TEX },
- { "EL_PH1", STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1 },
- { "EL_PH2", STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2 },
- { "EL_PH3", STREAMED_SOUND_CUTSCENE_ELBURRO3_PH3 },
- { "EL_PH4", STREAMED_SOUND_CUTSCENE_ELBURRO4_PH4 },
- { "YD_PH1", STREAMED_SOUND_CUTSCENE_YARDIE_PH1 },
- { "YD_PH2", STREAMED_SOUND_CUTSCENE_YARDIE_PH2 },
- { "YD_PH3", STREAMED_SOUND_CUTSCENE_YARDIE_PH3 },
- { "YD_PH4", STREAMED_SOUND_CUTSCENE_YARDIE_PH4 },
- { "HD_PH1", STREAMED_SOUND_CUTSCENE_HOODS_PH1 },
- { "HD_PH2", STREAMED_SOUND_CUTSCENE_HOODS_PH2 },
- { "HD_PH3", STREAMED_SOUND_CUTSCENE_HOODS_PH3 },
- { "HD_PH4", STREAMED_SOUND_CUTSCENE_HOODS_PH4 },
- { "HD_PH5", STREAMED_SOUND_CUTSCENE_HOODS_PH5 },
- { "MT_PH1", STREAMED_SOUND_CUTSCENE_MARTY_PH1 },
- { "MT_PH2", STREAMED_SOUND_CUTSCENE_MARTY_PH2 },
- { "MT_PH3", STREAMED_SOUND_CUTSCENE_MARTY_PH3 },
- { "MT_PH4", STREAMED_SOUND_CUTSCENE_MARTY_PH4 },
- { NULL, 0 }
+ { "ASS_1", STREAMED_SOUND_CUTSCENE_ASS_1 },
+ { "ASS_2", STREAMED_SOUND_CUTSCENE_ASS_2 },
+ { "BANK_1", STREAMED_SOUND_CUTSCENE_BANK_1 },
+ { "BANK_2A", STREAMED_SOUND_CUTSCENE_BANK_2A },
+ { "BANK_2B", STREAMED_SOUND_CUTSCENE_BANK_2B },
+ { "BANK_3A", STREAMED_SOUND_CUTSCENE_BANK_3A },
+ { "BANK_3B", STREAMED_SOUND_CUTSCENE_BANK_3B },
+ { "BANK_4", STREAMED_SOUND_CUTSCENE_BANK_4 },
+ { "BIKE_1", STREAMED_SOUND_CUTSCENE_BIKE_1 },
+ { "BIKE_2", STREAMED_SOUND_CUTSCENE_BIKE_2 },
+ { "BIKE_3", STREAMED_SOUND_CUTSCENE_BIKE_3 },
+ { "BUD_1", STREAMED_SOUND_CUTSCENE_BUD_1 },
+ { "BUD_2", STREAMED_SOUND_CUTSCENE_BUD_2 },
+ { "BUD_3", STREAMED_SOUND_CUTSCENE_BUD_3 },
+ { "CAP_1", STREAMED_SOUND_CUTSCENE_CAP_1 },
+ { "CAR_1", STREAMED_SOUND_CUTSCENE_CAR_1 },
+ { "CNT_1A", STREAMED_SOUND_CUTSCENE_CNT_1A },
+ { "CNT_1B", STREAMED_SOUND_CUTSCENE_CNT_1B },
+ { "CNT_2", STREAMED_SOUND_CUTSCENE_CNT_2 },
+ { "COK_1", STREAMED_SOUND_CUTSCENE_COK_1 },
+ { "COK_2A", STREAMED_SOUND_CUTSCENE_COK_2A },
+ { "COK_2B", STREAMED_SOUND_CUTSCENE_COK_2B },
+ { "COK_3", STREAMED_SOUND_CUTSCENE_COK_3 },
+ { "COK_4A", STREAMED_SOUND_CUTSCENE_COK_4A },
+ { "COK_4A2", STREAMED_SOUND_CUTSCENE_COK_4A2 },
+ { "COK_4B", STREAMED_SOUND_CUTSCENE_COK_4B },
+ { "COL_1", STREAMED_SOUND_CUTSCENE_COL_1 },
+ { "COL_2", STREAMED_SOUND_CUTSCENE_COL_2 },
+ { "COL_3A", STREAMED_SOUND_CUTSCENE_COL_3A },
+ { "COL_4A", STREAMED_SOUND_CUTSCENE_COL_4A },
+ { "COL_5A", STREAMED_SOUND_CUTSCENE_COL_5A },
+ { "COL_5B", STREAMED_SOUND_CUTSCENE_COL_5B },
+ { "CUB_1", STREAMED_SOUND_CUTSCENE_CUB_1 },
+ { "CUB_2", STREAMED_SOUND_CUTSCENE_CUB_2 },
+ { "CUB_3", STREAMED_SOUND_CUTSCENE_CUB_3 },
+ { "CUB_4", STREAMED_SOUND_CUTSCENE_CUB_4 },
+ { "DRUG_1", STREAMED_SOUND_CUTSCENE_DRUG_1 },
+ { "FIN", STREAMED_SOUND_CUTSCENE_FIN },
+ { "FIN_2", STREAMED_SOUND_CUTSCENE_FIN2 },
+ { "FINALE", STREAMED_SOUND_CUTSCENE_FINALE },
+ { "HAT_1", STREAMED_SOUND_CUTSCENE_HAT_1 },
+ { "HAT_2", STREAMED_SOUND_CUTSCENE_HAT_2 },
+ { "HAT_3", STREAMED_SOUND_CUTSCENE_HAT_3 },
+ { "ICE_1", STREAMED_SOUND_CUTSCENE_ICE_1 },
+ { "INT_A", STREAMED_SOUND_CUTSCENE_INT_A },
+ { "INT_B", STREAMED_SOUND_CUTSCENE_INT_B },
+ { "INT_D", STREAMED_SOUND_CUTSCENE_INT_D },
+ { "INT_M", STREAMED_SOUND_CUTSCENE_INT_M },
+ { "LAW_1A", STREAMED_SOUND_CUTSCENE_LAW_1A },
+ { "LAW_1B", STREAMED_SOUND_CUTSCENE_LAW_1B },
+ { "LAW_2A", STREAMED_SOUND_CUTSCENE_LAW_2A },
+ { "LAW_2B", STREAMED_SOUND_CUTSCENE_LAW_2B },
+ { "LAW_2C", STREAMED_SOUND_CUTSCENE_LAW_2C },
+ { "LAW_3", STREAMED_SOUND_CUTSCENE_LAW_3 },
+ { "LAW_4", STREAMED_SOUND_CUTSCENE_LAW_4 },
+ { "PHIL_1", STREAMED_SOUND_CUTSCENE_PHIL_1 },
+ { "PHIL_2", STREAMED_SOUND_CUTSCENE_PHIL_2 },
+ { "PORN_1", STREAMED_SOUND_CUTSCENE_PORN_1 },
+ { "PORN_2", STREAMED_SOUND_CUTSCENE_PORN_2 },
+ { "PORN_3", STREAMED_SOUND_CUTSCENE_PORN_3 },
+ { "PORN_4", STREAMED_SOUND_CUTSCENE_PORN_4 },
+ { "RESC_1A", STREAMED_SOUND_CUTSCENE_RESC_1A },
+ { "ROK_1", STREAMED_SOUND_CUTSCENE_ROK_1 },
+ { "ROK_2", STREAMED_SOUND_CUTSCENE_ROK_2 },
+ { "ROK_3A", STREAMED_SOUND_CUTSCENE_ROK_3A },
+ { "STRIPA", STREAMED_SOUND_CUTSCENE_STRIPA },
+ { "TAX_1", STREAMED_SOUND_CUTSCENE_TAX_1 },
+ { "TEX_1", STREAMED_SOUND_CUTSCENE_TEX_1 },
+ { "TEX_2", STREAMED_SOUND_CUTSCENE_TEX_2 },
+ { "TEX_3", STREAMED_SOUND_CUTSCENE_TEX_3 },
+ { "GSPOT", STREAMED_SOUND_CUTSCENE_GLIGHT },
+ { "FIST", STREAMED_SOUND_CUTSCENE_FIST },
+ { "EL_PH1", STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1 },
+ { "EL_PH2", STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2 },
+ { NULL, 0 }
};
int
@@ -128,7 +128,18 @@ char CCutsceneMgr::ms_cutsceneName[CUTSCENENAMESIZE];
CAnimBlendAssocGroup CCutsceneMgr::ms_cutsceneAssociations;
CVector CCutsceneMgr::ms_cutsceneOffset;
float CCutsceneMgr::ms_cutsceneTimer;
+bool CCutsceneMgr::ms_wasCutsceneSkipped;
uint32 CCutsceneMgr::ms_cutsceneLoadStatus;
+bool CCutsceneMgr::ms_useCutsceneShadows = true;
+
+bool bCamLoaded;
+bool bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver; // pls don't shrink the name :P
+int32 NumberOfSavedWeapons;
+eWeaponType SavedWeaponIDs[TOTAL_WEAPON_SLOTS];
+int32 SavedWeaponAmmo[TOTAL_WEAPON_SLOTS];
+char uncompressedAnims[8][32];
+uint32 numUncompressedAnims;
+
RpAtomic *
CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data)
@@ -150,13 +161,17 @@ CCutsceneMgr::Initialise(void)
{
ms_numCutsceneObjs = 0;
ms_loaded = false;
+ ms_wasCutsceneSkipped = false;
ms_running = false;
+ ms_useLodMultiplier = false;
ms_animLoaded = false;
ms_cutsceneProcessing = false;
- ms_useLodMultiplier = false;
ms_pCutsceneDir = new CDirectory(CUTSCENEDIRSIZE);
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
+
+ numUncompressedAnims = 0;
+ uncompressedAnims[0][0] = '\0';
}
void
@@ -174,9 +189,10 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CPlayerPed *pPlayerPed;
ms_cutsceneProcessing = true;
- if (!strcasecmp(szCutsceneName, "jb"))
- ms_useLodMultiplier = true;
- CTimer::Stop();
+ ms_wasCutsceneSkipped = false;
+ CTimer::Suspend();
+ if (!bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver)
+ CStreaming::RemoveCurrentZonesModels();
ms_pCutsceneDir->numEntries = 0;
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
@@ -185,32 +201,42 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CGame::DrasticTidyUpMemory(true);
strcpy(ms_cutsceneName, szCutsceneName);
- file = CFileMgr::OpenFile("ANIM\\CUTS.IMG", "rb");
+
+ RwStream *stream;
+ stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
+ assert(stream);
// Load animations
sprintf(gString, "%s.IFP", szCutsceneName);
if (ms_pCutsceneDir->FindItem(gString, offset, size)) {
CStreaming::MakeSpaceFor(size << 11);
CStreaming::ImGonnaUseStreamingMemory();
- CFileMgr::Seek(file, offset << 11, SEEK_SET);
- CAnimManager::LoadAnimFile(file, false);
+ RwStreamSkip(stream, offset << 11);
+ CAnimManager::LoadAnimFile(stream, true, uncompressedAnims);
ms_cutsceneAssociations.CreateAssociations(szCutsceneName);
CStreaming::IHaveUsedStreamingMemory();
ms_animLoaded = true;
} else {
ms_animLoaded = false;
}
+ RwStreamClose(stream, nil);
// Load camera data
+ file = CFileMgr::OpenFile("ANIM\\CUTS.IMG", "rb");
sprintf(gString, "%s.DAT", szCutsceneName);
if (ms_pCutsceneDir->FindItem(gString, offset, size)) {
+ CStreaming::ImGonnaUseStreamingMemory();
CFileMgr::Seek(file, offset << 11, SEEK_SET);
TheCamera.LoadPathSplines(file);
+ CStreaming::IHaveUsedStreamingMemory();
+ bCamLoaded = true;
+ } else {
+ bCamLoaded = false;
}
CFileMgr::CloseFile(file);
- if (CGeneral::faststricmp(ms_cutsceneName, "end")) {
+ if (CGeneral::faststricmp(ms_cutsceneName, "finale")) {
DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE);
int trackId = FindCutsceneAudioTrackId(szCutsceneName);
if (trackId != -1) {
@@ -225,30 +251,23 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
ms_cutsceneOffset = CVector(0.0f, 0.0f, 0.0f);
pPlayerPed = FindPlayerPed();
- CTimer::Update();
-
pPlayerPed->m_pWanted->ClearQdCrimes();
pPlayerPed->bIsVisible = false;
pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_CUTSCENE);
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(true);
-}
-
-void
-CCutsceneMgr::SetHeadAnim(const char *animName, CObject *pObject)
-{
- CCutsceneHead *pCutsceneHead = (CCutsceneHead*)pObject;
- char szAnim[CUTSCENENAMESIZE * 2];
- sprintf(szAnim, "%s_%s", ms_cutsceneName, animName);
- pCutsceneHead->PlayAnimation(szAnim);
+ CTimer::Resume();
}
void
CCutsceneMgr::FinishCutscene()
{
- CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f;
- TheCamera.FinishCutscene();
+ ms_wasCutsceneSkipped = true;
+ if (bCamLoaded) {
+ CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f;
+ TheCamera.FinishCutscene();
+ }
FindPlayerPed()->bIsVisible = true;
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false);
@@ -257,9 +276,11 @@ CCutsceneMgr::FinishCutscene()
void
CCutsceneMgr::SetupCutsceneToStart(void)
{
- TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset);
- TheCamera.TakeControlWithSpline(JUMP_CUT);
- TheCamera.SetWideScreenOn();
+ if (bCamLoaded) {
+ TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset);
+ TheCamera.TakeControlWithSpline(JUMP_CUT);
+ TheCamera.SetWideScreenOn();
+ }
ms_cutsceneOffset.z++;
@@ -267,12 +288,24 @@ CCutsceneMgr::SetupCutsceneToStart(void)
assert(RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP);
if (CAnimBlendAssociation *pAnimBlendAssoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)ms_pCutsceneObjects[i]->m_rwObject)) {
assert(pAnimBlendAssoc->hierarchy->sequences[0].HasTranslation());
- ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0))->translation);
- CWorld::Add(ms_pCutsceneObjects[i]);
+ if (ms_pCutsceneObjects[i]->m_pAttachTo != nil) {
+ pAnimBlendAssoc->flags &= (~ASSOC_HAS_TRANSLATION);
+ } else {
+ KeyFrameTrans* keyFrames;
+ if (pAnimBlendAssoc->hierarchy->IsCompressed())
+ keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0));
+ else
+ keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0));
+ ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation);
+ }
pAnimBlendAssoc->SetRun();
} else {
ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset);
}
+ CWorld::Add(ms_pCutsceneObjects[i]);
+ if (RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP) {
+ ms_pCutsceneObjects[i]->UpdateRpHAnim();
+ }
}
CTimer::Update();
@@ -288,25 +321,55 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject)
CAnimBlendClumpData *pAnimBlendClumpData;
assert(RwObjectGetType(pObject->m_rwObject) == rpCLUMP);
+ debug("Give cutscene anim %s\n", animName);
RpAnimBlendClumpRemoveAllAssociations((RpClump*)pObject->m_rwObject);
+ pNewAnim = ms_cutsceneAssociations.GetAnimation(animName);
+ if (!pNewAnim) {
+ debug("\n\nHaven't I told you I can't find the fucking animation %s\n\n\n", animName);
+ return;
+ }
+
+ if (pNewAnim->hierarchy->IsCompressed())
+ pNewAnim->hierarchy->compressed2 = true;
+
+ CStreaming::ImGonnaUseStreamingMemory();
pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName);
+ CStreaming::IHaveUsedStreamingMemory();
+
pNewAnim->SetCurrentTime(0.0f);
pNewAnim->flags |= ASSOC_HAS_TRANSLATION;
pNewAnim->flags &= ~ASSOC_RUNNING;
pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject);
pAnimBlendClumpData->link.Prepend(&pNewAnim->link);
+
+ if (pNewAnim->hierarchy->compressed2)
+ pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::UNK_COMPRESSED;
+}
+
+void
+CCutsceneMgr::SetCutsceneAnimToLoop(const char* animName)
+{
+ ms_cutsceneAssociations.GetAnimation(animName)->flags |= ASSOC_REPEAT;
}
CCutsceneHead *
CCutsceneMgr::AddCutsceneHead(CObject *pObject, int modelId)
{
- CCutsceneHead *pHead = new CCutsceneHead(pObject);
- pHead->SetModelIndex(modelId);
- CWorld::Add(pHead);
- ms_pCutsceneObjects[ms_numCutsceneObjs++] = pHead;
- return pHead;
+ return nil;
+}
+
+void UpdateCutsceneObjectBoundingBox(RpClump* clump, int modelId)
+{
+ if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) {
+ CColModel* pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01];
+ float radius = 0.0f;
+ RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
+ pColModel->boundingSphere.radius = radius;
+ pColModel->boundingBox.min = CVector(-radius, -radius, -radius);
+ pColModel->boundingBox.max = CVector(radius, radius, radius);
+ }
}
CCutsceneObject *
@@ -314,20 +377,25 @@ CCutsceneMgr::CreateCutsceneObject(int modelId)
{
CBaseModelInfo *pModelInfo;
CColModel *pColModel;
- float radius;
- RpClump *clump;
CCutsceneObject *pCutsceneObject;
+ CStreaming::ImGonnaUseStreamingMemory();
+ debug("Created cutscene object %s\n", CModelInfo::GetModelInfo(modelId)->GetName());
if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) {
pModelInfo = CModelInfo::GetModelInfo(modelId);
pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01];
- radius = 0.0f;
-
pModelInfo->SetColModel(pColModel);
- clump = (RpClump*)pModelInfo->GetRwObject();
- assert(RwObjectGetType((RwObject*)clump) == rpCLUMP);
- RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
-
+ UpdateCutsceneObjectBoundingBox((RpClump*)pModelInfo->GetRwObject(), modelId);
+ } else if (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL21) {
+ pModelInfo = CModelInfo::GetModelInfo(modelId);
+ if (pModelInfo->GetColModel() == &CTempColModels::ms_colModelPed1) {
+ CColModel *colModel = new CColModel();
+ colModel->boundingSphere.radius = 2.0f;
+ colModel->boundingSphere.center = CVector(0.0f, 0.0f, 0.0f);
+ pModelInfo->SetColModel(colModel, true);
+ }
+ pColModel = pModelInfo->GetColModel();
+ float radius = 2.0f;
pColModel->boundingSphere.radius = radius;
pColModel->boundingBox.min = CVector(-radius, -radius, -radius);
pColModel->boundingBox.max = CVector(radius, radius, radius);
@@ -335,7 +403,10 @@ CCutsceneMgr::CreateCutsceneObject(int modelId)
pCutsceneObject = new CCutsceneObject();
pCutsceneObject->SetModelIndex(modelId);
+ if (ms_useCutsceneShadows)
+ pCutsceneObject->CreateShadow();
ms_pCutsceneObjects[ms_numCutsceneObjs++] = pCutsceneObject;
+ CStreaming::IHaveUsedStreamingMemory();
return pCutsceneObject;
}
@@ -343,9 +414,11 @@ void
CCutsceneMgr::DeleteCutsceneData(void)
{
if (!ms_loaded) return;
+ CTimer::Suspend();
ms_cutsceneProcessing = false;
ms_useLodMultiplier = false;
+ ms_useCutsceneShadows = true;
for (--ms_numCutsceneObjs; ms_numCutsceneObjs >= 0; ms_numCutsceneObjs--) {
CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]);
@@ -355,12 +428,27 @@ CCutsceneMgr::DeleteCutsceneData(void)
}
ms_numCutsceneObjs = 0;
+ for (int i = MI_SPECIAL01; i < MI_SPECIAL21; i++) {
+ CBaseModelInfo *minfo = CModelInfo::GetModelInfo(i);
+ CColModel *colModel = minfo->GetColModel();
+ if (colModel != &CTempColModels::ms_colModelPed1) {
+ delete colModel;
+ minfo->SetColModel(&CTempColModels::ms_colModelPed1);
+ }
+ }
+
if (ms_animLoaded)
CAnimManager::RemoveLastAnimFile();
ms_animLoaded = false;
- TheCamera.RestoreWithJumpCut();
- TheCamera.SetWideScreenOff();
+ numUncompressedAnims = 0;
+ uncompressedAnims[0][0] = '\0';
+
+ if (bCamLoaded) {
+ TheCamera.RestoreWithJumpCut();
+ TheCamera.SetWideScreenOff();
+ TheCamera.DeleteCutSceneCamDataMemory();
+ }
ms_running = false;
ms_loaded = false;
@@ -368,14 +456,42 @@ CCutsceneMgr::DeleteCutsceneData(void)
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_CUTSCENE);
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false);
- if (CGeneral::faststricmp(ms_cutsceneName, "end")) {
+ if (CGeneral::faststricmp(ms_cutsceneName, "finale")) {
DMAudio.StopCutSceneMusic();
- if (CGeneral::faststricmp(ms_cutsceneName, "bet"))
- DMAudio.ChangeMusicMode(MUSICMODE_GAME);
+ DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
- CTimer::Stop();
- CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == FADE_2);
- CTimer::Update();
+
+ CStreaming::ms_disableStreaming = false;
+ CWorld::bProcessCutsceneOnly = false;
+
+ if(bCamLoaded)
+ CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == FADE_2);
+
+ CPad::GetPad(0)->Clear(false);
+ if (bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver) {
+ CStreaming::LoadInitialPeds();
+ CStreaming::LoadInitialWeapons();
+ CStreaming::LoadInitialVehicles();
+ bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver = false;
+
+ CPlayerPed *pPlayerPed = FindPlayerPed();
+ for (int i = 0; i < NumberOfSavedWeapons; i++) {
+ int32 weaponModelId = CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModelId;
+ uint8 flags = CStreaming::ms_aInfoForModel[weaponModelId].m_flags;
+ CStreaming::RequestModel(weaponModelId, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
+ if (CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModel2Id != -1) {
+ CStreaming::RequestModel(CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModel2Id, 0);
+ CStreaming::LoadAllRequestedModels(false);
+ }
+ if (!(flags & STREAMFLAGS_DONT_REMOVE))
+ CStreaming::SetModelIsDeletable(weaponModelId);
+ pPlayerPed->GiveWeapon(SavedWeaponIDs[i], SavedWeaponAmmo[i], true);
+ }
+ NumberOfSavedWeapons = 0;
+ }
+
+ CTimer::Resume();
}
void
@@ -392,7 +508,7 @@ CCutsceneMgr::Update(void)
switch (ms_cutsceneLoadStatus) {
case CUTSCENE_LOADING_AUDIO:
SetupCutsceneToStart();
- if (CGeneral::faststricmp(ms_cutsceneName, "end"))
+ if (CGeneral::faststricmp(ms_cutsceneName, "finale"))
DMAudio.PlayPreloadedCutSceneMusic();
ms_cutsceneLoadStatus++;
break;
@@ -410,15 +526,157 @@ CCutsceneMgr::Update(void)
if (!ms_running) return;
ms_cutsceneTimer += CTimer::GetTimeStepNonClippedInSeconds();
- if (CGeneral::faststricmp(ms_cutsceneName, "end") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) {
- if (CPad::GetPad(0)->GetCrossJustDown()
- || (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
- || CPad::GetPad(0)->GetLeftMouseJustDown()
- || CPad::GetPad(0)->GetEnterJustDown()
- || CPad::GetPad(0)->GetCharJustDown(' '))
- FinishCutscene();
+
+ for (int i = 0; i < ms_numCutsceneObjs; i++) {
+ int modelId = ms_pCutsceneObjects[i]->GetModelIndex();
+ if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05)
+ UpdateCutsceneObjectBoundingBox(ms_pCutsceneObjects[i]->GetClump(), modelId);
+
+ if (ms_pCutsceneObjects[i]->m_pAttachTo != nil && modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL21)
+ UpdateCutsceneObjectBoundingBox(ms_pCutsceneObjects[i]->GetClump(), modelId);
}
+
+ if (bCamLoaded)
+ if (CGeneral::faststricmp(ms_cutsceneName, "finale") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) {
+ if (CPad::GetPad(0)->GetCrossJustDown()
+ || (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
+ || CPad::GetPad(0)->GetLeftMouseJustDown()
+ || CPad::GetPad(0)->GetEnterJustDown()
+ || CPad::GetPad(0)->GetCharJustDown(' '))
+ FinishCutscene();
+ }
}
-bool CCutsceneMgr::HasCutsceneFinished(void) { return TheCamera.GetPositionAlongSpline() == 1.0f; }
+bool CCutsceneMgr::HasCutsceneFinished(void) { return !bCamLoaded || TheCamera.GetPositionAlongSpline() == 1.0f; }
+
+void
+CCutsceneMgr::LoadAnimationUncompressed(char const* name)
+{
+ strcpy(uncompressedAnims[numUncompressedAnims], name);
+
+ // Because that's how CAnimManager knows the end of array
+ ++numUncompressedAnims;
+ assert(numUncompressedAnims < ARRAY_SIZE(uncompressedAnims));
+ uncompressedAnims[numUncompressedAnims][0] = '\0';
+}
+void
+CCutsceneMgr::AttachObjectToParent(CObject *pObject, CEntity *pAttachTo)
+{
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = RpClumpGetFrame(pAttachTo->GetClump());
+
+ debug("Attach %s to %s\n", CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(), CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+}
+
+void
+CCutsceneMgr::AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const char *frame)
+{
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = RpAnimBlendClumpFindFrame(pAttachTo->GetClump(), frame)->frame;
+ debug("Attach %s to component %s of %s\n",
+ CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(),
+ frame,
+ CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+ if (RwObjectGetType(pObject->m_rwObject) == rpCLUMP) {
+ RpClump *clump = (RpClump*)pObject->m_rwObject;
+ if (IsClumpSkinned(clump))
+ RpAtomicGetBoundingSphere(GetFirstAtomic(clump))->radius *= 1.1f;
+ }
+}
+
+void
+CCutsceneMgr::AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int bone)
+{
+ RpHAnimHierarchy *hanim = GetAnimHierarchyFromSkinClump(pAttachTo->GetClump());
+ RwInt32 id = RpHAnimIDGetIndex(hanim, bone);
+ RwMatrix *matrixArray = RpHAnimHierarchyGetMatrixArray(hanim);
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = pAttachTo;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = &matrixArray[id];
+ debug("Attach %s to %s\n",
+ CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(),
+ CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+}
+
+void
+CCutsceneMgr::RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver()
+{
+ CStreaming::ms_disableStreaming = true;
+ CColStore::RemoveAllCollision();
+ CWorld::bProcessCutsceneOnly = true;
+ ms_cutsceneProcessing = true;
+
+ for (int i = CPools::GetPedPool()->GetSize() - 1; i >= 0; i--) {
+ CPed *pPed = CPools::GetPedPool()->GetSlot(i);
+ if (pPed) {
+ if (!pPed->IsPlayer() && pPed->CanBeDeleted()) {
+ CWorld::Remove(pPed);
+ delete pPed;
+ }
+ }
+ }
+
+ for (int i = CPools::GetVehiclePool()->GetSize() - 1; i >= 0; i--) {
+ CVehicle *pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (pVehicle) {
+ if (pVehicle->CanBeDeleted()) {
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
+ }
+ }
+
+ bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver = true;
+ CStreaming::RemoveCurrentZonesModels();
+ CStreaming::SetModelIsDeletable(MI_MALE01);
+ CStreaming::SetModelTxdIsDeletable(MI_MALE01);
+ CStreaming::SetModelIsDeletable(MI_HMOCA);
+ CStreaming::SetModelTxdIsDeletable(MI_HMOCA);
+ CStreaming::SetModelIsDeletable(MI_NIGHTSTICK);
+ CStreaming::SetModelTxdIsDeletable(MI_NIGHTSTICK);
+ CStreaming::SetModelIsDeletable(MI_MISSILE);
+ CStreaming::SetModelTxdIsDeletable(MI_MISSILE);
+ CStreaming::SetModelIsDeletable(MI_POLICE);
+ CStreaming::SetModelTxdIsDeletable(MI_POLICE);
+
+ while (CStreaming::RemoveLoadedVehicle()) ;
+
+ CRadar::RemoveRadarSections();
+
+ for (int i = CPools::GetDummyPool()->GetSize() - 1; i >= 0; i--) {
+ CDummy* pDummy = CPools::GetDummyPool()->GetSlot(i);
+ if (pDummy)
+ pDummy->DeleteRwObject();
+ }
+
+ for (int i = CPools::GetObjectPool()->GetSize() - 1; i >= 0; i--) {
+ CObject* pObject = CPools::GetObjectPool()->GetSlot(i);
+ if (pObject)
+ pObject->DeleteRwObject();
+ }
+
+ for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) {
+ CBuilding* pBuilding = CPools::GetBuildingPool()->GetSlot(i);
+ if (pBuilding && pBuilding->m_rwObject != nil && pBuilding->bIsBIGBuilding && pBuilding->bStreamBIGBuilding) {
+ if (pBuilding->bIsBIGBuilding)
+ CStreaming::RequestModel(pBuilding->GetModelIndex(), 0);
+ if (!pBuilding->bImBeingRendered)
+ pBuilding->DeleteRwObject();
+ }
+ }
+
+ CPlayerPed *pPlayerPed = FindPlayerPed();
+ pPlayerPed->RemoveWeaponAnims(0, -1000.0f);
+ NumberOfSavedWeapons = 0;
+
+ for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
+ if (pPlayerPed->m_weapons[i].m_eWeaponType != WEAPONTYPE_UNARMED) {
+ SavedWeaponIDs[NumberOfSavedWeapons] = pPlayerPed->m_weapons[i].m_eWeaponType;
+ SavedWeaponAmmo[NumberOfSavedWeapons] = pPlayerPed->m_weapons[i].m_nAmmoTotal;
+ NumberOfSavedWeapons++;
+ }
+ }
+
+ pPlayerPed->ClearWeapons();
+ CGame::DrasticTidyUpMemory(true);
+} \ No newline at end of file
diff --git a/src/animation/CutsceneMgr.h b/src/animation/CutsceneMgr.h
index bfdcdb57..51ef6c04 100644
--- a/src/animation/CutsceneMgr.h
+++ b/src/animation/CutsceneMgr.h
@@ -21,7 +21,9 @@ class CCutsceneMgr
static CAnimBlendAssocGroup ms_cutsceneAssociations;
static CVector ms_cutsceneOffset;
static float ms_cutsceneTimer;
+ static bool ms_wasCutsceneSkipped;
static bool ms_cutsceneProcessing;
+ static bool ms_useCutsceneShadows;
public:
static CDirectory *ms_pCutsceneDir;
static uint32 ms_cutsceneLoadStatus;
@@ -30,6 +32,7 @@ public:
static bool IsRunning(void) { return ms_running; }
static bool HasLoaded(void) { return ms_loaded; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
+ static bool WasCutsceneSkipped(void) { return ms_wasCutsceneSkipped; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }
static int GetCutsceneTimeInMilleseconds(void) { return 1000.0f * ms_cutsceneTimer; }
@@ -41,11 +44,18 @@ public:
static void Shutdown(void);
static void LoadCutsceneData(const char *szCutsceneName);
static void FinishCutscene(void);
- static void SetHeadAnim(const char *animName, CObject *pObject);
static void SetupCutsceneToStart(void);
static void SetCutsceneAnim(const char *animName, CObject *pObject);
+ static void SetCutsceneAnimToLoop(const char *animName);
static CCutsceneHead *AddCutsceneHead(CObject *pObject, int modelId);
static CCutsceneObject *CreateCutsceneObject(int modelId);
static void DeleteCutsceneData(void);
+ static void LoadAnimationUncompressed(char const*);
static void Update(void);
+
+ static void AttachObjectToParent(CObject *pObject, CEntity *pAttachTo);
+ static void AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const char *frame);
+ static void AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int frame);
+ static void RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver();
+ static void DisableCutsceneShadows() { ms_useCutsceneShadows = false; }
};
diff --git a/src/animation/FrameUpdate.cpp b/src/animation/FrameUpdate.cpp
index 6e5501cb..faeea709 100644
--- a/src/animation/FrameUpdate.cpp
+++ b/src/animation/FrameUpdate.cpp
@@ -6,6 +6,8 @@
#include "AnimBlendAssociation.h"
#include "RpAnimBlend.h"
+//--MIAMI: file done
+
CAnimBlendClumpData *gpAnimBlendClump;
// PS2 names without "NonSkinned"
@@ -17,7 +19,6 @@ void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
-
void
FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg)
{
@@ -228,12 +229,11 @@ FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(AnimBlendFrameData *frame,
RwMatrixUpdate(mat);
}
-#ifdef PED_SKIN
-
void
FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg)
{
CVector vec, pos(0.0f, 0.0f, 0.0f);
+ float transBlendAmount = 0.0f;
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
float totalBlendAmount = 0.0f;
RpHAnimStdInterpFrame *xform = frame->hanimFrame;
@@ -257,13 +257,13 @@ FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg)
for(node = updateData->nodes; *node; node++){
if((*node)->sequence){
(*node)->Update(vec, q, 1.0f-totalBlendAmount);
- if((*node)->sequence->HasTranslation())
+ if((*node)->sequence->HasTranslation()){
pos += vec;
-#ifdef FIX_BUGS
+ transBlendAmount += (*node)->association->blendAmount;
+ }
if(DotProduct(rot, q) < 0.0f)
rot -= q;
else
-#endif
rot += q;
}
++*node;
@@ -278,12 +278,12 @@ FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg)
}
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
- xform->t.x = pos.x;
- xform->t.y = pos.y;
- xform->t.z = pos.z;
- xform->t.x += frame->resetPos.x;
- xform->t.y += frame->resetPos.y;
- xform->t.z += frame->resetPos.z;
+ xform->t.x = transBlendAmount*pos.x;
+ xform->t.y = transBlendAmount*pos.y;
+ xform->t.z = transBlendAmount*pos.z;
+ xform->t.x += (1.0f-transBlendAmount)*frame->resetPos.x;
+ xform->t.y += (1.0f-transBlendAmount)*frame->resetPos.y;
+ xform->t.z += (1.0f-transBlendAmount)*frame->resetPos.z;
}
}
@@ -319,11 +319,9 @@ FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void
for(node = updateData->nodes; *node; node++){
if((*node)->sequence){
bool nodelooped = (*node)->Update(vec, q, 1.0f-totalBlendAmount);
-#ifdef FIX_BUGS
if(DotProduct(rot, q) < 0.0f)
rot -= q;
else
-#endif
rot += q;
if((*node)->sequence->HasTranslation()){
pos += vec;
@@ -442,4 +440,9 @@ FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, vo
}
}
-#endif
+void
+FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg)
+{
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && gpAnimBlendClump->velocity)
+ FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg);
+}
diff --git a/src/animation/RpAnimBlend.cpp b/src/animation/RpAnimBlend.cpp
index dcb656ee..e93615b7 100644
--- a/src/animation/RpAnimBlend.cpp
+++ b/src/animation/RpAnimBlend.cpp
@@ -9,9 +9,9 @@
#include "AnimBlendHierarchy.h"
#include "AnimBlendAssociation.h"
#include "RpAnimBlend.h"
-#ifdef PED_SKIN
#include "PedModelInfo.h"
-#endif
+
+//--MIAMI: file done
RwInt32 ClumpOffset;
@@ -141,7 +141,6 @@ FrameInitCBskin(AnimBlendFrameData *frameData, void*)
frameData->flag = 0;
}
-#ifdef PED_SKIN
void
RpAnimBlendClumpInitSkinned(RpClump *clump)
{
@@ -155,7 +154,7 @@ RpAnimBlendClumpInitSkinned(RpClump *clump)
RpAnimBlendAllocateData(clump);
clumpData = *RPANIMBLENDCLUMPDATA(clump);
- atomic = IsClumpSkinned(clump);
+ atomic = GetFirstAtomic(clump);
assert(atomic);
skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic));
assert(skin);
@@ -170,12 +169,15 @@ RpAnimBlendClumpInitSkinned(RpClump *clump)
for(i = 0; i < numBones; i++){
frames[i].nodeID = HIERNODEID(hier, i);
frames[i].resetPos = boneTab[i];
+#ifdef LIBRW
frames[i].hanimFrame = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
+#else
+ frames[i].hanimFrame = (RpHAnimStdInterpFrame*)rtANIMGETINTERPFRAME(hier->currentAnim, i);
+#endif
}
clumpData->ForAllFrames(FrameInitCBskin, nil);
clumpData->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION;
}
-#endif
void
RpAnimBlendClumpInitNotSkinned(RpClump *clump)
@@ -199,11 +201,9 @@ RpAnimBlendClumpInitNotSkinned(RpClump *clump)
void
RpAnimBlendClumpInit(RpClump *clump)
{
-#ifdef PED_SKIN
if(IsClumpSkinned(clump))
RpAnimBlendClumpInitSkinned(clump);
else
-#endif
RpAnimBlendClumpInitNotSkinned(clump);
}
@@ -363,7 +363,6 @@ FillFrameArrayCBnonskin(AnimBlendFrameData *frame, void *arg)
frames[CVisibilityPlugins::GetFrameHierarchyId(frame->frame)] = frame;
}
-#ifdef PED_SKIN
void
RpAnimBlendClumpFillFrameArraySkin(RpClump *clump, AnimBlendFrameData **frames)
{
@@ -373,22 +372,18 @@ RpAnimBlendClumpFillFrameArraySkin(RpClump *clump, AnimBlendFrameData **frames)
for(i = PED_MID; i < PED_NODE_MAX; i++)
frames[i] = &clumpData->frames[RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(i))];
}
-#endif
void
RpAnimBlendClumpFillFrameArray(RpClump *clump, AnimBlendFrameData **frames)
{
-#ifdef PED_SKIN
if(IsClumpSkinned(clump))
RpAnimBlendClumpFillFrameArraySkin(clump, frames);
else
-#endif
(*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FillFrameArrayCBnonskin, frames);
}
AnimBlendFrameData *pFrameDataFound;
-// FrameFindCallBack on PS2
void
FrameFindByNameCBnonskin(AnimBlendFrameData *frame, void *arg)
{
@@ -397,7 +392,6 @@ FrameFindByNameCBnonskin(AnimBlendFrameData *frame, void *arg)
pFrameDataFound = frame;
}
-#ifdef PED_SKIN
void
FrameFindByNameCBskin(AnimBlendFrameData *frame, void *arg)
{
@@ -405,25 +399,55 @@ FrameFindByNameCBskin(AnimBlendFrameData *frame, void *arg)
if(name && CGeneral::faststricmp(name, (char*)arg) == 0)
pFrameDataFound = frame;
}
-#endif
+
+void
+FrameFindByBoneCB(AnimBlendFrameData *frame, void *arg)
+{
+ if(frame->nodeID == (int32)(uintptr)arg)
+ pFrameDataFound = frame;
+}
AnimBlendFrameData*
RpAnimBlendClumpFindFrame(RpClump *clump, const char *name)
{
pFrameDataFound = nil;
-#ifdef PED_SKIN
if(IsClumpSkinned(clump))
(*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByNameCBskin, (void*)name);
else
-#endif
(*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByNameCBnonskin, (void*)name);
return pFrameDataFound;
}
+AnimBlendFrameData*
+RpAnimBlendClumpFindBone(RpClump *clump, uint32 boneTag)
+{
+ pFrameDataFound = nil;
+ (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByBoneCB, (void*)boneTag);
+ return pFrameDataFound;
+}
+
void
-RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta)
+RpAnimBlendNodeUpdateKeyframes(AnimBlendFrameData *frames, AnimBlendFrameUpdateData *updateData, int32 numNodes)
{
+ CAnimBlendNode **node;
int i;
+
+ for(node = updateData->nodes; *node; node++){
+ CAnimBlendAssociation *a = (*node)->association;
+ for(i = 0; i < numNodes; i++)
+ if((frames[i].flag & AnimBlendFrameData::VELOCITY_EXTRACTION) == 0 ||
+ gpAnimBlendClump->velocity == nil){
+ if((*node)[i].sequence)
+ (*node)[i].FindKeyFrame(a->currentTime - a->timeStep);
+ }
+ }
+}
+
+void
+RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender)
+{
+ int i;
+ CAnimBlendAssociation *assoc;
AnimBlendFrameUpdateData updateData;
float totalLength = 0.0f;
float totalBlend = 0.0f;
@@ -439,30 +463,45 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta)
updateData.foobar = 0;
for(link = clumpData->link.next; link; link = next){
next = link->next;
- CAnimBlendAssociation *assoc = CAnimBlendAssociation::FromLink(link);
+ assoc = CAnimBlendAssociation::FromLink(link);
if(assoc->UpdateBlend(timeDelta)){
- // CAnimManager::UncompressAnimation(v6->hierarchy)
- updateData.nodes[i++] = assoc->GetNode(0);
- if(assoc->flags & ASSOC_MOVEMENT){
- totalLength += assoc->hierarchy->totalLength/assoc->speed * assoc->blendAmount;
- totalBlend += assoc->blendAmount;
+ if(assoc->hierarchy->sequences){
+ //CAnimManager::UncompressAnimation(v6->hierarchy)
+ if(i < 11)
+ updateData.nodes[i++] = assoc->GetNode(0);
+ if(assoc->flags & ASSOC_MOVEMENT){
+ totalLength += assoc->hierarchy->totalLength/assoc->speed * assoc->blendAmount;
+ totalBlend += assoc->blendAmount;
+ }else
+ updateData.foobar = 1;
}else
- updateData.foobar = 1;
+ debug("anim %s is not loaded\n", assoc->hierarchy->name);
}
}
+
+ for(link = clumpData->link.next; link; link = link->next){
+ assoc = CAnimBlendAssociation::FromLink(link);
+ assoc->UpdateTimeStep(timeDelta, totalLength == 0.0f ? 1.0f : totalBlend/totalLength);
+ }
+
updateData.nodes[i] = nil;
-#ifdef PED_SKIN
- if(IsClumpSkinned(clump))
- clumpData->ForAllFrames(FrameUpdateCallBackSkinned, &updateData);
- else
-#endif
- clumpData->ForAllFrames(FrameUpdateCallBackNonSkinned, &updateData);
+ if(doRender){
+ if(clumpData->frames[0].flag & AnimBlendFrameData::UPDATE_KEYFRAMES)
+ RpAnimBlendNodeUpdateKeyframes(clumpData->frames, &updateData, clumpData->numFrames);
+ if(IsClumpSkinned(clump))
+ clumpData->ForAllFrames(FrameUpdateCallBackSkinned, &updateData);
+ else
+ clumpData->ForAllFrames(FrameUpdateCallBackNonSkinned, &updateData);
+ clumpData->frames[0].flag &= ~AnimBlendFrameData::UPDATE_KEYFRAMES;
+ }else{
+ clumpData->ForAllFrames(FrameUpdateCallBackOffscreen, &updateData);
+ clumpData->frames[0].flag |= AnimBlendFrameData::UPDATE_KEYFRAMES;
+ }
for(link = clumpData->link.next; link; link = link->next){
- CAnimBlendAssociation *assoc = CAnimBlendAssociation::FromLink(link);
- float relSpeed = totalLength == 0.0f ? 1.0f : totalBlend/totalLength;
- assoc->UpdateTime(timeDelta, relSpeed);
+ assoc = CAnimBlendAssociation::FromLink(link);
+ assoc->UpdateTime(timeDelta, totalLength == 0.0f ? 1.0f : totalBlend/totalLength);
}
RwFrameUpdateObjects(RpClumpGetFrame(clump));
}
diff --git a/src/animation/RpAnimBlend.h b/src/animation/RpAnimBlend.h
index 838c8816..d0f7a114 100644
--- a/src/animation/RpAnimBlend.h
+++ b/src/animation/RpAnimBlend.h
@@ -26,6 +26,7 @@ void RpAnimBlendClumpInit(RpClump *clump);
bool RpAnimBlendClumpIsInitialized(RpClump *clump);
void RpAnimBlendClumpFillFrameArray(RpClump* clump, AnimBlendFrameData** frames);
AnimBlendFrameData *RpAnimBlendClumpFindFrame(RpClump *clump, const char *name);
+AnimBlendFrameData *RpAnimBlendClumpFindBone(RpClump *clump, uint32 boneTag);
void FillFrameArrayCallBack(AnimBlendFrameData *frame, void *arg);
CAnimBlendAssociation *RpAnimBlendClumpGetAssociation(RpClump *clump, uint32 id);
CAnimBlendAssociation *RpAnimBlendClumpGetMainAssociation(RpClump *clump, CAnimBlendAssociation **assocRet, float *blendRet);
@@ -34,9 +35,11 @@ CAnimBlendAssociation *RpAnimBlendClumpGetMainAssociation_N(RpClump *clump, int
CAnimBlendAssociation *RpAnimBlendClumpGetMainPartialAssociation_N(RpClump *clump, int n);
CAnimBlendAssociation *RpAnimBlendClumpGetFirstAssociation(RpClump *clump, uint32 mask);
CAnimBlendAssociation *RpAnimBlendClumpGetFirstAssociation(RpClump *clump);
-void RpAnimBlendClumpUpdateAnimations(RpClump* clump, float timeDelta);
+void RpAnimBlendNodeUpdateKeyframes(AnimBlendFrameData *frames, AnimBlendFrameUpdateData *updateData, int32 numNodes);
+void RpAnimBlendClumpUpdateAnimations(RpClump* clump, float timeDelta, bool doRender = true);
extern CAnimBlendClumpData *gpAnimBlendClump;
void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg);