diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 71a2567a..a4c11e15 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -3864,7 +3864,7 @@ GetRuntimeTypeInfo__Q34nw4r3lyt7TextBoxCFv = .text:0x800B15B0; // type:function fn_800B15C0 = .text:0x800B15C0; // type:function size:0x68 fn_800B1630 = .text:0x800B1630; // type:function size:0x3C fn_800B1670 = .text:0x800B1670; // type:function size:0x134 -fn_800B17B0 = .text:0x800B17B0; // type:function size:0x8 +GetRuntimeTypeInfo__Q34nw4r3lyt6WindowCFv = .text:0x800B17B0; // type:function size:0x8 scope:weak fn_800B17C0 = .text:0x800B17C0; // type:function size:0x58 __dt__Q34nw4r3lyt19ArcResourceAccessorFv = .text:0x800B1820; // type:function size:0x6C scope:weak fn_800B1890 = .text:0x800B1890; // type:function size:0x40 @@ -37077,8 +37077,8 @@ __vt__Q34nw4r3lyt5Group = .data:0x8056E4A8; // type:object size:0xC __vt__Q34nw4r3lyt6Layout = .data:0x8056E4B8; // type:object size:0x40 __vt__Q34nw4r3lyt7Picture = .data:0x8056E4F8; // type:object size:0x78 __vt__Q34nw4r3lyt7TextBox = .data:0x8056E570; // type:object size:0x84 -lbl_8056E5F8 = .data:0x8056E5F8; // type:object size:0x3C -lbl_8056E634 = .data:0x8056E634; // type:object size:0x8C +@LOCAL@GetTextureFlipInfo__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FUc@flipInfos = .data:0x8056E5F8; // type:object size:0x3C +__vt__Q34nw4r3lyt6Window = .data:0x8056E634; // type:object size:0x8C lbl_8056E6C0 = .data:0x8056E6C0; // type:object size:0x78 lbl_8056E738 = .data:0x8056E738; // type:object size:0x20 data:4byte lbl_8056E758 = .data:0x8056E758; // type:object size:0x20 data:4byte diff --git a/configure.py b/configure.py index caea4da1..e81a6cdc 100644 --- a/configure.py +++ b/configure.py @@ -203,6 +203,7 @@ cflags_nw4r = [ *cflags_base, "-ipa file", "-fp_contract off", + "" ] # REL flags @@ -357,7 +358,7 @@ config.libs = [ Object(Matching, "nw4r/lyt/lyt_layout.cpp"), Object(Matching, "nw4r/lyt/lyt_picture.cpp"), Object(Matching, "nw4r/lyt/lyt_textBox.cpp"), - Object(NonMatching, "nw4r/lyt/lyt_window.cpp"), + Object(Matching, "nw4r/lyt/lyt_window.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_bounding.h b/include/nw4r/lyt/lyt_bounding.h index 56fe12d2..323e768a 100644 --- a/include/nw4r/lyt/lyt_bounding.h +++ b/include/nw4r/lyt/lyt_bounding.h @@ -8,13 +8,6 @@ namespace nw4r { namespace lyt { -struct ResBlockSet { - const res::TextureList *pTextureList; // at 0x00 - const res::FontList *pFontList; // at 0x04 - const res::MaterialList *pMaterialList; // at 0x08 - ResourceAccessor *pResAccessor; // at 0x0C -}; - class Bounding : public Pane { public: Bounding(const res::Bounding *, const ResBlockSet &); diff --git a/include/nw4r/lyt/lyt_common.h b/include/nw4r/lyt/lyt_common.h index 81b40ae5..bd09aae9 100644 --- a/include/nw4r/lyt/lyt_common.h +++ b/include/nw4r/lyt/lyt_common.h @@ -75,10 +75,19 @@ void MultipleAlpha(ut::Color *, const ut::Color *, u8); // Inlined ut::Color MultipleAlpha(ut::Color, u8); void SetVertexFormat(bool, u8); void DrawQuad(const math::VEC2 &, const Size &, u8, const TexCoordData *, const ut::Color *); -void DrawQuad(const math::VEC2 &, const Size &, u8, const TexCoordData *, const ut::Color *, u8); +void DrawQuad(const math::VEC2 &basePt, const Size &size, u8 texCoordNum, const TexCoordData *texCoords, + const ut::Color *vtxColors, u8 alpha); void DrawLine(const math::VEC2 &pos, const Size &size, ut::Color color); } // namespace detail + +struct ResBlockSet { + const res::TextureList *pTextureList; // at 0x00 + const res::FontList *pFontList; // at 0x04 + const res::MaterialList *pMaterialList; // at 0x08 + ResourceAccessor *pResAccessor; // at 0x0C +}; + } // namespace lyt } // namespace nw4r diff --git a/include/nw4r/lyt/lyt_layout.h b/include/nw4r/lyt/lyt_layout.h index b7d801c7..13689a32 100644 --- a/include/nw4r/lyt/lyt_layout.h +++ b/include/nw4r/lyt/lyt_layout.h @@ -3,6 +3,7 @@ #include "common.h" #include #include +#include #include #include #include diff --git a/include/nw4r/lyt/lyt_window.h b/include/nw4r/lyt/lyt_window.h index a13133d6..89c6d9e4 100644 --- a/include/nw4r/lyt/lyt_window.h +++ b/include/nw4r/lyt/lyt_window.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -10,6 +11,19 @@ namespace nw4r { namespace lyt { +// NOT OFFICAL +// Pulled from https://wiki.tockdom.com/wiki/BRLYT_(File_Format)#Window_Frames +enum TextureFlip { + TEXFLIP_NONE, + TEXFLIP_HORIZONTAL, + TEXFLIP_VERTICAL, + TEXFLIP_ROTATE_90, + TEXFLIP_ROTATE_180, + TEXFLIP_ROTATE_270, +}; + +enum TextureCoord { TopL, TopR, BotL, BotR }; + struct WindowFrameSize { f32 l; // at 0x00 f32 r; // at 0x04 @@ -20,13 +34,17 @@ struct WindowFrameSize { class Window : public Pane { public: struct Content { - Content() {} + Content() : vtxColors(), texCoordAry() {} ut::Color vtxColors[4]; // at 0x00 detail::TexCoordAry texCoordAry; // at 0x10 }; struct Frame { - bool textureFlip; // at 0x00 + Frame() : textureFlip(false), pMaterial(nullptr) {} + ~Frame() { + Layout::DeleteObj(pMaterial); + } + u8 textureFlip; // at 0x00 Material *pMaterial; // at 0x04 }; @@ -35,12 +53,8 @@ public: void InitContent(u8 texNum); void InitFrame(u8 frameNum); void ReserveTexCoord(u8 num); - AnimationLink *FindAnimationLink(AnimTransform *pAnimTrans); - void SetAnimationEnable(AnimTransform *pAnimTrans, bool, bool); static WindowFrameSize GetFrameSize(u8 frameNum, const Frame *frames); - Material *GetFrameMaterial(u32 frameIdx) const; - Material *GetContentMaterial() const; virtual ~Window(); // at 0x08 NW4R_UT_RTTI_DECL(Window); // at 0x0C @@ -54,18 +68,20 @@ public: virtual void UnbindAnimationSelf(AnimTransform *pAnimTrans); // at 0x50 virtual u8 GetMaterialNum() const; // at 0x64 virtual Material *GetMaterial(u32 idx) const; // at 0x6C - virtual void DrawContent(const math::VEC2 &basePt, const WindowFrameSize &frameSize, u8 alpha); // at 0x74 + virtual Material *GetContentMaterial() const; // at 0x74 + virtual Material *GetFrameMaterial(u32 frameIdx) const; // at 0x78 + virtual void DrawContent(const math::VEC2 &basePt, const WindowFrameSize &frameSize, u8 alpha); // at 0x7C virtual void DrawFrame(const math::VEC2 &basePt, const Frame &frame, const WindowFrameSize &frameSize, // - u8 alpha); // at 0x78 - virtual void DrawFrame4(const math::VEC2 &basePt, const Frame *frame, const WindowFrameSize &frameSize, // - u8 alpha); // at 0x7C - virtual void DrawFrame8(const math::VEC2 &basePt, const Frame *frame, const WindowFrameSize &frameSize, // u8 alpha); // at 0x80 + virtual void DrawFrame4(const math::VEC2 &basePt, const Frame *frame, const WindowFrameSize &frameSize, // + u8 alpha); // at 0x84 + virtual void DrawFrame8(const math::VEC2 &basePt, const Frame *frame, const WindowFrameSize &frameSize, // + u8 alpha); // at 0x88 private: res::InflationLRTB mContentInflation; // at 0x0D8 Content mContent; // at 0x0E8 - Frame *mFrams; // at 0x100 + Frame *mFrames; // at 0x100 u8 mFrameNum; // 0x104 }; diff --git a/src/nw4r/lyt/lyt_window.cpp b/src/nw4r/lyt/lyt_window.cpp index 728c461d..93bb2ed7 100644 --- a/src/nw4r/lyt/lyt_window.cpp +++ b/src/nw4r/lyt/lyt_window.cpp @@ -1,76 +1,179 @@ #include +#include +#include #include namespace nw4r { namespace lyt { - // TODO: Find Place struct TextureFlipInfo { - u8 coords[2][4]; // at 0x00 + u8 coords[4][2]; // at 0x00 u8 idx[2]; // at 0x8 }; -TextureFlipInfo flipInfos[6] = {}; - namespace { // GetTexutreFlipInfo__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FUc // GetTexutreFlipInfo__24@unnamed@lyt_window_cpp@FUc -TextureFlipInfo &GetTextureFlipInfo(u8 textureFlip) {} +// look at TextureFlip enum in lyt_window.h +TextureFlipInfo &GetTextureFlipInfo(u8 textureFlip) { + static TextureFlipInfo flipInfos[6] = { + // TopL TopR BotL BotR idx + {{{0, 0}, {1, 0}, {0, 1}, {1, 1}}, {0, 1}}, // Normal + {{{1, 0}, {0, 0}, {1, 1}, {0, 1}}, {0, 1}}, // Horizontal Flip + {{{0, 1}, {1, 1}, {0, 0}, {1, 0}}, {0, 1}}, // Vertical Flip + {{{0, 1}, {0, 0}, {1, 1}, {1, 0}}, {1, 0}}, // Rotate 90 + {{{1, 1}, {0, 1}, {1, 0}, {0, 0}}, {0, 1}}, // Rotate 180 + {{{1, 0}, {1, 1}, {0, 0}, {0, 1}}, {1, 0}}, // Rotate 270 + }; + return flipInfos[textureFlip]; +} + +/** +----> +x + * LT RT | + * v v v + * +-------+-----------------+-------+ ^ -y + * | ^ | | | + * | t | | | VTX: (x, y) + * | v | | | base = (x, y) + * LB->+-------+-----------------+ + | LT = ( x , y ) + * | | | | | RT = ( x + w - r , y ) + * | | | | | LB = ( x , y - t ) + * |<- l ->| |<- r ->| h RB = ( x + l , y - h + b ) + * | | | | | SIZE: (w, h) + * | | RB (at +) | | | LT = ( w - r , t ) + * | | V | | | RT = ( r , h - b ) + * + +-----------------+-------+ | LB = ( l , h - t ) + * | | ^ | | RB = ( w - l , b ) + * | | b | | + * | | v | | + * +-------+-----------------+-------+ v + * <--------------- w ---------------> + */ + +// The below functions were started with +// https://github.com/Treeki/LayoutStudio/blob/be8b56a7f0a8f6ba5456a099b61d032fd8aa2f61/layoutgl/widget.cpp#L162 Really +// helped read the awful Ghidra output xD // GetLTFrameSize__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2PQ34nw4r3lyt4SizeRCQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt15WindowFrameSize // GetLTFrameSize__24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2PQ34nw4r3lyt4SizeRCQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt15WindowFrameSize void GetLTFrameSize(math::VEC2 *pPt, Size *pSize, const math::VEC2 &basePt, const Size &windSize, - const WindowFrameSize &frameSize) {} + const WindowFrameSize &frameSize) { + *pPt = basePt; + // pPt->x = basePt.x; + // pPt->y = basePt.y; + pSize->width = windSize.width - frameSize.r; + pSize->height = frameSize.t; + // *pSize = Size(windSize.width - frameSize.r, frameSize.t); +} // GetLTTexCoord__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt4SizeUc // GetLTTexCoord__24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt4SizeUc void GetLTTexCoord(math::VEC2 *texCds, const Size &polSize, const Size &texSize, u8 textureFlip) { - const TextureFlipInfo &flipInfo = flipInfo; - int ix; - int iy; - math::VEC2 tSz; + const TextureFlipInfo &flipInfo = GetTextureFlipInfo(textureFlip); + + int ix = flipInfo.idx[0]; + int iy = flipInfo.idx[1]; + math::VEC2 tSz(texSize.width, texSize.height); + + // clang-format off + // Again no temp vars used here + texCds[TopL][ix] = texCds[BotL][ix] = flipInfo.coords[TopL][ix]; + texCds[TopL][iy] = texCds[TopR][iy] = flipInfo.coords[TopL][iy]; + + texCds[BotR][ix] = texCds[TopR][ix] = flipInfo.coords[TopL][ix] + polSize.width / ((flipInfo.coords[TopR][ix] - flipInfo.coords[TopL][ix]) * tSz[ix]); + texCds[BotR][iy] = texCds[BotL][iy] = flipInfo.coords[TopL][iy] + polSize.height / ((flipInfo.coords[BotL][iy] - flipInfo.coords[TopL][iy]) * tSz[iy]); + // clang-format on } // GetRTFrameSize__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2PQ34nw4r3lyt4SizeRCQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt15WindowFrameSize // GetRTFrameSize__24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2PQ34nw4r3lyt4SizeRCQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt15WindowFrameSize void GetRTFrameSize(math::VEC2 *pPt, Size *pSize, const math::VEC2 &basePt, const Size &windSize, - const WindowFrameSize &frameSize) {} + const WindowFrameSize &frameSize) { + *pPt = math::VEC2(basePt.x + windSize.width - frameSize.r, basePt.y); + // pPt->x = basePt.x + windSize.width - frameSize.r; + // pPt->y = basePt.y + // *pSize = Size(frameSize.r, windSize.height - frameSize.b); + pSize->width = frameSize.r; + pSize->height = windSize.height - frameSize.b; +} // GetRTTexCoord__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt4SizeUc // GetRTTexCoord__24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt4SizeUc void GetRTTexCoord(math::VEC2 *texCds, const Size &polSize, const Size &texSize, u8 textureFlip) { - const TextureFlipInfo &flipInfo = flipInfo; - int ix; - int iy; - math::VEC2 tSz; + const TextureFlipInfo &flipInfo = GetTextureFlipInfo(textureFlip); + int ix = flipInfo.idx[0]; + int iy = flipInfo.idx[1]; + + math::VEC2 tSz(texSize.width, texSize.height); + // clang-format off + // Again no temp vars used here + texCds[TopR][ix] = texCds[BotR][ix] = flipInfo.coords[TopR][ix]; + texCds[TopR][iy] = texCds[TopL][iy] = flipInfo.coords[TopR][iy]; + + texCds[BotL][ix] = texCds[TopL][ix] = flipInfo.coords[TopR][ix] + polSize.width / ((flipInfo.coords[TopL][ix] - flipInfo.coords[TopR][ix]) * tSz[ix]); + texCds[BotL][iy] = texCds[BotR][iy] = flipInfo.coords[TopR][iy] + polSize.height / ((flipInfo.coords[BotR][iy] - flipInfo.coords[TopR][iy]) * tSz[iy]); + // clang-format on } // GetLBFrameSize__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2PQ34nw4r3lyt4SizeRCQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt15WindowFrameSize // GetLBFrameSize__24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2PQ34nw4r3lyt4SizeRCQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt15WindowFrameSize void GetLBFrameSize(math::VEC2 *pPt, Size *pSize, const math::VEC2 &basePt, const Size &windSize, - const WindowFrameSize &frameSize) {} + const WindowFrameSize &frameSize) { + *pPt = math::VEC2(basePt.x, basePt.y - frameSize.t); + // pPt->x = basePt.x; + // pPt->y = basePt.y - frameSize.t; + + // *pSize = Size(frameSize.l, windSize.height - frameSize.t); + pSize->width = frameSize.l; + pSize->height = windSize.height - frameSize.t; +} // GetLBTexCoord__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt4SizeUc // GetLBTexCoord__24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt4SizeUc void GetLBTexCoord(math::VEC2 *texCds, const Size &polSize, const Size &texSize, u8 textureFlip) { - const TextureFlipInfo &flipInfo = flipInfo; - int ix; - int iy; - math::VEC2 tSz; + const TextureFlipInfo &flipInfo = GetTextureFlipInfo(textureFlip); + int ix = flipInfo.idx[0]; + int iy = flipInfo.idx[1]; + + math::VEC2 tSz(texSize.width, texSize.height); + // clang-format off + // Again no temp vars used here + texCds[BotL][ix] = texCds[TopL][ix] = flipInfo.coords[BotL][ix]; + texCds[BotL][iy] = texCds[BotR][iy] = flipInfo.coords[BotL][iy]; + + texCds[TopR][ix] = texCds[BotR][ix] = flipInfo.coords[BotL][ix] + polSize.width / ((flipInfo.coords[BotR][ix] - flipInfo.coords[BotL][ix]) * tSz[ix]); + texCds[TopR][iy] = texCds[TopL][iy] = flipInfo.coords[BotL][iy] + polSize.height / ((flipInfo.coords[TopL][iy] - flipInfo.coords[BotL][iy]) * tSz[iy]); + + // clang-format on } // GetRBFrameSize__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2PQ34nw4r3lyt4SizeRCQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt15WindowFrameSize // GetRBFrameSize__24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2PQ34nw4r3lyt4SizeRCQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt15WindowFrameSize void GetRBFrameSize(math::VEC2 *pPt, Size *pSize, const math::VEC2 &basePt, const Size &windSize, - const WindowFrameSize &frameSize) {} + const WindowFrameSize &frameSize) { + *pPt = math::VEC2(basePt.x + frameSize.l, basePt.y - windSize.height + frameSize.b); + // pPt->x = basePt.x + frameSize.l; + // pPt->y = basePt.y - windSize.height + frameSize.b; + // *pSize = Size(windSize.width - frameSize.l, frameSize.b); + pSize->width = windSize.width - frameSize.l; + pSize->height = frameSize.b; +} // GetRBTexCoord__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt4SizeUc // GetRBTexCoord__24@unnamed@lyt_window_cpp@FPQ34nw4r4math4VEC2RCQ34nw4r3lyt4SizeRCQ34nw4r3lyt4SizeUc void GetRBTexCoord(math::VEC2 *texCds, const Size &polSize, const Size &texSize, u8 textureFlip) { - const TextureFlipInfo &flipInfo = flipInfo; - int ix; - int iy; - math::VEC2 tSz; + const TextureFlipInfo &flipInfo = GetTextureFlipInfo(textureFlip); + int ix = flipInfo.idx[0]; + int iy = flipInfo.idx[1]; + math::VEC2 tSz(texSize.width, texSize.height); + + // clang-format off + texCds[BotR][ix] = texCds[TopR][ix] = flipInfo.coords[BotR][ix]; + texCds[BotR][iy] = texCds[BotL][iy] = flipInfo.coords[BotR][iy]; + + texCds[TopL][ix] = texCds[BotL][ix] = flipInfo.coords[BotR][ix] + polSize.width / ((flipInfo.coords[BotL][ix] - flipInfo.coords[BotR][ix]) * tSz[ix]); + texCds[TopL][iy] = texCds[TopR][iy] = flipInfo.coords[BotR][iy] + polSize.height / ((flipInfo.coords[TopR][iy] - flipInfo.coords[BotR][iy]) * tSz[iy]); + // clang-format on } } // namespace @@ -79,94 +182,222 @@ NW4R_UT_RTTI_DEF_DERIVED(Window, Pane); // __dt__Q44nw4r3lyt6Window5FrameFv // __ct__Q34nw4r3lyt6WindowFPCQ44nw4r3lyt3res6WindowRCQ34nw4r3lyt11ResBlockSet -Window::Window(const res::Window *pBlock, const ResBlockSet &ResBlockSet) { - const res::WindowContent *pResContent; - u8 texCoordNum; - const u32 *matOffsTbl; - { - int i; - const res::Material *pResMaterial; +Window::Window(const res::Window *pBlock, const ResBlockSet &resBlockSet) : Pane(pBlock), mContent() { + const res::WindowContent *pResContent = + detail::ConvertOffsToPtr(pBlock, pBlock->contentOffset); + + u8 texCoordNum = ut::Min(pResContent->texCoordNum, 8); + + InitContent(texCoordNum); + + const u32 *matOffsTbl = detail::ConvertOffsToPtr(resBlockSet.pMaterialList, sizeof(res::MaterialList)); + + mContentInflation = pBlock->inflation; + for (int i = 0; i < TEXCOORD_VTX_COUNT; i++) { + mContent.vtxColors[i] = pResContent->vtxCols[i]; } - const u32 *frameOffsetTable; - { - int i; - const res::WindowFrame *pResWindowFrame; + if (texCoordNum && !mContent.texCoordAry.IsEmpty()) { + mContent.texCoordAry.Copy(&pResContent[1], texCoordNum); + } + + const res::Material *pResMaterial = + detail::ConvertOffsToPtr(resBlockSet.pMaterialList, matOffsTbl[pResContent->materialIdx]); + mpMaterial = Layout::NewObj(pResMaterial, resBlockSet); + + mFrameNum = 0; + mFrames = nullptr; + if (pBlock->frameNum) { + InitFrame(pBlock->frameNum); + const u32 *frameOffsetTable = detail::ConvertOffsToPtr(pBlock, pBlock->frameOffsetTableOffset); + for (int i = 0; i < mFrameNum; i++) { + const res::WindowFrame *pResWindowFrame = + detail::ConvertOffsToPtr(pBlock, frameOffsetTable[i]); + mFrames[i].textureFlip = pResWindowFrame->textureFlip; + const res::Material *pResMaterial = detail::ConvertOffsToPtr(resBlockSet.pMaterialList, + matOffsTbl[pResWindowFrame->materialIdx]); + mFrames[i].pMaterial = Layout::NewObj(pResMaterial, resBlockSet); + } } } // InitContent__Q34nw4r3lyt6WindowFUc -void Window::InitContent(u8 texNum) {} +void Window::InitContent(u8 texNum) { + // Guess based of of usual Init Patterns + // not needed to match ¯\_(ツ)_/¯ + if (texNum) { + ReserveTexCoord(texNum); + } +} // InitFrame__Q34nw4r3lyt6WindowFUc -void Window::InitFrame(u8 frameNum) {} +void Window::InitFrame(u8 frameNum) { + mFrameNum = 0; + mFrames = Layout::NewArray(frameNum); + if (mFrames) { + mFrameNum = frameNum; + } +} // __dt__Q44nw4r3lyt6Window7ContentFv // __dt__Q34nw4r3lyt6WindowFv -Window::~Window() {} +Window::~Window() { + Layout::DeleteArray(mFrames, mFrameNum); + if (mpMaterial && !mpMaterial->IsUserAllocated()) { + Layout::DeleteObj(mpMaterial); + mpMaterial = nullptr; + } + mContent.texCoordAry.Free(); +} // ReserveTexCoord__Q34nw4r3lyt6WindowFUc -void Window::ReserveTexCoord(u8 num) {} +void Window::ReserveTexCoord(u8 num) { + // Inline Guess + mContent.texCoordAry.Reserve(num); +} // FindMaterialByName__Q34nw4r3lyt6WindowFPCcb Material *Window::FindMaterialByName(const char *findName, bool bRecursive) { - int i; - // ut::LinkList<>::Iterator it - Material *pMat; + if (mpMaterial && detail::EqualsMaterialName(mpMaterial->GetName(), findName)) { + return mpMaterial; + } + + for (int i = 0; i < mFrameNum; i++) { + if (detail::EqualsMaterialName(mFrames[i].pMaterial->GetName(), findName)) { + return mFrames[i].pMaterial; + } + } + + if (bRecursive) { + for (ut::LinkList::Iterator it = mChildList.GetBeginIter(); it != mChildList.GetEndIter(); it++) { + Material *pMat = it->FindMaterialByName(findName, bRecursive); + if (pMat) { + return pMat; + } + } + } + return nullptr; } // FindAnimationLink__Q34nw4r3lyt6WindowFPQ34nw4r3lyt13AnimTransform -AnimationLink *Window::FindAnimationLink(AnimTransform *pAnimTrans) { - // TOOD -} +// AnimationLink *Window::FindAnimationLink(AnimTransform *pAnimTrans) { +// // Not In SS - Part of Vtable in Pane +// } // SetAnimationEnable__Q34nw4r3lyt6WindowFPQ34nw4r3lyt13AnimTransformbb -void Window::SetAnimationEnable(AnimTransform *pAnimTrans, bool, bool) { - // TOOD -} +// void Window::SetAnimationEnable(AnimTransform *pAnimTrans, bool, bool) { +// // Not In SS - Part of Vtable in Pane +// } // GetVtxColor__Q34nw4r3lyt6WindowCFUl -ut::Color Window::GetVtxColor(u32 idx) const {} +ut::Color Window::GetVtxColor(u32 idx) const { + return mContent.vtxColors[idx]; +} // SetVtxColor__Q34nw4r3lyt6WindowFUlQ34nw4r2ut5Color -void Window::SetVtxColor(u32, ut::Color) {} +void Window::SetVtxColor(u32 idx, ut::Color value) { + mContent.vtxColors[idx] = value; +} // GetVtxColorElement__Q34nw4r3lyt6WindowCFUl -u8 Window::GetVtxColorElement(u32 idx) const {} +u8 Window::GetVtxColorElement(u32 idx) const { + return detail::GetVtxColorElement(mContent.vtxColors, idx); +} // SetVtxColorElement__Q34nw4r3lyt6WindowFUlUc -void Window::SetVtxColorElement(u32 idx, u8 value) {} +void Window::SetVtxColorElement(u32 idx, u8 value) { + detail::SetVtxColElement(mContent.vtxColors, idx, value); +} // DrawSelf__Q34nw4r3lyt6WindowFRCQ34nw4r3lyt8DrawInfo void Window::DrawSelf(const DrawInfo &drawInfo) { - WindowFrameSize frameSize; - math::VEC2 bastPt; + LoadMtx(drawInfo); + WindowFrameSize frameSize = GetFrameSize(mFrameNum, mFrames); + math::VEC2 basePt = GetVtxPos(); + DrawContent(basePt, frameSize, mGlbAlpha); + switch (mFrameNum) { + case 1: + DrawFrame(basePt, mFrames[0], frameSize, mGlbAlpha); + break; + case 4: + DrawFrame4(basePt, mFrames, frameSize, mGlbAlpha); + break; + case 8: + DrawFrame8(basePt, mFrames, frameSize, mGlbAlpha); + break; + } } // AnimateSelf__Q34nw4r3lyt6WindowFUl void Window::AnimateSelf(u32 option) { - int i; + Pane::AnimateSelf(option); + if (IsVisible() || !(option & 1)) { + for (int i = 0; i < mFrameNum; i++) { + mFrames[i].pMaterial->Animate(); + } + } } // UnbindAnimationSelf__Q34nw4r3lyt6WindowFPQ34nw4r3lyt13AnimTransform void Window::UnbindAnimationSelf(AnimTransform *pAnimTrans) { - int i; + for (int i = 0; i < mFrameNum; i++) { + mFrames[i].pMaterial->UnbindAnimation(pAnimTrans); + } + Pane::UnbindAnimationSelf(pAnimTrans); } // DrawContent__Q34nw4r3lyt6WindowFRCQ34nw4r4math4VEC2RCQ34nw4r3lyt15WindowFrameSizeUc void Window::DrawContent(const math::VEC2 &basePt, const WindowFrameSize &frameSize, u8 alpha) { - bool bUseVtxCol; + bool bUseVtxCol = detail::IsModulateVertexColor(mContent.vtxColors, alpha); + bUseVtxCol = mpMaterial->SetupGX(bUseVtxCol, alpha); + detail::SetVertexFormat(bUseVtxCol, mContent.texCoordAry.GetSize()); + + // Why not use temps wtf. only bUseVtxCol is defined in DWARF and I cant find evidence of an inline + detail::DrawQuad( + math::VEC2(basePt.x + frameSize.l - mContentInflation.l, basePt.y - frameSize.t + mContentInflation.t), + Size(mSize.width - frameSize.l + mContentInflation.l - frameSize.r + mContentInflation.r, + mSize.height - frameSize.t + mContentInflation.t - frameSize.b + mContentInflation.b), + mContent.texCoordAry.GetSize(), mContent.texCoordAry.GetArray(), bUseVtxCol ? mContent.vtxColors : nullptr, + alpha); } // DrawFrame__Q34nw4r3lyt6WindowFRCQ34nw4r4math4VEC2RCQ44nw4r3lyt6Window5FrameRCQ34nw4r3lyt15WindowFrameSizeUc void Window::DrawFrame(const math::VEC2 &basePt, const Frame &frame, const WindowFrameSize &frameSize, u8 alpha) { - bool bUseVtxCol; - Size texSize; - ut::Color vtxColors[4]; - detail::TexCoordData texCds[1]; - math::VEC2 polPt; - Size polSize; + if (frame.pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = detail::IsModulateVertexColor(nullptr, alpha); + bUseVtxCol = frame.pMaterial->SetupGX(bUseVtxCol, alpha); + + detail::SetVertexFormat(bUseVtxCol, 1); + Size texSize = detail::GetTextureSize(frame.pMaterial, 0); + + ut::Color vtxColors[4]; + detail::TexCoordData texCds[1]; + math::VEC2 polPt; + Size polSize; + + // Splits Frame into 4 Corners (repeats frame for each part (texture is quartered)) + // Not sure if just edges or Quadrants + // (Top Left Quadrant) + GetLTFrameSize(&polPt, &polSize, basePt, mSize, frameSize); + GetLTTexCoord(texCds[0], polSize, texSize, TEXFLIP_NONE); + detail::DrawQuad(polPt, polSize, 1, texCds, bUseVtxCol ? vtxColors : nullptr, alpha); + + // (Top Right Quadrant) + GetRTFrameSize(&polPt, &polSize, basePt, mSize, frameSize); + GetRTTexCoord(texCds[0], polSize, texSize, TEXFLIP_HORIZONTAL); + detail::DrawQuad(polPt, polSize, 1, texCds, bUseVtxCol ? vtxColors : nullptr, alpha); + + // (Bottom Right Quadrant) + GetRBFrameSize(&polPt, &polSize, basePt, mSize, frameSize); + GetRBTexCoord(texCds[0], polSize, texSize, TEXFLIP_ROTATE_180); + detail::DrawQuad(polPt, polSize, 1, texCds, bUseVtxCol ? vtxColors : nullptr, alpha); + + // (Bottom Left Quadrant) + GetLBFrameSize(&polPt, &polSize, basePt, mSize, frameSize); + GetLBTexCoord(texCds[0], polSize, texSize, TEXFLIP_VERTICAL); + detail::DrawQuad(polPt, polSize, 1, texCds, bUseVtxCol ? vtxColors : nullptr, alpha); + } } // DrawFrame4__Q34nw4r3lyt6WindowFRCQ34nw4r4math4VEC2PCQ44nw4r3lyt6Window5FrameRCQ34nw4r3lyt15WindowFrameSizeUc @@ -175,47 +406,193 @@ void Window::DrawFrame4(const math::VEC2 &basePt, const Frame *frame, const Wind detail::TexCoordData texCds[1]; math::VEC2 polPt; Size polSize; - bool bModVtxCol; - { bool bUseVtxCol; } - { bool bUseVtxCol; } - { bool bUseVtxCol; } - { bool bUseVtxCol; } + + bool bModVtxCol = detail::IsModulateVertexColor(nullptr, alpha); + if (frame[0].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[0].pMaterial->SetupGX(bModVtxCol, alpha); + GetLTFrameSize(&polPt, &polSize, basePt, mSize, frameSize); + GetLTTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[0].pMaterial, 0), frame[0].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(polPt, polSize, 1, texCds, bUseVtxCol ? vtxColors : nullptr, alpha); + } + + if (frame[1].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[1].pMaterial->SetupGX(bModVtxCol, alpha); + GetRTFrameSize(&polPt, &polSize, basePt, mSize, frameSize); + GetRTTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[1].pMaterial, 0), frame[1].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(polPt, polSize, 1, texCds, bUseVtxCol ? vtxColors : nullptr, alpha); + } + + if (frame[3].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[3].pMaterial->SetupGX(bModVtxCol, alpha); + GetRBFrameSize(&polPt, &polSize, basePt, mSize, frameSize); + GetRBTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[3].pMaterial, 0), frame[3].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(polPt, polSize, 1, texCds, bUseVtxCol ? vtxColors : nullptr, alpha); + } + + if (frame[2].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[2].pMaterial->SetupGX(bModVtxCol, alpha); + GetLBFrameSize(&polPt, &polSize, basePt, mSize, frameSize); + GetLBTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[2].pMaterial, 0), frame[2].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(polPt, polSize, 1, texCds, bUseVtxCol ? vtxColors : nullptr, alpha); + } } +/** +----> +x + * LT T RT | + * v v v v + * +-------+-----------------+-------+ ^ -y + * | | ^ | | | VTX: (x, y) + * | | t | | | base = (x, y) + * | | v | | | LT = ( x , y ) | L = ( x , y - t ) + * L->+-------+-----------------+-------+ | RT = ( x + w - r , y ) | R = ( x + w - r , y - t ) + * | | ^| | | LB = ( y - h + b , y - h + b ) | T = ( x + l , y ) + * | | R| | | RB = ( x + w - r , y - h + b ) | B = ( x + l , y - h + b ) + * |<- l ->| |<- r ->| h + * | | | | | SIZE: (w, h) + * | |B RB| | | LT = ( l , t ) | L = ( l , h - t - b ) + * | |V V| | | RT = ( r , t ) | R = ( r , h - t - b ) + * LB->+-------+-----------------+-------+ | LB = ( l , b ) | T = ( w - l - r , t ) + * | | ^ | | | RB = ( r , b ) | B = ( w - l - r , b ) + * | | b | | | + * | | v | | | + * +-------+-----------------+-------+ v + * <--------------- w ---------------> + */ + // DrawFrame8__Q34nw4r3lyt6WindowFRCQ34nw4r4math4VEC2PCQ44nw4r3lyt6Window5FrameRCQ34nw4r3lyt15WindowFrameSizeUc void Window::DrawFrame8(const math::VEC2 &basePt, const Frame *frame, const WindowFrameSize &frameSize, u8 alpha) { ut::Color vtxColors[4]; detail::TexCoordData texCds[1]; - math::VEC2 polPt; Size polSize; - bool bModVtxCol; - { bool bUseVtxCol; } - { bool bUseVtxCol; } - { bool bUseVtxCol; } - { bool bUseVtxCol; } - { bool bUseVtxCol; } - { bool bUseVtxCol; } - { bool bUseVtxCol; } - { bool bUseVtxCol; } + + bool bModVtxCol = detail::IsModulateVertexColor(nullptr, alpha); + // TOP LEFT + if (frame[0].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[0].pMaterial->SetupGX(bModVtxCol, alpha); + polSize = Size(frameSize.l, frameSize.t); + GetLTTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[0].pMaterial, 0), frame[0].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(basePt, polSize, 1, texCds, bUseVtxCol ? vtxColors : nullptr, alpha); + } + // TOP + if (frame[6].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[6].pMaterial->SetupGX(bModVtxCol, alpha); + polSize = Size(mSize.width - frameSize.l - frameSize.r, frameSize.t); + GetLTTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[6].pMaterial, 0), frame[6].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(math::VEC2(basePt.x + frameSize.l, basePt.y), polSize, 1, texCds, + bUseVtxCol ? vtxColors : nullptr, alpha); + } + // TOP RIGHT + if (frame[1].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[1].pMaterial->SetupGX(bModVtxCol, alpha); + polSize = Size(frameSize.r, frameSize.t); + GetRTTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[1].pMaterial, 0), frame[1].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(math::VEC2(basePt.x + mSize.width - frameSize.r, basePt.y), polSize, 1, texCds, + bUseVtxCol ? vtxColors : nullptr, alpha); + } + // RIGHT + if (frame[5].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[5].pMaterial->SetupGX(bModVtxCol, alpha); + polSize = Size(frameSize.r, mSize.height - frameSize.t - frameSize.b); + GetRTTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[5].pMaterial, 0), frame[5].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(math::VEC2(basePt.x + mSize.width - frameSize.r, basePt.y - frameSize.t), polSize, 1, texCds, + bUseVtxCol ? vtxColors : nullptr, alpha); + } + // BOTTOM RIGHT + if (frame[3].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[3].pMaterial->SetupGX(bModVtxCol, alpha); + polSize = Size(frameSize.r, frameSize.b); + GetRBTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[3].pMaterial, 0), frame[3].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(math::VEC2(basePt.x + mSize.width - frameSize.r, basePt.y - mSize.height + frameSize.b), + polSize, 1, texCds, bUseVtxCol ? vtxColors : nullptr, alpha); + } + // BOTTOM + if (frame[7].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[7].pMaterial->SetupGX(bModVtxCol, alpha); + polSize = Size(mSize.width - frameSize.l - frameSize.r, frameSize.b); + GetRBTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[7].pMaterial, 0), frame[7].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(math::VEC2(basePt.x + frameSize.l, basePt.y - mSize.height + frameSize.b), polSize, 1, texCds, + bUseVtxCol ? vtxColors : nullptr, alpha); + } + // BOTTOM LEFT + if (frame[2].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[2].pMaterial->SetupGX(bModVtxCol, alpha); + polSize = Size(frameSize.l, frameSize.b); + GetLBTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[2].pMaterial, 0), frame[2].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(math::VEC2(basePt.x, basePt.y - mSize.height + frameSize.b), polSize, 1, texCds, + bUseVtxCol ? vtxColors : nullptr, alpha); + } + // LEFT + if (frame[4].pMaterial->GetTextureNum() != 0) { + bool bUseVtxCol = frame[4].pMaterial->SetupGX(bModVtxCol, alpha); + polSize = Size(frameSize.l, mSize.height - frameSize.t - frameSize.b); + GetLBTexCoord(texCds[0], polSize, detail::GetTextureSize(frame[4].pMaterial, 0), frame[4].textureFlip); + detail::SetVertexFormat(bUseVtxCol, 1); + detail::DrawQuad(math::VEC2(basePt.x, basePt.y - frameSize.t), polSize, 1, texCds, + bUseVtxCol ? vtxColors : nullptr, alpha); + } } // GetFrameSize__Q34nw4r3lyt6WindowFUcPCQ44nw4r3lyt6Window5Frame WindowFrameSize Window::GetFrameSize(u8 frameNum, const Frame *frames) { - { Size texSize; } - { Size texSize; } + WindowFrameSize ret = {0.0f, 0.0f, 0.0f, 0.0f}; + switch (frameNum) { + case 1: { + Size texSize = detail::GetTextureSize(frames[0].pMaterial, 0); + ret.l = texSize.width; + ret.t = texSize.height; + ret.r = texSize.width; + ret.b = texSize.height; + } break; + case 4: + case 8: { + Size texSize = detail::GetTextureSize(frames[0].pMaterial, 0); + ret.l = texSize.width; + ret.t = texSize.height; + texSize = detail::GetTextureSize(frames[3].pMaterial, 0); + ret.r = texSize.width; + ret.b = texSize.height; + } break; + } + return ret; } // GetMaterialNum__Q34nw4r3lyt6WindowCFv -u8 Window::GetMaterialNum() const {} +u8 Window::GetMaterialNum() const { + return mFrameNum + 1; +} // GetMaterial__Q34nw4r3lyt6WindowCFUl -Material *Window::GetMaterial(u32 idx) const {} +Material *Window::GetMaterial(u32 idx) const { + if (idx == 0) { + return GetContentMaterial(); + } else { + return GetFrameMaterial(idx - 1); + } +} // GetFrameMaterial__Q34nw4r3lyt6WindowCFUl -Material *Window::GetFrameMaterial(u32 frameIdx) const {} +Material *Window::GetFrameMaterial(u32 frameIdx) const { + if (frameIdx >= mFrameNum) { + return nullptr; + } + return mFrames[frameIdx].pMaterial; +} // GetContentMaterial__Q34nw4r3lyt6WindowCFv -Material *Window::GetContentMaterial() const {} +Material *Window::GetContentMaterial() const { + return reinterpret_cast(this)->GetMaterial(); +} } // namespace lyt