#include "d/d_cursor_hit_check.h" #include "common.h" #include "d/col/bg/d_bg_s.h" #include "d/col/bg/d_bg_s_lin_chk.h" #include "d/col/cc/d_cc_s.h" #include "d/d_gfx.h" #include "d/d_pad.h" #include "d/d_stage_mgr.h" #include "m/m_mtx.h" #include "m/m_vec.h" #include "nw4r/g3d/g3d_camera.h" #include "nw4r/lyt/lyt_bounding.h" #include "nw4r/lyt/lyt_pane.h" #include "nw4r/ut/ut_RuntimeTypeInfo.h" #include "toBeSorted/d_d3d.h" dCsMgr_c::dCsMgr_c() { // NONMATCHING - TList ctor issues field_0x18 = true; sInstance = this; } extern "C" bool lbl_80572D10; void dCsMgr_c::execute() { // NONMATCHING - TList if (field_0x18 == 0 && lbl_80572D10 == 0) { for (CursorList::Iterator it = mList1.GetBeginIter(); it != mList1.GetEndIter(); ++it) { it->mpHit = nullptr; } return; } for (CursorList::Iterator it = mList1.GetBeginIter(); it != mList1.GetEndIter(); ++it) { mVec2_c &pos = it->getCursorPos(); s16 x = pos.x; s16 y = pos.y; it->mpHit = 0; u32 mask = it->mCursorMask; if (mask) { for (HitCheckList::Iterator chkIt = mList2.GetBeginIter(); chkIt != mList2.GetEndIter(); ++it) { if ((chkIt->mMask & mask) != 0) { bool hit = chkIt->checkHit(x, y); if (chkIt->checkOverrideCallback(hit)) { it->mpHit = &*chkIt; break; } } } } } } void dCsMgr_c::registCursor(dCursorInterface_c *cursor) { mList1.append(cursor); } void dCsMgr_c::unregistCursor(dCursorInterface_c *cursor) { // NONMATCHING - TList mList1.remove(cursor); } void dCsMgr_c::registCursorTarget(dCursorHitCheck_c *target) { // NONMATCHING - TList HitCheckList::Iterator it = mList2.GetBeginIter(); HitCheckList::Iterator end = mList2.GetEndIter(); while (it != end) { if (target->mPriority < it->mPriority) { if (it == end) { mList2.prepend(target); return; } mList2.insertBefore(&*it, target); return; } ++it; } mList2.append(target); } void dCsMgr_c::unregistCursorTarget(dCursorHitCheck_c *target) { // NONMATCHING - TList for (CursorList::Iterator it = mList1.GetBeginIter(); it != mList1.GetEndIter(); ++it) { if (target == it->mpHit) { it->mpHit = 0; } } mList2.remove(target); } bool dCsMgr_c::isRegist(dCursorHitCheck_c *target) { return mList2.GetPosition(target) != mList2.GetEndIter(); } dCsMgr_c *dCsMgr_c::create(EGG::Heap *heap) { return new (heap) dCsMgr_c(); } bool dCursorHitCheck_c::init(u8 prio, u8 a, u16 mask) { if (dCsMgr_c::GetInstance()->isRegist(this)) { return false; } mPriority = prio; field_0x017 = a; mMask = mask; return true; } bool dCursorHitCheck_c::checkOverrideCallback(bool b) { if (mOverrideHitCallback == nullptr) { return b; } return mOverrideHitCallback(b, this, mCallbackData); } bool dCursorHitCheckCC_c::checkHit(s32 x, s32 y) { // NONMATCHING - TODO mVec3_c pos( (x - dGfx_c::getWidth4x3LeftF()) / dGfx_c::getWidth4x3F() * 2.f - 1.f, (y - dGfx_c::getCurrentScreenTopF()) / dGfx_c::getCurrentScreenHeightF() * -2.f - 1.f, 10000.f ); mVec3_c v; d3d::fn_80016B60(v, pos); nw4r::g3d::Camera cam = dStageMgr_c::GetInstance()->getCamera(0); mMtx_c mtx; mVec3_c a; cam.GetCameraMtx(mtx); mtx.inverse(); mtx.getTranslation(a); dBgS_LinChk ck; ck.Set(&a, &v, nullptr); dBgS::GetInstance()->LineCross(&ck); cCcD_ShapeAttr *attr = nullptr; if (dCcS::GetInstance()->fn_80357c90(a, v, 0, &attr, 15.0f)) { // TODO - this branches into unsplit code in col/ return true; } else { return false; } } bool dCursorHitCheckCC_c::init(u16 mask, u8 prio, u8 a) { return dCursorHitCheck_c::init(prio, a, mask); } dCursorHitCheckLyt_c::~dCursorHitCheckLyt_c() { delete[] mpBoundingData; mpBoundingData = nullptr; } bool dCursorHitCheckLyt_c::checkHit(s32 x, s32 y) { dCsCheckLyt_BoundingData *p = &mpBoundingData[0]; for (u16 i = 0; i < mNumBoundings; i++) { if (p->mMinX <= x && x <= p->mMaxX && p->mMaxY >= y && y >= p->mMinY) { mpHitPane = p->mpPane; if (mpHitPane->GetAlpha() != 0 && mpHitPane->IsVisible()) { return true; } } p++; } mpHitPane = nullptr; return false; } bool dCursorHitCheckLyt_c::init(nw4r::lyt::Pane *pPane, u16 mask, u8 prio, u8 a) { if (!dCursorHitCheck_c::init(prio, a, mask)) { return false; } mpRootPane = pPane; mNumBoundings = 0; countBoundings(pPane); dCsCheckLyt_BoundingData *pData = new dCsCheckLyt_BoundingData[mNumBoundings](); mpBoundingData = pData; dCsCheckLyt_BoundingData *pEnd = pData + mNumBoundings; gatherBoundings(&pEnd, mpRootPane); return true; } void dCursorHitCheckLyt_c::execute() { if (!mHasCalculatedBoundingData) { dCsCheckLyt_BoundingData *dat = &mpBoundingData[0]; for (u16 i = 0; i < mNumBoundings; i++) { nw4r::lyt::Pane *pane = dat->mpPane; f32 xx = pane->GetGlobalMtx()._00; switch (pane->GetPositionH()) { case 0: dat->mMinX = (s16)pane->GetGlobalMtx()._03; dat->mMaxX = (s16)pane->GetGlobalMtx()._03 + xx * pane->GetSize().width; break; case 1: dat->mMinX = (s16)pane->GetGlobalMtx()._03 - xx * pane->GetSize().width * 0.5f; dat->mMaxX = (s16)pane->GetGlobalMtx()._03 + xx * pane->GetSize().width * 0.5f; break; case 2: dat->mMinX = (s16)pane->GetGlobalMtx()._03 - xx * pane->GetSize().width; dat->mMaxX = (s16)pane->GetGlobalMtx()._03; break; } switch (pane->GetPositionV()) { case 0: dat->mMaxY = (s16)pane->GetGlobalMtx()._13; dat->mMinY = (s16)pane->GetGlobalMtx()._13 - pane->GetSize().height; break; case 1: dat->mMaxY = (s16)pane->GetGlobalMtx()._13 + (pane->GetSize().height * 0.5f); dat->mMinY = (s16)pane->GetGlobalMtx()._13 - (pane->GetSize().height * 0.5f); break; case 2: dat->mMaxY = (s16)pane->GetGlobalMtx()._13 + pane->GetSize().height; dat->mMinY = (s16)pane->GetGlobalMtx()._13; break; } dat++; } mHasCalculatedBoundingData = true; } } void dCursorHitCheckLyt_c::countBoundings(nw4r::lyt::Pane *pane) { nw4r::lyt::Bounding *b = nw4r::ut::DynamicCast(pane); if (b != nullptr) { mNumBoundings++; } for (nw4r::lyt::Pane::ChildList::ReverseIterator it = pane->GetChildList()->GetEndReverseIter(); it != pane->GetChildList()->GetBeginIter(); ++it) { countBoundings(&*it); } } void dCursorHitCheckLyt_c::gatherBoundings(dCsCheckLyt_BoundingData **pEnd, nw4r::lyt::Pane *pane) { nw4r::lyt::Bounding *b = nw4r::ut::DynamicCast(pane); if (b != nullptr) { (*pEnd)--; (*pEnd)->mpPane = pane; } for (nw4r::lyt::Pane::ChildList::ReverseIterator it = pane->GetChildList()->GetEndReverseIter(); it != pane->GetChildList()->GetBeginIter(); ++it) { gatherBoundings(pEnd, &*it); } } mVec2_c &dCursorInterface_c::getCursorPos() { return dPad::ex_c::getInstance()->field_0x8; }