2019-06-11 06:59:28 +00:00
|
|
|
#include "common.h"
|
|
|
|
#include "patcher.h"
|
2019-10-29 23:12:58 +00:00
|
|
|
#include "General.h"
|
2019-06-11 06:59:28 +00:00
|
|
|
#include "ModelInfo.h"
|
|
|
|
#include "AnimManager.h"
|
|
|
|
#include "RpAnimBlend.h"
|
|
|
|
#include "AnimBlendAssociation.h"
|
|
|
|
#include "AnimBlendAssocGroup.h"
|
|
|
|
|
|
|
|
CAnimBlendAssocGroup::CAnimBlendAssocGroup(void)
|
|
|
|
{
|
|
|
|
assocList = nil;
|
|
|
|
numAssociations = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CAnimBlendAssocGroup::~CAnimBlendAssocGroup(void)
|
|
|
|
{
|
|
|
|
DestroyAssociations();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CAnimBlendAssocGroup::DestroyAssociations(void)
|
|
|
|
{
|
|
|
|
if(assocList){
|
|
|
|
delete[] assocList;
|
|
|
|
assocList = nil;
|
|
|
|
numAssociations = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CAnimBlendAssociation*
|
|
|
|
CAnimBlendAssocGroup::GetAnimation(uint32 id)
|
|
|
|
{
|
|
|
|
return &assocList[id];
|
|
|
|
}
|
|
|
|
|
|
|
|
CAnimBlendAssociation*
|
|
|
|
CAnimBlendAssocGroup::GetAnimation(const char *name)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < numAssociations; i++)
|
2019-10-29 23:12:58 +00:00
|
|
|
if(!CGeneral::faststricmp(assocList[i].hierarchy->name, name))
|
2019-06-11 06:59:28 +00:00
|
|
|
return &assocList[i];
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CAnimBlendAssociation*
|
|
|
|
CAnimBlendAssocGroup::CopyAnimation(uint32 id)
|
|
|
|
{
|
|
|
|
CAnimBlendAssociation *anim = GetAnimation(id);
|
|
|
|
if(anim == nil)
|
|
|
|
return nil;
|
|
|
|
CAnimManager::UncompressAnimation(anim->hierarchy);
|
|
|
|
return new CAnimBlendAssociation(*anim);
|
|
|
|
}
|
|
|
|
|
|
|
|
CAnimBlendAssociation*
|
|
|
|
CAnimBlendAssocGroup::CopyAnimation(const char *name)
|
|
|
|
{
|
|
|
|
CAnimBlendAssociation *anim = GetAnimation(name);
|
|
|
|
if(anim == nil)
|
|
|
|
return nil;
|
|
|
|
CAnimManager::UncompressAnimation(anim->hierarchy);
|
|
|
|
return new CAnimBlendAssociation(*anim);
|
|
|
|
}
|
|
|
|
|
2019-10-29 23:12:58 +00:00
|
|
|
bool
|
2019-06-11 06:59:28 +00:00
|
|
|
strcmpIgnoringDigits(const char *s1, const char *s2)
|
|
|
|
{
|
|
|
|
char c1, c2;
|
|
|
|
|
|
|
|
for(;;){
|
|
|
|
c1 = *s1;
|
|
|
|
c2 = *s2;
|
|
|
|
if(c1) s1++;
|
|
|
|
if(c2) s2++;
|
|
|
|
if(c1 == '\0' && c2 == '\0')
|
2019-10-29 23:12:58 +00:00
|
|
|
return true;
|
|
|
|
if(__ascii_iswdigit(c1) && __ascii_iswdigit(c2))
|
2019-06-11 06:59:28 +00:00
|
|
|
continue;
|
2019-10-29 23:12:58 +00:00
|
|
|
c1 = __ascii_toupper(c1);
|
|
|
|
c2 = __ascii_toupper(c2);
|
2019-06-11 06:59:28 +00:00
|
|
|
if(c1 != c2)
|
2019-10-29 23:12:58 +00:00
|
|
|
return false;
|
2019-06-11 06:59:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CBaseModelInfo*
|
|
|
|
GetModelFromName(const char *name)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
CBaseModelInfo *mi;
|
|
|
|
|
|
|
|
for(i = 0; i < MODELINFOSIZE; i++){
|
|
|
|
mi = CModelInfo::GetModelInfo(i);
|
2019-06-12 08:50:23 +00:00
|
|
|
if(mi && mi->GetRwObject() && RwObjectGetType(mi->GetRwObject()) == rpCLUMP &&
|
2019-06-11 06:59:28 +00:00
|
|
|
strcmpIgnoringDigits(mi->GetName(), name))
|
|
|
|
return mi;
|
|
|
|
}
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CAnimBlendAssocGroup::CreateAssociations(const char *name)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
CAnimBlock *animBlock;
|
|
|
|
|
|
|
|
if(assocList)
|
|
|
|
DestroyAssociations();
|
|
|
|
|
|
|
|
animBlock = CAnimManager::GetAnimationBlock(name);
|
|
|
|
assocList = new CAnimBlendAssociation[animBlock->numAnims];
|
|
|
|
numAssociations = 0;
|
|
|
|
|
|
|
|
for(i = 0; i < animBlock->numAnims; i++){
|
|
|
|
CAnimBlendHierarchy *anim = CAnimManager::GetAnimation(animBlock->firstIndex + i);
|
|
|
|
CBaseModelInfo *model = GetModelFromName(anim->name);
|
2019-07-20 12:39:38 +00:00
|
|
|
assert(model);
|
2019-06-11 06:59:28 +00:00
|
|
|
printf("Associated anim %s with model %s\n", anim->name, model->GetName());
|
2019-07-20 12:39:38 +00:00
|
|
|
RpClump *clump = (RpClump*)model->CreateInstance();
|
|
|
|
RpAnimBlendClumpInit(clump);
|
|
|
|
assocList[i].Init(clump, anim);
|
|
|
|
RpClumpDestroy(clump);
|
|
|
|
assocList[i].animId = i;
|
2019-06-11 06:59:28 +00:00
|
|
|
}
|
|
|
|
numAssociations = animBlock->numAnims;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create associations from hierarchies for a given clump
|
|
|
|
void
|
2019-08-16 18:17:15 +00:00
|
|
|
CAnimBlendAssocGroup::CreateAssociations(const char *blockName, RpClump *clump, const char **animNames, int numAssocs)
|
2019-06-11 06:59:28 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
CAnimBlock *animBlock;
|
|
|
|
|
|
|
|
if(assocList)
|
|
|
|
DestroyAssociations();
|
|
|
|
|
|
|
|
animBlock = CAnimManager::GetAnimationBlock(blockName);
|
2019-06-17 21:31:00 +00:00
|
|
|
assocList = new CAnimBlendAssociation[numAssocs];
|
2019-06-11 06:59:28 +00:00
|
|
|
|
|
|
|
numAssociations = 0;
|
|
|
|
for(i = 0; i < numAssocs; i++){
|
|
|
|
assocList[i].Init(clump, CAnimManager::GetAnimation(animNames[i], animBlock));
|
|
|
|
assocList[i].animId = i;
|
|
|
|
}
|
|
|
|
numAssociations = numAssocs;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
STARTPATCHES
|
2019-06-12 08:50:23 +00:00
|
|
|
InjectHook(0x4012D0, &CAnimBlendAssocGroup::DestroyAssociations, PATCH_JUMP);
|
2019-06-11 06:59:28 +00:00
|
|
|
InjectHook(0x4013D0, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(uint32))&CAnimBlendAssocGroup::GetAnimation, PATCH_JUMP);
|
|
|
|
InjectHook(0x401300, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(const char*))&CAnimBlendAssocGroup::GetAnimation, PATCH_JUMP);
|
|
|
|
InjectHook(0x401420, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(uint32))&CAnimBlendAssocGroup::CopyAnimation, PATCH_JUMP);
|
|
|
|
InjectHook(0x4013E0, (CAnimBlendAssociation *(CAnimBlendAssocGroup::*)(const char*))&CAnimBlendAssocGroup::CopyAnimation, PATCH_JUMP);
|
|
|
|
InjectHook(0x401130, (void (CAnimBlendAssocGroup::*)(const char*))&CAnimBlendAssocGroup::CreateAssociations, PATCH_JUMP);
|
2019-08-16 18:17:15 +00:00
|
|
|
InjectHook(0x401220, (void (CAnimBlendAssocGroup::*)(const char*, RpClump*, const char**, int))&CAnimBlendAssocGroup::CreateAssociations, PATCH_JUMP);
|
2019-06-11 06:59:28 +00:00
|
|
|
ENDPATCHES
|