summaryrefslogtreecommitdiff
path: root/src/d/d_cursor_hit_check.cpp
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2025-04-06 21:15:01 +0200
committerrobojumper <robojumper@gmail.com>2025-04-11 17:00:05 +0200
commitfe36b486bf28a220843194852506e7ad10b23a65 (patch)
treeeea64f6cfc8d4ced27a13da64b4aae1de5ba8884 /src/d/d_cursor_hit_check.cpp
parent6feb6a95c6e1b523a31fb1616207c02d63b10cbe (diff)
d_structd -> d_cursor_hit_check
Diffstat (limited to 'src/d/d_cursor_hit_check.cpp')
-rw-r--r--src/d/d_cursor_hit_check.cpp259
1 files changed, 259 insertions, 0 deletions
diff --git a/src/d/d_cursor_hit_check.cpp b/src/d/d_cursor_hit_check.cpp
new file mode 100644
index 00000000..9446db18
--- /dev/null
+++ b/src/d/d_cursor_hit_check.cpp
@@ -0,0 +1,259 @@
+#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_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 "rvl/MTX/mtx.h"
+#include "toBeSorted/d_d3d.h"
+#include "toBeSorted/lyt_related_floats.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, y, 10000.0f);
+ pos.x = (pos.x - get_8057515C()) / get_80575148() * -2.0f - 1.0f;
+ pos.y = (pos.y - get_8057519C()) / get_80575190() * 2.0f - 1.0f;
+ mVec3_c v;
+ d3d::fn_80016B60(v, pos);
+ nw4r::g3d::Camera cam = dStageMgr_c::GetInstance()->getCamera(0);
+ mMtx_c mtx;
+ cam.GetCameraMtx(mtx);
+ PSMTXInverse(mtx, mtx);
+ mVec3_c a;
+ a.x = mtx.m[0][3];
+ a.y = mtx.m[1][3];
+ a.z = mtx.m[2][3];
+ 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<nw4r::lyt::Bounding *>(pane);
+ if (b != nullptr) {
+ mNumBoundings++;
+ }
+
+ for (nw4r::lyt::Pane::ChildList::RevIterator 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<nw4r::lyt::Bounding *>(pane);
+ if (b != nullptr) {
+ (*pEnd)--;
+ (*pEnd)->mpPane = pane;
+ }
+
+ for (nw4r::lyt::Pane::ChildList::RevIterator it = pane->GetChildList()->GetEndReverseIter();
+ it != pane->GetChildList()->GetBeginIter(); ++it) {
+ gatherBoundings(pEnd, &*it);
+ }
+}
+
+mVec2_c &dCursorInterface_c::getCursorPos() {
+ // NONMATCHING - Controller stuff
+ return *(mVec2_c *)nullptr;
+}