#include "nw4r/lyt/lyt_window.h" #include "nw4r/lyt/lyt_common.h" #include "nw4r/lyt/lyt_layout.h" #include "nw4r/lyt/lyt_types.h" namespace nw4r { namespace lyt { // TODO: Find Place struct TextureFlipInfo { u8 coords[4][2]; // at 0x00 u8 idx[2]; // at 0x8 }; namespace { // GetTexutreFlipInfo__Q34nw4r3lyt24@unnamed@lyt_window_cpp@FUc // GetTexutreFlipInfo__24@unnamed@lyt_window_cpp@FUc // 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 ) { *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 = 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 ) { *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 = 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 ) { *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 = 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 ) { *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 = 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 NW4R_UT_RTTI_DEF_DERIVED(Window, Pane); // __dt__Q44nw4r3lyt6Window5FrameFv // __ct__Q34nw4r3lyt6WindowFPCQ44nw4r3lyt3res6WindowRCQ34nw4r3lyt11ResBlockSet 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]; } 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) { // Guess based of of usual Init Patterns // not needed to match ¯\_(ツ)_/¯ if (texNum) { ReserveTexCoord(texNum); } } // InitFrame__Q34nw4r3lyt6WindowFUc void Window::InitFrame(u8 frameNum) { mFrameNum = 0; mFrames = Layout::NewArray(frameNum); if (mFrames) { mFrameNum = frameNum; } } // __dt__Q44nw4r3lyt6Window7ContentFv // __dt__Q34nw4r3lyt6WindowFv 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) { // Inline Guess mContent.texCoordAry.Reserve(num); } // FindMaterialByName__Q34nw4r3lyt6WindowFPCcb Material *Window::FindMaterialByName(const char *findName, bool bRecursive) { 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) { // // Not In SS - Part of Vtable in Pane // } // SetAnimationEnable__Q34nw4r3lyt6WindowFPQ34nw4r3lyt13AnimTransformbb // void Window::SetAnimationEnable(AnimTransform *pAnimTrans, bool, bool) { // // Not In SS - Part of Vtable in Pane // } // GetVtxColor__Q34nw4r3lyt6WindowCFUl ut::Color Window::GetVtxColor(u32 idx) const { return mContent.vtxColors[idx]; } // SetVtxColor__Q34nw4r3lyt6WindowFUlQ34nw4r2ut5Color void Window::SetVtxColor(u32 idx, ut::Color value) { mContent.vtxColors[idx] = value; } // GetVtxColorElement__Q34nw4r3lyt6WindowCFUl u8 Window::GetVtxColorElement(u32 idx) const { return detail::GetVtxColorElement(mContent.vtxColors, idx); } // SetVtxColorElement__Q34nw4r3lyt6WindowFUlUc void Window::SetVtxColorElement(u32 idx, u8 value) { detail::SetVtxColElement(mContent.vtxColors, idx, value); } // DrawSelf__Q34nw4r3lyt6WindowFRCQ34nw4r3lyt8DrawInfo void Window::DrawSelf(const DrawInfo &drawInfo) { 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) { 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) { 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 = 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) { 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 void Window::DrawFrame4(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 = 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]; Size polSize; 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) { 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 { return mFrameNum + 1; } // GetMaterial__Q34nw4r3lyt6WindowCFUl Material *Window::GetMaterial(u32 idx) const { if (idx == 0) { return GetContentMaterial(); } else { return GetFrameMaterial(idx - 1); } } // GetFrameMaterial__Q34nw4r3lyt6WindowCFUl Material *Window::GetFrameMaterial(u32 frameIdx) const { if (frameIdx >= mFrameNum) { return nullptr; } return mFrames[frameIdx].pMaterial; } // GetContentMaterial__Q34nw4r3lyt6WindowCFv Material *Window::GetContentMaterial() const { return reinterpret_cast(this)->GetMaterial(); } } // namespace lyt } // namespace nw4r // HEADER STUFF // ConvertOffsToPtr // ConvertOffsToPtr // __as__Q34nw4r3lyt13InflationLRTBFRCQ34nw4r3lyt13InflationLRTB // texCoordNum .sdata // flipInfos . data // ut::Min