diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 2f635c49..829dfb90 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26115,7 +26115,7 @@ MultipleAlpha__Q34nw4r3lyt6detailFQ34nw4r2ut5ColorUc = .text:0x80492B20; // type SetVertexFormat__Q34nw4r3lyt6detailFbUc = .text:0x80492B60; // type:function size:0xE4 DrawQuad__Q34nw4r3lyt6detailFRCQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeUcPA4_CQ34nw4r4math4VEC2PCQ34nw4r2ut5Color = .text:0x80492C50; // type:function size:0x560 DrawQuad__Q34nw4r3lyt6detailFRCQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeUcPA4_CQ34nw4r4math4VEC2PCQ34nw4r2ut5ColorUc = .text:0x804931B0; // type:function size:0x130 -FUN_804932e0 = .text:0x804932E0; // type:function size:0x70 +BindAnimation__Q24nw4r3lytFPQ34nw4r3lyt5GroupPQ34nw4r3lyt13AnimTransformbb = .text:0x804932E0; // type:function size:0x70 FUN_80493350 = .text:0x80493350; // type:function size:0x78 FUN_804933d0 = .text:0x804933D0; // type:function size:0x70 FUN_80493440 = .text:0x80493440; // type:function size:0xCC diff --git a/configure.py b/configure.py index cc6aa06d..f8306211 100644 --- a/configure.py +++ b/configure.py @@ -355,7 +355,7 @@ config.libs = [ Object(Matching, "nw4r/lyt/lyt_init.cpp"), Object(Matching, "nw4r/lyt/lyt_pane.cpp"), Object(Matching, "nw4r/lyt/lyt_group.cpp"), - Object(NonMatching, "nw4r/lyt/lyt_layout.cpp"), + Object(Matching, "nw4r/lyt/lyt_layout.cpp"), Object(Matching, "nw4r/lyt/lyt_resourceAccessor.cpp"), Object(Matching, "nw4r/lyt/lyt_arcResourceAccessor.cpp"), Object(Matching, "nw4r/lyt/lyt_common.cpp"), diff --git a/include/nw4r/lyt/lyt_animation.h b/include/nw4r/lyt/lyt_animation.h index 90ee30c0..dbb5af4a 100644 --- a/include/nw4r/lyt/lyt_animation.h +++ b/include/nw4r/lyt/lyt_animation.h @@ -39,11 +39,55 @@ struct AnimationShareBlock { }; } // namespace res -struct AnimResource { - AnimResource(const void *anmResBuf) { - // TODO +struct AnimationShareInfo { + const char *GetTargetGroupName() const { + return targetGroupName; + } + const char *GetSrcPaneName() const { + return srcPaneName; } + char srcPaneName[17]; // at 0x00 + char targetGroupName[17]; // at 0x11 + u8 padding[2]; // at 0x12 +}; +struct AnimationGroupRef { + const char *GetName() const { + return name; + } + + char name[17]; // at 0x00 + u8 flag; // at 0x11 + u8 padding[2]; // at 0x12 +}; + +class AnimResource { +public: + AnimResource(); + AnimResource(const void *anmResBuf) { + Set(anmResBuf); + } + void Set(const void *anmResBuf); + void Init(); + u16 GetGroupNum() const; + const AnimationGroupRef *GetGroupArray() const; + bool IsDescendingBind() const; + u16 GetAnimationShareInfoNum() const; + AnimationShareInfo *GetAnimationShareInfoArray() const; + u16 CalcAnimationNum(Pane *pPane, bool bRecursive) const; + u16 CalcAnimationNum(Group *pGroup, bool bRecursive) const; + + const res::AnimationBlock *GetResourceBlock() const { + return mpResBlock; + } + const res::AnimationTagBlock *GetTagBlock() const { + return mpTagBlock; + } + const res::AnimationShareBlock *GetShareBlock() const { + return mpShareBlock; + } + +private: const res::BinaryFileHeader *mpFileHeader; // at 0x00 const res::AnimationBlock *mpResBlock; // at 0x04 const res::AnimationTagBlock *mpTagBlock; // at 0x08 @@ -51,29 +95,32 @@ struct AnimResource { }; namespace detail { -struct AnimPaneTree { - AnimPaneTree(Pane *pTargetPane, const AnimResource &animRes) : mAnimRes(animRes) { - // TODO - } - - bool IsEnabled() const { - // TODO - return false; +class AnimPaneTree { +public: + AnimPaneTree(Pane *pTargetPane, const AnimResource &animRes) : mAnimRes() { + Init(); + Set(pTargetPane, animRes); + } + bool IsEnabled() const; + static u16 FindAnimContent(const res::AnimationBlock *pAnimBlock, const char *animContName, u8 animContType); + void Init(); + void Set(Pane *pTargetPane, const AnimResource &animRes); + AnimTransform *Bind(Layout *pLayout, Pane *pTargetPane, ResourceAccessor *pResAccessor) const; + + // Inline Names Guess + u16 GetLinkNum() const { + return mLinkNum; } +private: AnimResource mAnimRes; // at 0x00 u16 mAnimPaneIdx; // at 0x10 u16 mLinkNum; // at 0x12 u16 mAnimMatIdx[9]; // at 0x14 u8 mAnimMatCnt; // at 0x26 }; -} // namespace detail -struct AnimationGroupRef { - char name[17]; // at 0x00 - u8 flag; // at 0x11 - u8 padding[2]; // at 0x12 -}; +} // namespace detail struct AnimTransform { inline AnimTransform() : mLink(), mpRes(NULL), mFrame(0.0f) {} @@ -112,7 +159,8 @@ struct AnimationLink { u16 mIdx; // at 0xC bool mbDisable; // at 0xE }; -struct AnimTransformBasic : AnimTransform { +class AnimTransformBasic : public AnimTransform { +public: AnimTransformBasic(); virtual ~AnimTransformBasic(); // at 0x08 virtual void SetResource(const res::AnimationBlock *pRes, ResourceAccessor *pResAccessor); // at 0x0C @@ -122,6 +170,7 @@ struct AnimTransformBasic : AnimTransform { virtual void Animate(u32 idx, Pane *pPane); // at 0x1C virtual void Animate(u32 idx, Material *pMaterial); // at 0x20 +private: void *mpFileResAry; // at 0x14 AnimationLink *mAnimLinkAry; // at 0x18 u16 mAnimLinkNum; // at 0x1C diff --git a/include/nw4r/lyt/lyt_common.h b/include/nw4r/lyt/lyt_common.h index c84d0065..f546e652 100644 --- a/include/nw4r/lyt/lyt_common.h +++ b/include/nw4r/lyt/lyt_common.h @@ -54,10 +54,10 @@ void DrawQuad(const math::VEC2 &, const Size &, u8, const TexCoordData *, const void DrawQuad(const math::VEC2 &, const Size &, u8, const TexCoordData *, const ut::Color *, u8); void DrawLine(const math::VEC2 &pos, const Size &size, ut::Color color); -s32 GetSignatureInt(const char *sig) { +inline s32 GetSignatureInt(const char *sig) { return *((s32 *)sig); } -bool TestFileVersion(const res::BinaryFileHeader &fileHeader) { +inline bool TestFileVersion(const res::BinaryFileHeader &fileHeader) { u32 majorVer = (fileHeader.version >> 8) & 0xFF; u32 minorVer = fileHeader.version & 0xFF; bool ret = majorVer == 0 && (minorVer > 7 && minorVer <= 10); diff --git a/include/nw4r/lyt/lyt_layout.h b/include/nw4r/lyt/lyt_layout.h index 39714af4..ebe0f6c7 100644 --- a/include/nw4r/lyt/lyt_layout.h +++ b/include/nw4r/lyt/lyt_layout.h @@ -40,6 +40,13 @@ public: virtual void Animate(u32 option); // at 0x38 virtual void SetTagProcessor(ut::TagProcessorBase *pTagProcessor); // at 0x3C +private: + ut::LinkList mAnimTransList; // at 0x04 + Pane *mpRootPane; // at 0x10 + GroupContainer *mpGroupContainer; // at 0x14 + Size mLayoutSize; // at 0x18 + +public: // STATICS static void FreeMemory(void *p) { MEMFreeToAllocator(mspAllocator, p); @@ -109,12 +116,6 @@ public: } } -private: - ut::LinkList mAnimTransList; // at 0x04 - Pane *mpRootPane; // at 0x10 - GroupContainer *mpGroupContainer; // at 0x14 - Size mLayoutSize; // at 0x18 - static MEMAllocator *mspAllocator; }; } // namespace lyt diff --git a/include/nw4r/lyt/lyt_types.h b/include/nw4r/lyt/lyt_types.h index 97e5890d..3cd60079 100644 --- a/include/nw4r/lyt/lyt_types.h +++ b/include/nw4r/lyt/lyt_types.h @@ -50,15 +50,6 @@ struct StepKey {}; } // namespace res -struct AnimationShareInfo { - const char *GetSrcPaneName() const { - return srcPaneName; - } - - char srcPaneName[17]; // at 0x00 - char targetGroupName[17]; // at 0x11 - u8 padding[2]; // at 0x12 -}; namespace detail { template inline bool TestBit(T bits, int index) { @@ -66,7 +57,7 @@ inline bool TestBit(T bits, int index) { return bits & mask; } template -inline bool SetBit(T *bits, int pos, bool val) { +inline void SetBit(T *bits, int pos, bool val) { T mask = T(1 << pos); *bits = T((*bits & ~mask)) | (val << pos); } diff --git a/include/nw4r/lyt/lyt_utils.h b/include/nw4r/lyt/lyt_utils.h new file mode 100644 index 00000000..3c5a72fd --- /dev/null +++ b/include/nw4r/lyt/lyt_utils.h @@ -0,0 +1,16 @@ +#ifndef NW4R_LYT_UTIL_H +#define NW4R_LYT_UTIL_H + +#include +#include + +namespace nw4r { +namespace lyt { + +void BindAnimation(Group *pGroup, AnimTransform *pAnimTrans, bool bRecursive, bool bDisable); + +} // namespace lyt + +} // namespace nw4r + +#endif diff --git a/src/nw4r/lyt/lyt_layout.cpp b/src/nw4r/lyt/lyt_layout.cpp index 75f8a4ee..11573c27 100644 --- a/src/nw4r/lyt/lyt_layout.cpp +++ b/src/nw4r/lyt/lyt_layout.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -161,47 +162,148 @@ bool Layout::Build(const void *lytResBuf, ResourceAccessor *pResAcsr) { // CreateAnimTransform__Q34nw4r3lyt6LayoutFv AnimTransform *Layout::CreateAnimTransform() { - return nullptr; + AnimTransform *pAnimTrans = NewObj(); + if (pAnimTrans) { + mAnimTransList.PushBack(pAnimTrans); + } + return pAnimTrans; } // CreateAnimTransform__Q34nw4r3lyt6LayoutFPCvPQ34nw4r3lyt16ResourceAccessor AnimTransform *Layout::CreateAnimTransform(const void *animResBuf, ResourceAccessor *pResAcsr) { - return nullptr; + return CreateAnimTransform(AnimResource(animResBuf), pResAcsr); } // CreateAnimTransform__Q34nw4r3lyt6LayoutFRCQ34nw4r3lyt12AnimResourcePQ34nw4r3lyt16ResourceAccessor AnimTransform *Layout::CreateAnimTransform(const AnimResource &animRes, ResourceAccessor *pResAcsr) { - return nullptr; + const res::AnimationBlock *pAnimBlock = animRes.GetResourceBlock(); + if (!pAnimBlock) { + return nullptr; + } + + AnimTransform *pAnimTrans = CreateAnimTransform(); + if (pAnimTrans) { + pAnimTrans->SetResource(pAnimBlock, pResAcsr); + } + + return pAnimTrans; } // BindAnimation__Q34nw4r3lyt6LayoutFPQ34nw4r3lyt13AnimTransform -void Layout::BindAnimation(AnimTransform *pAnimTrans) {} +void Layout::BindAnimation(AnimTransform *pAnimTrans) { + if (!mpRootPane) { + return; + } + mpRootPane->BindAnimation(pAnimTrans, true, false); +} // UnbindAnimation__Q34nw4r3lyt6LayoutFPQ34nw4r3lyt13AnimTransform -void Layout::UnbindAnimation(AnimTransform *pAnimTrans) {} +void Layout::UnbindAnimation(AnimTransform *pAnimTrans) { + if (!mpRootPane) { + return; + } + mpRootPane->UnbindAnimation(pAnimTrans, true); +} // UnbindAllAnimation__Q34nw4r3lyt6LayoutFv -void Layout::UnbindAllAnimation() {} +void Layout::UnbindAllAnimation() { + UnbindAnimation(nullptr); +} // BindAnimationAuto__Q34nw4r3lyt6LayoutFRCQ34nw4r3lyt12AnimResourcePQ34nw4r3lyt16ResourceAccessor bool Layout::BindAnimationAuto(const AnimResource &animRes, ResourceAccessor *pResAcsr) { - return IsIncludeAnimationGroupRef(nullptr, nullptr, 0, 0, nullptr); + // Ensure Root pane and Resource Block Exists + if (!mpRootPane) { + return false; + } + if (!animRes.GetResourceBlock()) { + return false; + } + + AnimTransform *pAnimTrans = CreateAnimTransform(); + u16 bindGroupNum = animRes.GetGroupNum(); + u16 animNum = 0; + if (bindGroupNum == 0) { + // No Groups to bind with, only bind to root pane + pAnimTrans->SetResource(animRes.GetResourceBlock(), pResAcsr, animRes.GetResourceBlock()->animContNum); + mpRootPane->BindAnimation(pAnimTrans, true, true); + } else { + // Bind to all Groups + const AnimationGroupRef *groupRefs = animRes.GetGroupArray(); + for (int grpIdx = 0; grpIdx < bindGroupNum; grpIdx++) { + Group *pGroup = mpGroupContainer->FindGroupByName(groupRefs[grpIdx].GetName()); + animNum += animRes.CalcAnimationNum(pGroup, animRes.IsDescendingBind()); + } + pAnimTrans->SetResource(animRes.GetResourceBlock(), pResAcsr, animNum); + for (int grpIdx = 0; grpIdx < bindGroupNum; grpIdx++) { + Group *pGroup = mpGroupContainer->FindGroupByName(groupRefs[grpIdx].GetName()); + lyt::BindAnimation(pGroup, pAnimTrans, animRes.IsDescendingBind(), true); + } + } + u16 animSharInfoNum = animRes.GetAnimationShareInfoNum(); + if (animSharInfoNum != 0) { + const AnimationShareInfo *animSharInfoAry = animRes.GetAnimationShareInfoArray(); + for (int i = 0; i < animSharInfoNum; i++) { + Pane *pSrcPane = mpRootPane->FindPaneByName(animSharInfoAry[i].GetSrcPaneName(), true); + detail::AnimPaneTree animPaneTree = detail::AnimPaneTree(pSrcPane, animRes); + if (animPaneTree.GetLinkNum()) { + Group *pGroup = mpGroupContainer->FindGroupByName(animSharInfoAry[i].GetTargetGroupName()); + ut::LinkList *paneList = pGroup->GetPaneList(); + for (ut::LinkList::Iterator it = paneList->GetBeginIter(); + it != paneList->GetEndIter(); it++) { + if (it->mTarget != pSrcPane) { + if (bindGroupNum != 0) { + bool bInclude = IsIncludeAnimationGroupRef(mpGroupContainer, animRes.GetGroupArray(), + bindGroupNum, animRes.IsDescendingBind(), it->mTarget); + if (!bInclude) { + continue; + } + } + animPaneTree.Bind(this, it->mTarget, pResAcsr); + } + } + } + } + } + return true; } // SetAnimationEnable__Q34nw4r3lyt6LayoutFPQ34nw4r3lyt13AnimTransformb -void Layout::SetAnimationEnable(AnimTransform *pAnimTrans, bool bEnable) {} +void Layout::SetAnimationEnable(AnimTransform *pAnimTrans, bool bEnable) { + if (!mpRootPane) { + return; + } + mpRootPane->SetAnimationEnable(pAnimTrans, bEnable, true); +} // CalculateMtx__Q34nw4r3lyt6LayoutFRCQ34nw4r3lyt8DrawInfo -void Layout::CalculateMtx(const DrawInfo &drawInfo) {} +void Layout::CalculateMtx(const DrawInfo &drawInfo) { + if (!mpRootPane) { + return; + } + mpRootPane->CalculateMtx(drawInfo); +} // Draw__Q34nw4r3lyt6LayoutFRCQ34nw4r3lyt8DrawInfo -void Layout::Draw(const DrawInfo &drawInfo) {} +void Layout::Draw(const DrawInfo &drawInfo) { + if (!mpRootPane) { + return; + } + mpRootPane->Draw(drawInfo); +} // Animate__Q34nw4r3lyt6LayoutFUl -void Layout::Animate(u32 option) {} +void Layout::Animate(u32 option) { + if (!mpRootPane) { + return; + } + mpRootPane->Animate(option); +} // GetLayoutRect__Q34nw4r3lyt6LayoutCFv -ut::Rect Layout::GetLayoutRect() const {} +ut::Rect Layout::GetLayoutRect() const { + return ut::Rect(-mLayoutSize.width / 2, mLayoutSize.height / 2, mLayoutSize.width / 2, -mLayoutSize.height / 2); +} // SetTagProcessor__Q34nw4r3lyt6LayoutFPQ34nw4r2ut19TagProcessorBase void Layout::SetTagProcessor(ut::TagProcessorBase *pTagProcessor) {