#include "nw4r/lyt/lyt_animation.h" #include "nw4r/lyt/lyt_group.h" #include "nw4r/lyt/lyt_layout.h" #include "nw4r/lyt/lyt_pane.h" namespace nw4r { namespace lyt { namespace { // RIsSame__27@unnamed@lyt_animation_cpp@Ffff // RIsSame__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@Ffff bool RIsSame(f32 a, f32 b, f32 tolerance) { f32 c = a - b; return (-tolerance < c && c < tolerance); } // GetStepCurveValue__27@unnamed@lyt_animation_cpp@FfPCQ44nw4r3lyt3res7StepKeyUl // GetStepCurveValue__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FfPCQ44nw4r3lyt3res7StepKeyUl u16 GetStepCurveValue(f32 frame, const res::StepKey *keyArray, u32 keySize) { if (keySize == 1 || frame <= keyArray[0].frame) { return keyArray[0].value; } if (frame >= keyArray[keySize - 1].frame) { return keyArray[keySize - 1].value; } int ikeyL = 0; int ikeyR = keySize - 1; while (ikeyL != ikeyR - 1 && ikeyL != ikeyR) { int ikeyCenter = (ikeyL + ikeyR) / 2; const res::StepKey ¢erKey = keyArray[ikeyCenter]; if (frame < centerKey.frame) { ikeyR = ikeyCenter; } else { ikeyL = ikeyCenter; } } if (RIsSame(frame, keyArray[ikeyR].frame, 0.001f)) { return keyArray[ikeyR].value; } else { return keyArray[ikeyL].value; } } // GetHermiteCurveValue__27@unnamed@lyt_animation_cpp@FfPCQ44nw4r3lyt3res10HermiteKeyUl // GetHermiteCurveValue__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FfPCQ44nw4r3lyt3res10HermiteKeyUl f32 GetHermiteCurveValue(f32 frame, const res::HermiteKey *keyArray, u32 keySize) { if (keySize == 1 || frame <= keyArray[0].frame) { return keyArray[0].value; } if (frame >= keyArray[keySize - 1].frame) { return keyArray[keySize - 1].value; } int ikeyL = 0; int ikeyR = keySize - 1; while (ikeyL != ikeyR - 1 && ikeyL != ikeyR) { int ikeyCenter = (ikeyL + ikeyR) / 2; if (frame <= keyArray[ikeyCenter].frame) { ikeyR = ikeyCenter; } else { ikeyL = ikeyCenter; } } const res::HermiteKey &key0 = keyArray[ikeyL]; const res::HermiteKey &key1 = keyArray[ikeyR]; if (RIsSame(frame, key1.frame, 0.001f)) { if (ikeyR < keySize - 1 && key1.frame == keyArray[ikeyR + 1].frame) { return keyArray[ikeyR + 1].value; } else { return key1.value; } } f32 t1 = frame - key0.frame; f32 t2 = 1.0f / (key1.frame - key0.frame); f32 v0 = key0.value; f32 v1 = key1.value; f32 s0 = key0.slope; f32 s1 = key1.slope; f32 t1t1t2 = t1 * t1 * t2; f32 t1t1t2t2 = t1t1t2 * t2; f32 t1t1t1t2t2 = t1 * t1t1t2t2; f32 t1t1t1t2t2t2 = t1t1t1t2t2 * t2; return v0 * (2.0f * t1t1t1t2t2t2 - 3.0f * t1t1t2t2 + 1.0f) + v1 * (-2.0f * t1t1t1t2t2t2 + 3.0f * t1t1t2t2) + s0 * (t1 + (t1t1t1t2t2 - 2.0f * t1t1t2)) + s1 * (t1t1t1t2t2 - t1t1t2); } // AnimatePainSRT__27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt4PanePCQ44nw4r3lyt3res13AnimationInfoPCUlf // AnimatePaneSRT__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt4PanePCQ44nw4r3lyt3res13AnimationInfoPCUlf void AnimatePaneSRT(Pane *pPane, const res::AnimationInfo *pAnimInfo, const u32 *animTargetOffsets, f32 frame) { for (int i = 0; i < pAnimInfo->num; i++) { const res::AnimationTarget *pAnimTarget = detail::ConvertOffsToPtr(pAnimInfo, animTargetOffsets[i]); const res::HermiteKey *keys = detail::ConvertOffsToPtr(pAnimTarget, pAnimTarget->keyOffset); pPane->SetSRTElement(pAnimTarget->target, GetHermiteCurveValue(frame, keys, pAnimTarget->keyNum)); } } // AnimateVisibility__27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt4PanePCQ44nw4r3lyt3res13AnimationInfoPCUlf // AnimateVisibility__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt4PanePCQ44nw4r3lyt3res13AnimationInfoPCUlf void AnimateVisibility(Pane *pPane, const res::AnimationInfo *pAnimInfo, const u32 *animTargetOffsets, f32 frame) { for (int i = 0; i < pAnimInfo->num; i++) { const res::AnimationTarget *pAnimTarget = detail::ConvertOffsToPtr(pAnimInfo, animTargetOffsets[i]); const res::StepKey *keys = detail::ConvertOffsToPtr(pAnimTarget, pAnimTarget->keyOffset); pPane->SetVisible(GetStepCurveValue(frame, keys, pAnimTarget->keyNum) != 0); } } // AnimateVertexColor__27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt4PanePCQ44nw4r3lyt3res13AnimationInfoPCUlf // AnimateVertexColor__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt4PanePCQ44nw4r3lyt3res13AnimationInfoPCUlf void AnimateVertexColor(Pane *pPane, const res::AnimationInfo *pAnimInfo, const u32 *animTargetOffsets, f32 frame) { for (int i = 0; i < pAnimInfo->num; i++) { const res::AnimationTarget *pAnimTarget = detail::ConvertOffsToPtr(pAnimInfo, animTargetOffsets[i]); const res::HermiteKey *keys = detail::ConvertOffsToPtr(pAnimTarget, pAnimTarget->keyOffset); f32 value = GetHermiteCurveValue(frame, keys, pAnimTarget->keyNum); value += 0.5f; u8 u8Val; OSf32tou8(&value, &u8Val); pPane->SetColorElement(pAnimTarget->target, u8Val); } } // AnimateMaterialColor__27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt8MaterialPCQ44nw4r3lyt3res13AnimationInfoPCUlf // AnimateMaterialColor__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt8MaterialPCQ44nw4r3lyt3res13AnimationInfoPCUlf void AnimateMaterialColor( Material *pMaterial, const res::AnimationInfo *pAnimInfo, const u32 *animTargetOffsets, f32 frame ) { for (int i = 0; i < pAnimInfo->num; i++) { const res::AnimationTarget *pAnimTarget = detail::ConvertOffsToPtr(pAnimInfo, animTargetOffsets[i]); const res::HermiteKey *keys = detail::ConvertOffsToPtr(pAnimTarget, pAnimTarget->keyOffset); f32 value = GetHermiteCurveValue(frame, keys, pAnimTarget->keyNum); value += 0.5f; s16 s16Val; OSf32tos16(&value, &s16Val); s16Val = ut::Min(ut::Max(s16Val, -0x400), 1023); pMaterial->SetColorElement(pAnimTarget->target, s16Val); } } // AnimateTextureSRT__27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt8MaterialPCQ44nw4r3lyt3res13AnimationInfoPCUlf // AnimateTextureSRT__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt8MaterialPCQ44nw4r3lyt3res13AnimationInfoPCUlf void AnimateTextureSRT( Material *pMaterial, const res::AnimationInfo *pAnimInfo, const u32 *animTargetOffsets, f32 frame ) { for (int i = 0; i < pAnimInfo->num; i++) { const res::AnimationTarget *pAnimTarget = detail::ConvertOffsToPtr(pAnimInfo, animTargetOffsets[i]); if (pAnimTarget->id < pMaterial->GetTexSRTCap()) { const res::HermiteKey *keys = detail::ConvertOffsToPtr(pAnimTarget, pAnimTarget->keyOffset); pMaterial->SetTexSRTElement( pAnimTarget->id, pAnimTarget->target, GetHermiteCurveValue(frame, keys, pAnimTarget->keyNum) ); } } } // AnimateTexturePattern__27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt8MaterialPCQ44nw4r3lyt3res13AnimationInfoPCUlfPPv // AnimateTexturePattern__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt8MaterialPCQ44nw4r3lyt3res13AnimationInfoPCUlfPPv void AnimateTexturePattern( Material *pMaterial, const res::AnimationInfo *pAnimInfo, const u32 *animTargetOffsets, f32 frame, void **tpls ) { for (int i = 0; i < pAnimInfo->num; i++) { const res::AnimationTarget *pAnimTarget = detail::ConvertOffsToPtr(pAnimInfo, animTargetOffsets[i]); if (pAnimTarget->id < pMaterial->GetTextureNum()) { const res::StepKey *keys = detail::ConvertOffsToPtr(pAnimTarget, pAnimTarget->keyOffset); u16 fileIdx = GetStepCurveValue(frame, keys, pAnimTarget->keyNum); if (tpls[fileIdx] != nullptr) { pMaterial->GetTexturePtr(pAnimTarget->id)->ReplaceImage((TPLPalette *)tpls[fileIdx], 0); } } } } // AnimateIndTexSRT__27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt8MaterialPCQ44nw4r3lyt3res13AnimationInfoPCUlf // AnimateIndTexSRT__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt8MaterialPCQ44nw4r3lyt3res13AnimationInfoPCUlf void AnimateIndTexSRT( Material *pMaterial, const res::AnimationInfo *pAnimInfo, const u32 *animTargetOffsets, f32 frame ) { for (int i = 0; i < pAnimInfo->num; i++) { const res::AnimationTarget *pAnimTarget = detail::ConvertOffsToPtr(pAnimInfo, animTargetOffsets[i]); if (pAnimTarget->id < pMaterial->GetIndTexSRTCap()) { const res::HermiteKey *keys = detail::ConvertOffsToPtr(pAnimTarget, pAnimTarget->keyOffset); pMaterial->SetIndTexSRTElement( pAnimTarget->id, pAnimTarget->target, GetHermiteCurveValue(frame, keys, pAnimTarget->keyNum) ); } } } // IsBindAnimation__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt8MaterialPQ34nw4r3lyt13AnimTransform bool IsBindAnimation(Material *pMaterial, AnimTransform *pAnimTrans) { return false; // Early return in release builds, no call to FindAnimationLink in SS, exists in tfp2 if (pMaterial->FindAnimationLink(pAnimTrans)) { return true; } return false; } // IsBindAnimation__Q34nw4r3lyt27@unnamed@lyt_animation_cpp@FPQ34nw4r3lyt4PanePQ34nw4r3lyt13AnimTransform bool IsBindAnimation(Pane *pPane, AnimTransform *pAnimTrans) { return false; // Early return in release builds, no call to FindAnimationLink in SS, exists in tfp2 if (pPane->FindAnimationLinkSelf(pAnimTrans)) { return true; } return false; } } // namespace // __ct__Q34nw4r3lyt13AnimTransformFv AnimTransform::AnimTransform() : mLink(), mpRes(NULL), mFrame(0.0f) {} // __dt__Q34nw4r3lyt13AnimTransformFv AnimTransform::~AnimTransform() {} // GetFrameSize__Q34nw4r3lyt13AnimTransformCFv u16 AnimTransform::GetFrameSize() const { return mpRes->frameSize; } // IsLoopData__Q34nw4r3lyt13AnimTransformCFv bool AnimTransform::IsLoopData() const { return mpRes->loop; } // __ct__Q34nw4r3lyt18AnimTransformBasicFv AnimTransformBasic::AnimTransformBasic() : mpFileResAry(nullptr), mAnimLinkAry(nullptr), mAnimLinkNum(0) {} // __dt__Q34nw4r3lyt18AnimTransformBasicFv AnimTransformBasic::~AnimTransformBasic() { Layout::DeletePrimArray(mAnimLinkAry); Layout::DeletePrimArray(mpFileResAry); } // SetResource__Q34nw4r3lyt18AnimTransformBasicFPCQ44nw4r3lyt3res14AnimationBlockPQ34nw4r3lyt16ResourceAccessor void AnimTransformBasic::SetResource(const res::AnimationBlock *pRes, ResourceAccessor *pResAccessor) { SetResource(pRes, pResAccessor, pRes->animContNum); } // SetResource__Q34nw4r3lyt18AnimTransformBasicFPCQ44nw4r3lyt3res14AnimationBlockPQ34nw4r3lyt16ResourceAccessorUs void AnimTransformBasic::SetResource(const res::AnimationBlock *pRes, ResourceAccessor *pResAccessor, u16 animNum) { mpRes = pRes; mpFileResAry = nullptr; if (mpRes->fileNum != 0) { mpFileResAry = Layout::NewArray(mpRes->fileNum); if (mpFileResAry) { const u32 *fileNameOffsets = detail::ConvertOffsToPtr(mpRes, sizeof(*mpRes)); for (int i = 0; i < mpRes->fileNum; i++) { const char *fileName = detail::GetStrTableStr(fileNameOffsets, i); mpFileResAry[i] = pResAccessor->GetResource('timg', fileName, nullptr); } } } mAnimLinkAry = Layout::NewArray(animNum); if (mAnimLinkAry) { mAnimLinkNum = animNum; } } // Bind__Q34nw4r3lyt18AnimTransformBasicFPQ34nw4r3lyt4Paneb // Bind__Q34nw4r3lyt18AnimTransformBasicFPQ34nw4r3lyt4Panebb void AnimTransformBasic::Bind(Pane *pPane, bool bRecursive, bool bDisable) { AnimationLink *pCrAnimLink = nullptr; const u32 *animContOffsets = detail::ConvertOffsToPtr(mpRes, mpRes->animContOffsetsOffset); for (u16 i = 0; i < mpRes->animContNum; i++) { const res::AnimationContent &animCont = *detail::ConvertOffsToPtr(mpRes, animContOffsets[i]); if (animCont.type == 0) { Pane *pFindPane = pPane->FindPaneByName(animCont.name, bRecursive); if (pFindPane && !IsBindAnimation(pFindPane, this)) { pCrAnimLink = Bind(pFindPane, pCrAnimLink, i, bDisable); if (pCrAnimLink == nullptr) { break; } } } else { Material *pFindMat = pPane->FindMaterialByName(animCont.name, bRecursive); if (pFindMat && !IsBindAnimation(pFindMat, this)) { pCrAnimLink = Bind(pFindMat, pCrAnimLink, i, bDisable); if (pCrAnimLink == nullptr) { break; } } } } } // Bind__Q34nw4r3lyt18AnimTransformBasicFPQ34nw4r3lyt8Material // Bind__Q34nw4r3lyt18AnimTransformBasicFPQ34nw4r3lyt8Materialb void AnimTransformBasic::Bind(Material *pMaterial, bool bDisable) { AnimationLink *pCrAnimLink = nullptr; const u32 *animContOffsets = detail::ConvertOffsToPtr(mpRes, mpRes->animContOffsetsOffset); for (u16 i = 0; i < mpRes->animContNum; i++) { const res::AnimationContent &animCont = *detail::ConvertOffsToPtr(mpRes, animContOffsets[i]); if (animCont.type == 1) { if (detail::EqualsMaterialName(pMaterial->GetName(), animCont.name) && !IsBindAnimation(pMaterial, this)) { pCrAnimLink = Bind(pMaterial, pCrAnimLink, i, bDisable); if (pCrAnimLink == nullptr) { break; } } } } } // Animate__Q34nw4r3lyt18AnimTransformBasicFUlPQ34nw4r3lyt4Pane void AnimTransformBasic::Animate(u32 idx, Pane *pPane) { u32 animContOffsets = detail::ConvertOffsToPtr(mpRes, mpRes->animContOffsetsOffset)[idx]; const res::AnimationContent *pAnimCont = detail::ConvertOffsToPtr(mpRes, animContOffsets); const u32 *animInfoOffsets = detail::ConvertOffsToPtr(pAnimCont, sizeof(res::AnimationContent)); for (int i = 0; i < pAnimCont->num; i++) { const res::AnimationInfo *pAnimInfo = detail::ConvertOffsToPtr(pAnimCont, animInfoOffsets[i]); const u32 *animTargetOffsets = detail::ConvertOffsToPtr(pAnimInfo, sizeof(res::AnimationInfo)); switch (pAnimInfo->kind) { case 'RLPA': AnimatePaneSRT(pPane, pAnimInfo, animTargetOffsets, mFrame); break; case 'RLVI': AnimateVisibility(pPane, pAnimInfo, animTargetOffsets, mFrame); break; case 'RLVC': AnimateVertexColor(pPane, pAnimInfo, animTargetOffsets, mFrame); break; } } } // Animate__Q34nw4r3lyt18AnimTransformBasicFUlPQ34nw4r3lyt8Material void AnimTransformBasic::Animate(u32 idx, Material *pMaterial) { u32 animContOffsets = detail::ConvertOffsToPtr(mpRes, mpRes->animContOffsetsOffset)[idx]; const res::AnimationContent *pAnimCont = detail::ConvertOffsToPtr(mpRes, animContOffsets); const u32 *animInfoOffsets = detail::ConvertOffsToPtr(pAnimCont, sizeof(res::AnimationContent)); for (int i = 0; i < pAnimCont->num; i++) { const res::AnimationInfo *pAnimInfo = detail::ConvertOffsToPtr(pAnimCont, animInfoOffsets[i]); const u32 *animTargetOffsets = detail::ConvertOffsToPtr(pAnimInfo, sizeof(res::AnimationInfo)); switch (pAnimInfo->kind) { case 'RLMC': AnimateMaterialColor(pMaterial, pAnimInfo, animTargetOffsets, mFrame); break; case 'RLTS': AnimateTextureSRT(pMaterial, pAnimInfo, animTargetOffsets, mFrame); break; case 'RLTP': if (mpFileResAry) { AnimateTexturePattern(pMaterial, pAnimInfo, animTargetOffsets, mFrame, mpFileResAry); } break; case 'RLIM': AnimateIndTexSRT(pMaterial, pAnimInfo, animTargetOffsets, mFrame); break; } } } // FindUnbindLink__Q34nw4r3lyt18AnimTransformBasicCFPQ34nw4r3lyt13AnimationLink AnimationLink *AnimTransformBasic::FindUnbindLink(AnimationLink *pLink) const { if (pLink == nullptr) { pLink = mAnimLinkAry; } while (pLink < &mAnimLinkAry[mAnimLinkNum]) { if (pLink->GetAnimTransform() == nullptr) { return pLink; } pLink++; } return nullptr; } // Bind__Q34nw4r3lyt18AnimTransformBasicFPQ34nw4r3lyt4PanePQ34nw4r3lyt13AnimationLinkUsb_PQ34nw4r3lyt13AnimationLink // Bind__Q34nw4r3lyt18AnimTransformBasicFPQ34nw4r3lyt8MaterialPQ34nw4r3lyt13AnimationLinkUsb_PQ34nw4r3lyt13AnimationLink template AnimationLink *AnimTransformBasic::Bind(T *pTarget, AnimationLink *pAnimLink, u16 idx, bool bDisable) { pAnimLink = FindUnbindLink(pAnimLink); if (!pAnimLink) { return nullptr; } pAnimLink->Set(this, idx, bDisable); pTarget->AddAnimationLink(pAnimLink); pAnimLink++; return pAnimLink; } // __ct__Q34nw4r3lyt12AnimResourceFv AnimResource::AnimResource() { Init(); } // Set__Q34nw4r3lyt12AnimResourceFPCv void AnimResource::Set(const void *animResBuf) { Init(); const res::BinaryFileHeader *pFileHeader = (res::BinaryFileHeader *)animResBuf; if (detail::TestFileHeader(*pFileHeader, 'RLAN')) { if (detail::TestFileVersion(*pFileHeader)) { mpFileHeader = pFileHeader; const res::DataBlockHeader *pDataBlockHead = detail::ConvertOffsToPtr(mpFileHeader, mpFileHeader->headerSize); for (int i = 0; i < mpFileHeader->dataBlocks; i++) { switch (detail::GetSignatureInt(pDataBlockHead->kind)) { case 'pat1': mpTagBlock = (res::AnimationTagBlock *)pDataBlockHead; break; case 'pah1': mpShareBlock = (res::AnimationShareBlock *)pDataBlockHead; break; case 'pai1': mpResBlock = (res::AnimationBlock *)pDataBlockHead; break; } pDataBlockHead = detail::ConvertOffsToPtr(pDataBlockHead, pDataBlockHead->size); } } } } // Init__Q34nw4r3lyt12AnimResourceFv void AnimResource::Init() { mpFileHeader = nullptr; mpResBlock = nullptr; mpTagBlock = nullptr; mpShareBlock = nullptr; } // GetGroupNum__Q34nw4r3lyt12AnimResourceCFv u16 AnimResource::GetGroupNum() const { if (mpTagBlock) { return mpTagBlock->groupNum; } return 0; } // GetGroupArray__Q34nw4r3lyt12AnimResourceCFv const AnimationGroupRef *AnimResource::GetGroupArray() const { if (mpTagBlock) { const AnimationGroupRef *groups = detail::ConvertOffsToPtr(mpTagBlock, mpTagBlock->groupsOffset); return groups; } return nullptr; } // IsDescendingBind__Q34nw4r3lyt12AnimResourceCFv bool AnimResource::IsDescendingBind() const { if (mpTagBlock) { return detail::TestBit(mpTagBlock->flag, 0); } return false; } // GetAnimationShareInfoNum__Q34nw4r3lyt12AnimResourceCFv u16 AnimResource::GetAnimationShareInfoNum() const { if (mpShareBlock) { return mpShareBlock->shareNum; } return 0; } // GetAnimationShareInfoArray__Q34nw4r3lyt12AnimResourceCFv const AnimationShareInfo *AnimResource::GetAnimationShareInfoArray() const { if (mpShareBlock) { return detail::ConvertOffsToPtr(mpShareBlock, mpShareBlock->animShareInfoOffset); } return 0; } // CalcAnimationNum__Q34nw4r3lyt12AnimResourceCFPQ34nw4r3lyt4Paneb u16 AnimResource::CalcAnimationNum(Pane *pPane, bool bRecursive) const { u16 linkNum = 0; const u32 *animContOffsets = detail::ConvertOffsToPtr(mpResBlock, mpResBlock->animContOffsetsOffset); for (u16 i = 0; i < mpResBlock->animContNum; i++) { const res::AnimationContent &animCont = *detail::ConvertOffsToPtr(mpResBlock, animContOffsets[i]); if (animCont.type == 0) { Pane *pFindPane = pPane->FindPaneByName(animCont.name, bRecursive); if (pFindPane) { linkNum++; } } else { Material *pFindMat = pPane->FindMaterialByName(animCont.name, bRecursive); if (pFindMat) { linkNum++; } } } return linkNum; } // CalcAnimationNum__Q34nw4r3lyt12AnimResourceCFPQ34nw4r3lyt5Groupb u16 AnimResource::CalcAnimationNum(Group *pGroup, bool bRecursive) const { u16 linkNum = 0; ut::LinkList *paneList = pGroup->GetPaneList(); for (ut::LinkList::Iterator it = paneList->GetBeginIter(); it != paneList->GetEndIter(); it++) { linkNum += CalcAnimationNum(it->mTarget, bRecursive); } return linkNum; } namespace detail { // FindAnimContent__Q44nw4r3lyt6detail12AnimPaneTreeFPCQ44nw4r3lyt3res14AnimationBlockPCcUc u16 AnimPaneTree::FindAnimContent(const res::AnimationBlock *pAnimBlock, const char *animContName, u8 animContType) { const u32 *animContOffsets = detail::ConvertOffsToPtr(pAnimBlock, pAnimBlock->animContOffsetsOffset); for (u16 i = 0; i < pAnimBlock->animContNum; i++) { const res::AnimationContent *pAnimCont = detail::ConvertOffsToPtr(pAnimBlock, animContOffsets[i]); if (pAnimCont->type == animContType && EqualsMaterialName(pAnimCont->name, animContName)) { return i; } } return -1; } // Init__Q44nw4r3lyt6detail12AnimPaneTreeFv void AnimPaneTree::Init() { mLinkNum = 0; mAnimPaneIdx = 0; mAnimMatCnt = 0; for (u8 i = 0; i < 9; i++) { mAnimMatIdx[i] = 0; } } // Set__Q44nw4r3lyt6detail12AnimPaneTreeFPQ34nw4r3lyt4PaneRCQ34nw4r3lyt12AnimResource void AnimPaneTree::Set(Pane *pTargetPane, const AnimResource &animRes) { u16 linkNum = 0; const res::AnimationBlock *pAnimBlock = animRes.GetResourceBlock(); u16 animContIdx = FindAnimContent(pAnimBlock, pTargetPane->GetName(), 0); if (animContIdx != 0xFFFF) { linkNum++; } u8 animMatCnt = pTargetPane->GetMaterialNum(); u16 animMatIdxs[9]; for (u8 i = 0; i < animMatCnt; i++) { animMatIdxs[i] = FindAnimContent(pAnimBlock, pTargetPane->GetMaterial(i)->GetName(), 1); if (animMatIdxs[i] != 0xFFFF) { linkNum++; } } if (linkNum != 0) { mAnimRes = animRes; mAnimPaneIdx = animContIdx; mAnimMatCnt = animMatCnt; for (u8 i = 0; i < animMatCnt; i++) { mAnimMatIdx[i] = animMatIdxs[i]; } mLinkNum = linkNum; } } // Bind__Q44nw4r3lyt6detail12AnimPaneTreeCFPQ34nw4r3lyt6LayoutPQ34nw4r3lyt4PanePQ34nw4r3lyt16ResourceAccessor AnimTransform *AnimPaneTree::Bind(Layout *pLayout, Pane *pTargetPane, ResourceAccessor *pResAccessor) const { AnimTransformBasic *pAnimTrans = (AnimTransformBasic *)pLayout->CreateAnimTransform(); pAnimTrans->SetResource(mAnimRes.GetResourceBlock(), pResAccessor, mLinkNum); AnimationLink *pCrAnimLink = nullptr; if (mAnimPaneIdx != 0xFFFF) { pCrAnimLink = pAnimTrans->Bind(pTargetPane, nullptr, mAnimPaneIdx, true); } u8 animMatMax = ut::Min(mAnimMatCnt, pTargetPane->GetMaterialNum()); for (u8 i = 0; i < animMatMax; i++) { if (mAnimMatIdx[i] != 0xFFFF) { Material *pMaterial = pTargetPane->GetMaterial(i); pCrAnimLink = pAnimTrans->Bind(pMaterial, pCrAnimLink, mAnimMatIdx[i], true); } } return pAnimTrans; } // FindAnimationLink__Q34nw4r3lyt6detailFPQ34nw4r2ut38LinkListPQ34nw4r3lyt13AnimTransform AnimationLink *FindAnimationLink(ut::LinkList *pAnimList, AnimTransform *pAnimTrans) { for (ut::LinkList::Iterator it = pAnimList->GetBeginIter(); it != pAnimList->GetEndIter(); it++) { if (pAnimTrans == it->GetAnimTransform()) { return &*it; } } return nullptr; } // FindAnimationLink__Q34nw4r3lyt6detailFPQ34nw4r2ut38LinkListRCQ34nw4r3lyt12AnimResource AnimationLink *FindAnimationLink(ut::LinkList *pAnimList, const AnimResource &animRes) { for (ut::LinkList::Iterator it = pAnimList->GetBeginIter(); it != pAnimList->GetEndIter(); it++) { if (animRes.GetResourceBlock() == it->GetAnimTransform()->GetAnimResource()) { return &*it; } } return nullptr; } // UnbindAnimationLink__Q34nw4r3lyt6detailFPQ34nw4r2ut38LinkListPQ34nw4r3lyt13AnimTransform void UnbindAnimationLink(ut::LinkList *pAnimList, AnimTransform *pAnimTrans) { ut::LinkList::Iterator it = pAnimList->GetBeginIter(); while (it != pAnimList->GetEndIter()) { ut::LinkList::Iterator currIt = it++; if (pAnimTrans == nullptr || currIt->GetAnimTransform() == pAnimTrans) { pAnimList->Erase(currIt); currIt->Reset(); } } } // Guess, Unused // UnbindAnimationLink__Q34nw4r3lyt6detailFPQ34nw4r2ut38LinkListRCQ34nw4r3lyt12AnimResource void UnbindAnimationLink(ut::LinkList *pAnimList, const AnimResource &animRes) { ut::LinkList::Iterator it = pAnimList->GetBeginIter(); while (it != pAnimList->GetEndIter()) { ut::LinkList::Iterator currIt = it++; if (currIt->GetAnimTransform()->GetAnimResource() == animRes.GetResourceBlock()) { pAnimList->Erase(currIt); currIt->Reset(); } } } } // namespace detail } // namespace lyt } // namespace nw4r