summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Roncace <me@caseif.net>2026-02-18 01:58:52 -0500
committerGitHub <noreply@github.com>2026-02-17 22:58:52 -0800
commita790efafc526f79a79fad38186335d222a215cb5 (patch)
tree963dadd351a6aebd60f4a87d03ef32fe3bd10762
parent34ea82dd28e74bb375d0ace2cf6aab94da9de569 (diff)
d_cursor_mng mostly matching (#3101)
-rw-r--r--include/d/d_cc_s.h4
-rw-r--r--include/d/d_cursor_mng.h116
-rw-r--r--include/m_Do/m_Do_graphic.h2
-rw-r--r--include/m_Do/m_Do_lib.h4
-rw-r--r--src/d/d_cc_s.cpp42
-rw-r--r--src/d/d_cursor_mng.cpp385
-rw-r--r--src/m_Do/m_Do_graphic.cpp8
-rw-r--r--src/m_Do/m_Do_lib.cpp20
8 files changed, 581 insertions, 0 deletions
diff --git a/include/d/d_cc_s.h b/include/d/d_cc_s.h
index 2f9b475f70..dbd3c18285 100644
--- a/include/d/d_cc_s.h
+++ b/include/d/d_cc_s.h
@@ -61,6 +61,10 @@ public:
void ChkActor(fopAc_ac_c*);
+#if PLATFORM_WII
+ BOOL ChkLine(cXyz&, cXyz&, f32, fopAc_ac_c**);
+#endif
+
static bool m_mtrl_hit_tbl[64];
// /* 0x0000 */ cCcS mCCcS;
diff --git a/include/d/d_cursor_mng.h b/include/d/d_cursor_mng.h
index 459d747ffa..d8a84eb381 100644
--- a/include/d/d_cursor_mng.h
+++ b/include/d/d_cursor_mng.h
@@ -1,9 +1,125 @@
#ifndef D_CURSOR_MNG_H
#define D_CURSOR_MNG_H
+#include "JSystem/J2DGraph/J2DScreen.h"
+#include "m_Do/m_Do_graphic.h"
#include "m_Re/m_Re_controller_pad.h"
// TODO: putting this here until a more appropriate place is found
extern u8 data_8053a730;
+class dCsr_mng_c {
+ struct csr_c;
+
+ struct node_c : mDoGph_gInf_c::csr_c {
+ BOOL set(u8 i_priority, u8, u16 i_mask);
+
+ /* 0x04 */ u8 m_priority;
+ /* 0x05 */ u8 field_0x05;
+ /* 0x06 */ u16 m_mask;
+ /* 0x08 */ node_c* m_prev;
+ /* 0x0C */ node_c* m_next;
+ /* 0x10 */ int m_actor_id;
+ /* 0x14 */ csr_c* m_csr;
+ /* 0x18 */ node_c* m_pointed_obj;
+ };
+
+ struct obj_c : node_c {
+ };
+
+ struct list_c {
+ list_c() : m_root(NULL) {
+ }
+
+ virtual ~list_c(void) {}
+ void entry(node_c* i_node);
+ node_c* release(node_c* i_node);
+ node_c* release(u16 i_mask);
+ BOOL isEntry(const node_c* i_node) const;
+
+ /* 0x04 */ node_c* m_root;
+ };
+
+ struct bloObj_c {
+ struct paneObj_c {
+ paneObj_c(void) {
+ m_handle = NULL;
+ m_min_x = 0;
+ m_min_y = 0;
+ m_max_x = 0;
+ m_max_y = 0;
+ }
+ virtual ~paneObj_c(void) {}
+
+ /* 0x04 */ J2DPane* m_handle;
+ /* 0x08 */ s16 m_min_x;
+ /* 0x0A */ s16 m_min_y;
+ /* 0x0C */ s16 m_max_x;
+ /* 0x0E */ s16 m_max_y;
+ };
+
+ bloObj_c() {
+ m_panes = new paneObj_c[1];
+ m_screen = 0;
+ }
+
+ virtual ~bloObj_c(void);
+ virtual u32 signature(void) const {
+ return 0x626c6f20;
+ }
+ virtual BOOL isInside(s16 i_x, s16 i_y);
+ BOOL create(J2DScreen* i_screen, u16 i_mask, u8 i_priority, u8);
+ void calc(void);
+ void calcPaneObjNum(J2DPane* i_pane);
+ void createPaneObj(paneObj_c** i_panes, J2DPane* i_pane);
+
+ /* 0x04 */ u8 field_0x04[0x10 - 0x4];
+ /* 0x10 */ J2DScreen* m_screen;
+ /* 0x14 */ paneObj_c* m_panes;
+ /* 0x18 */ u16 m_pane_num;
+ /* 0x1A */ u8 m_is_calc;
+ /* 0x1C */ J2DPane* m_pane_handle;
+ };
+
+ struct ccObj_c : node_c {
+ virtual ~ccObj_c(void);
+ virtual int signature(void) const {
+ return 'cc ';
+ }
+ virtual BOOL isInside(s16, s16);
+ void set(u16, u8, u8);
+ };
+
+ struct csr_c : node_c {
+ virtual ~csr_c(void);
+ BOOL set(mDoGph_gInf_c::csr_c* i_csr, u16, u8, u8);
+ };
+
+private:
+ dCsr_mng_c() : is_csr_on(true) {
+ }
+
+ void update_(void);
+ void releaseCsr_(csr_c* i_csr);
+ void insideObjReleaseCheck_(void);
+
+public:
+ static void create(void);
+ static void update(void);
+ static void entryCsr(csr_c* i_csr);
+ static void releaseCsr(csr_c* i_csr);
+ static void entryObj(obj_c* i_obj);
+ static void releaseObj(obj_c* i_obj);
+ static void releaseObj(u16 i_mask);
+ static void onCsr(void);
+ static void offCsr(void);
+
+ static dCsr_mng_c* m_myObj;
+
+private:
+ /* 0x00 */ list_c m_csr_list;
+ /* 0x08 */ list_c m_obj_list;
+ /* 0x10 */ bool is_csr_on;
+};
+
#endif /* D_CURSOR_MNG_H */
diff --git a/include/m_Do/m_Do_graphic.h b/include/m_Do/m_Do_graphic.h
index e584fcf7b1..a00d62dbe8 100644
--- a/include/m_Do/m_Do_graphic.h
+++ b/include/m_Do/m_Do_graphic.h
@@ -69,6 +69,8 @@ public:
};
static void entryBaseCsr(csr_c*);
+ static void releaseCsr(void);
+ static void entryCsr(csr_c*);
#endif
static void create();
diff --git a/include/m_Do/m_Do_lib.h b/include/m_Do/m_Do_lib.h
index 31b5b5f700..bb4b1e6e2e 100644
--- a/include/m_Do/m_Do_lib.h
+++ b/include/m_Do/m_Do_lib.h
@@ -42,4 +42,8 @@ u32 mDoLib_setResTimgObj(ResTIMG const* res, GXTexObj* o_texObj, u32 tlut_name,
GXTlutObj* o_tlutObj);
void mDoLib_pos2camera(Vec* src, Vec* dst);
+#if PLATFORM_WII
+void mDoLib_2Dto3D(f32, f32, f32, Vec*);
+#endif
+
#endif /* M_DO_M_DO_LIB_H */
diff --git a/src/d/d_cc_s.cpp b/src/d/d_cc_s.cpp
index f7e275dea4..ccb8501542 100644
--- a/src/d/d_cc_s.cpp
+++ b/src/d/d_cc_s.cpp
@@ -536,6 +536,48 @@ bool dCcS::ChkCamera(cXyz& param_0, cXyz& param_1, f32 param_2, fopAc_ac_c* para
return false;
}
+#if PLATFORM_WII
+BOOL dCcS::ChkLine(cXyz& i_p_start, cXyz& i_p_end, f32 i_radius, fopAc_ac_c** o_actor) {
+ u16 obj_co_count = mObjCoCount;
+ if (obj_co_count == 0) {
+ return 0;
+ }
+ cCcD_Obj** max_obj_pp = &mpObjCo[mObjCoCount];
+ cCcD_CpsAttr cps_attr;
+ cps_attr.Set(i_p_start, i_p_end, i_radius);
+ cps_attr.CalcAabBox();
+ *o_actor = NULL;
+ f32 z_max = -FLT_MAX;
+ cCcD_DivideInfo sp18;
+ mDivideArea.CalcDivideInfoOverArea(&sp18, cps_attr.mAab);
+ cCcD_Obj** obj_pp = mpObjCo;
+ while (obj_pp < max_obj_pp) {
+ cCcD_Obj* obj_p = *obj_pp;
+ if (obj_p->GetObjCo().getSPrm() & 1) {
+ fopAc_ac_c* temp_r31 = dComIfGp_getPlayer(0);
+ if (obj_p->GetAc() != temp_r31 && (*obj_pp)->GetDivideInfo().Chk(sp18) != 0) {
+ f32 sp8;
+ if ((*obj_pp)->GetShapeAttr()->CrossCo(cps_attr, &sp8) != 0) {
+ fopAc_ac_c* actor = (*obj_pp)->GetAc();
+ if (actor != NULL &&
+ actor->attention_info.flags & (fopAc_AttnFlag_LOCK_e | fopAc_AttnFlag_BATTLE_e)) {
+ Vec spC;
+ PSMTXMultVec(dComIfGd_getViewMtx(), &actor->current.pos, &spC);
+ if (spC.z < 0.0f && spC.z > z_max) {
+ *o_actor = actor;
+ z_max = spC.z;
+ }
+ }
+ }
+ }
+ }
+ obj_pp++;
+ }
+
+ return *o_actor != NULL;
+}
+#endif
+
bool dCcS::chkCameraPoint(cXyz const& param_0, cCcD_ShapeAttr::Shape* param_1, fopAc_ac_c* param_2,
fopAc_ac_c* param_3) {
if (mObjCoCount == 0) {
diff --git a/src/d/d_cursor_mng.cpp b/src/d/d_cursor_mng.cpp
index 8b39195217..223d01bffc 100644
--- a/src/d/d_cursor_mng.cpp
+++ b/src/d/d_cursor_mng.cpp
@@ -1,4 +1,389 @@
+#include "d/dolzel.h" // IWYU pragma: keep
+
#include "d/d_cursor_mng.h"
+#include "d/d_com_inf_game.h"
+
+dCsr_mng_c* dCsr_mng_c::m_myObj;
+
// TODO: putting this here until a more appropriate place is found
u8 data_8053a730;
+
+void dCsr_mng_c::update_(void) {
+ BOOL is_valid = FALSE;
+
+ if (dComIfGs_getOptPointer()) {
+ mReCPd::enableDpd(0);
+ is_valid = mReCPd::chkDpdValid(NULL);
+ } else {
+ mReCPd::disableDpd(0);
+ }
+
+ if (is_csr_on == 0) {
+ mDoGph_gInf_c::entryCsr(NULL);
+ node_c* cur_node = m_csr_list.m_root;
+ while (cur_node != NULL) {
+ cur_node->m_pointed_obj = 0;
+ cur_node = cur_node->m_next;
+ }
+
+ return;
+ }
+
+ mDoGph_gInf_c::releaseCsr();
+ Vec2* pos = &mReCPd::getDpd2DPos(0);
+ int x = pos->x;
+ int y = pos->y;
+
+ node_c* cur_node = m_csr_list.m_root;
+ mDoGph_gInf_c::csr_c* csr = NULL;
+ u16 last_mask = 1;
+ while (cur_node != NULL) {
+ cur_node->m_pointed_obj = NULL;
+
+ u16 cur_mask = cur_node->m_mask;
+ if (!g_dComIfG_gameInfo.play.mItemInfo.mPauseFlag || (cur_node->m_mask & 0x200) == 0) {
+ if (csr == NULL) {
+ csr = cur_node->m_csr;
+ }
+
+ if (is_valid && last_mask != 0) {
+ last_mask = cur_mask;
+ if (last_mask != 0) {
+ node_c* cur_node_2 = m_obj_list.m_root;
+ while (cur_node_2 != NULL) {
+ if ((cur_mask & cur_node_2->m_mask) != 0 &&
+ ((bloObj_c*)cur_node_2)->isInside(x, y))
+ {
+ cur_node->m_pointed_obj = cur_node_2;
+ }
+
+ cur_node_2 = cur_node_2->m_next;
+ }
+ }
+ }
+ }
+
+ cur_node = cur_node->m_next;
+ }
+
+ if (!dComIfGs_getOptPointer()) {
+ if (csr != NULL) {
+ if (csr->isPointer()) {
+ csr = NULL;
+ }
+ }
+ } else if (csr == NULL) {
+ return;
+ }
+
+ mDoGph_gInf_c::entryCsr(csr);
+}
+
+void dCsr_mng_c::releaseCsr_(csr_c* i_csr) {
+ mDoGph_gInf_c::csr_c* temp_r5 = i_csr->m_csr;
+ i_csr->m_pointed_obj = 0;
+ if (temp_r5 != NULL && temp_r5 == mDoGph_gInf_c::m_csr) {
+ mDoGph_gInf_c::entryCsr(NULL);
+ }
+ m_csr_list.release(i_csr);
+}
+
+void dCsr_mng_c::insideObjReleaseCheck_(void) {
+ node_c* cur_node = m_csr_list.m_root;
+ while (cur_node != NULL) {
+ if (!m_obj_list.isEntry(cur_node->m_pointed_obj)) {
+ cur_node->m_pointed_obj = NULL;
+ }
+ cur_node = cur_node->m_next;
+ }
+}
+
+void dCsr_mng_c::create(void) {
+ dCsr_mng_c* mng = new dCsr_mng_c();
+ m_myObj = mng;
+}
+
+void dCsr_mng_c::update(void) {
+ m_myObj->update_();
+}
+
+void dCsr_mng_c::entryCsr(csr_c* i_csr) {
+ dCsr_mng_c* mng = m_myObj;
+ mng->m_csr_list.entry(i_csr);
+ mng->is_csr_on = true;
+}
+
+void dCsr_mng_c::releaseCsr(csr_c* i_csr) {
+ m_myObj->releaseCsr_(i_csr);
+}
+
+void dCsr_mng_c::entryObj(obj_c* i_obj) {
+ m_myObj->m_obj_list.entry(i_obj);
+}
+
+void dCsr_mng_c::releaseObj(obj_c* i_obj) {
+ m_myObj->m_obj_list.release(i_obj);
+ m_myObj->insideObjReleaseCheck_();
+}
+
+void dCsr_mng_c::releaseObj(u16 param_0) {
+ m_myObj->m_obj_list.release(param_0);
+ m_myObj->insideObjReleaseCheck_();
+}
+
+void dCsr_mng_c::onCsr(void) {
+ m_myObj->is_csr_on = true;
+}
+
+void dCsr_mng_c::offCsr(void) {
+ m_myObj->is_csr_on = false;
+}
+
+BOOL dCsr_mng_c::node_c::set(u8 i_priority, u8 param_1, u16 i_mask) {
+ BOOL has_relatives = FALSE;
+ if (m_prev != NULL || m_next != NULL) {
+ has_relatives = TRUE;
+ }
+ if (has_relatives) {
+ return FALSE;
+ }
+
+ m_priority = i_priority;
+ field_0x05 = param_1;
+ m_mask = i_mask;
+
+ return TRUE;
+}
+
+void dCsr_mng_c::list_c::entry(node_c* i_node) {
+ BOOL has_relatives = FALSE;
+ if (i_node->m_prev != NULL || i_node->m_next != NULL) {
+ has_relatives = TRUE;
+ }
+ if (has_relatives) {
+ return;
+ }
+
+ node_c* cur_node = m_root;
+ if (cur_node == NULL) {
+ m_root = i_node;
+ return;
+ }
+
+ while (i_node->m_priority > cur_node->m_priority) {
+ node_c* next = cur_node->m_next;
+ if (next == NULL) {
+ cur_node->m_next = i_node;
+ i_node->m_prev = cur_node;
+ i_node->m_next = NULL;
+ return;
+ }
+ cur_node = next;
+ }
+
+ node_c* prev = cur_node->m_prev;
+ if (prev == NULL) {
+ m_root = i_node;
+ } else {
+ i_node->m_prev = prev;
+ prev->m_next = i_node;
+ }
+ i_node->m_next = cur_node;
+ cur_node->m_prev = i_node;
+}
+
+dCsr_mng_c::node_c* dCsr_mng_c::list_c::release(node_c* i_node) {
+ node_c *next;
+ node_c *prev;
+
+ if (!isEntry(i_node)) {
+ return NULL;
+ }
+
+ prev = i_node->m_prev;
+ next = i_node->m_next;
+ if (prev != NULL) {
+ prev->m_next = next;
+ i_node->m_prev = NULL;
+ } else {
+ m_root = next;
+ }
+
+ if (next != NULL) {
+ next->m_prev = prev;
+ i_node->m_next = NULL;
+ }
+
+ return next;
+}
+
+dCsr_mng_c::node_c* dCsr_mng_c::list_c::release(u16 i_mask) {
+ node_c* cur_node = m_root;
+ while (cur_node != NULL) {
+ if (cur_node->m_mask & i_mask) {
+ cur_node = release(cur_node);
+ } else {
+ cur_node = cur_node->m_next;
+ }
+ }
+}
+
+BOOL dCsr_mng_c::list_c::isEntry(const node_c* i_node) const {
+ node_c* cur_node = m_root;
+ while (cur_node != NULL) {
+ if (cur_node == i_node) {
+ return TRUE;
+ }
+ cur_node = cur_node->m_next;
+ }
+ return FALSE;
+}
+
+dCsr_mng_c::bloObj_c::~bloObj_c() {
+ if (m_panes != NULL) {
+ delete[] m_panes;
+ m_panes = NULL;
+ }
+ m_screen = NULL;
+}
+
+BOOL dCsr_mng_c::bloObj_c::isInside(s16 i_x, s16 i_y) {
+ if (mReCPd::chkSwingBlock(0) == 0) {
+ paneObj_c* pane = m_panes;
+ for (u16 i = 0; i < m_pane_num; pane++, i++) {
+ if (pane->m_min_x <= i_x && i_x <= pane->m_max_x &&
+ pane->m_min_y <= i_y && i_y <= pane->m_max_y) {
+ J2DPane* pane_handle = pane->m_handle;
+ m_pane_handle = pane_handle;
+ if (pane_handle->mAlpha != 0 && pane_handle->mVisible) {
+ return 1;
+ }
+ }
+ }
+ }
+
+ m_pane_handle = NULL;
+ return 0;
+}
+
+BOOL dCsr_mng_c::bloObj_c::create(J2DScreen* i_screen, u16 i_mask, u8 i_priority, u8 param_3) {
+ if (!((node_c*)this)->set(i_priority, param_3, i_mask)) {
+ return FALSE;
+ }
+ m_screen = i_screen;
+ m_pane_num = 0;
+ calcPaneObjNum(i_screen);
+ m_panes = new paneObj_c[m_pane_num];
+ paneObj_c* sp08 = m_panes + m_pane_num;
+ createPaneObj(&sp08, m_screen);
+ return TRUE;
+}
+
+void dCsr_mng_c::bloObj_c::calc(void) {
+ if (m_is_calc == 0) {
+ paneObj_c* pane_obj = m_panes;
+ u32 var_r30 = 0;
+ while ((u16)var_r30 < m_pane_num) {
+ J2DPane* pane = pane_obj->m_handle;
+ Vec sp20 = pane->getGlbVtx(0);
+ pane_obj->m_min_x = sp20.x;
+ pane_obj->m_min_y = sp20.y;
+ sp20 = pane->getGlbVtx(3);
+ var_r30++;
+ pane_obj->m_max_x = sp20.x;
+ pane_obj->m_max_y = sp20.y;
+ pane_obj++;
+ }
+ m_is_calc = 1;
+ }
+}
+
+char* nullSkip(char* buf) {
+ char* cursor = buf;
+ while (*cursor == 0) {
+ cursor += 1;
+ }
+ return cursor;
+}
+
+void dCsr_mng_c::bloObj_c::calcPaneObjNum(J2DPane* i_pane) {
+ u64 info_tag = i_pane->mInfoTag;
+ char* info_start = nullSkip((char*)&info_tag);
+ if (info_start[0] == 0x4E && info_start[1] == 0x5F) {
+ m_pane_num += 1;
+ }
+
+ JSUTreeIterator<J2DPane> iter = i_pane->getPaneTree()->getFirstChild();
+ while (iter != NULL) {
+ calcPaneObjNum(*iter);
+ ++iter;
+ }
+}
+
+void dCsr_mng_c::bloObj_c::createPaneObj(paneObj_c** i_panes, J2DPane* i_pane) {
+ u64 info_tag = i_pane->mInfoTag;
+ char* info_start = nullSkip((char*)&info_tag);
+ if (info_start[0] == 0x4E && info_start[1] == 0x5F) {
+ paneObj_c* pane = *i_panes;
+ *i_panes -= 1;
+ pane->m_handle = i_pane;
+ }
+
+ JSUTreeIterator<J2DPane> iter = i_pane->getPaneTree()->getFirstChild();
+ while (iter != NULL) {
+ createPaneObj(i_panes, *iter);
+ ++iter;
+ }
+}
+
+BOOL dCsr_mng_c::ccObj_c::isInside(s16 param_0, s16 param_1) {
+ if (dComIfGd_getView() == NULL) {
+ return 0;
+ }
+
+ f32 x = (param_0 - mDoGph_gInf_c::getMinXF()) / mDoGph_gInf_c::getWidthF() * 2.0f - 1.0f;
+ f32 y = (param_1 - mDoGph_gInf_c::getMinYF()) / mDoGph_gInf_c::getHeightF() * 2.0f - 1.0f;
+ cXyz sp18;
+ mDoLib_2Dto3D(x, y, 1000.0f, &sp18);
+ cXyz sp0C;
+ PSMTXMultVec(dComIfGd_getInvViewMtx(), &cXyz::Zero, &sp0C);
+ dBgS_LinChk linChk;
+ linChk.Set(&sp0C, &sp18, NULL);
+ if (dComIfG_Bgsp().LineCross(&linChk)) {
+ sp18 = linChk.GetCross();
+ }
+
+ s32 actor_id;
+ fopAc_ac_c* actor_p = NULL;
+ dComIfG_Ccsp()->ChkLine(sp0C, sp18, 15.0f, &actor_p);
+ if (actor_p != NULL) {
+ actor_id = actor_p->base.base.id;
+ } else {
+ actor_id = fpcM_ERROR_PROCESS_ID_e;
+ }
+ m_actor_id = actor_id;
+ return actor_p != 0;
+}
+
+void dCsr_mng_c::ccObj_c::set(u16 param_0, u8 param_1, u8 param_2) {
+ node_c::set(param_1, param_2, param_0);
+}
+
+dCsr_mng_c::csr_c::~csr_c() {
+ if (m_csr == mDoGph_gInf_c::m_csr) {
+ mDoGph_gInf_c::releaseCsr();
+ }
+}
+
+BOOL dCsr_mng_c::csr_c::set(mDoGph_gInf_c::csr_c* i_csr, u16 param_1, u8 param_2, u8 param_3) {
+ if (!node_c::set(param_2, param_3, param_1)) {
+ return FALSE;
+ }
+ m_csr = i_csr;
+ return TRUE;
+}
+
+dCsr_mng_c::ccObj_c::~ccObj_c() {
+ // empty function
+}
diff --git a/src/m_Do/m_Do_graphic.cpp b/src/m_Do/m_Do_graphic.cpp
index 1708067ac4..08842cd792 100644
--- a/src/m_Do/m_Do_graphic.cpp
+++ b/src/m_Do/m_Do_graphic.cpp
@@ -670,6 +670,14 @@ void mDoGph_gInf_c::entryBaseCsr(mDoGph_gInf_c::csr_c* i_entry) {
m_baseCsr = i_entry;
m_csr = i_entry;
}
+
+void mDoGph_gInf_c::entryCsr(mDoGph_gInf_c::csr_c* i_csr) {
+ m_csr = i_csr;
+}
+
+void mDoGph_gInf_c::releaseCsr(void) {
+ m_csr = m_baseCsr;
+}
#endif
void mDoGph_BlankingON() {}
diff --git a/src/m_Do/m_Do_lib.cpp b/src/m_Do/m_Do_lib.cpp
index 8876beb12d..292a10869a 100644
--- a/src/m_Do/m_Do_lib.cpp
+++ b/src/m_Do/m_Do_lib.cpp
@@ -118,6 +118,26 @@ void mDoLib_pos2camera(Vec* src, Vec* dst) {
cMtx_multVec(dComIfGd_getView()->viewMtx, src, dst);
}
+#if PLATFORM_WII
+void mDoLib_2Dto3D(f32 i_x, f32 i_y, f32 i_z, Vec* o_dst) {
+ if (dComIfGd_getView() == NULL) {
+ o_dst->x = 0.0f;
+ o_dst->y = 0.0f;
+ o_dst->z = 0.0f;
+ return;
+ }
+
+ f32 fovy = dComIfGd_getView()->fovy;
+ f32 aspect = dComIfGd_getView()->aspect;
+ f32 temp_f3 = tan(DEG_TO_RAD(0.5f * fovy));
+ Vec sp8;
+ sp8.x = (-i_x * i_z) * (temp_f3 * aspect);
+ sp8.y = (i_y * -i_z) * temp_f3;
+ sp8.z = -i_z;
+ PSMTXMultVec(dComIfGd_getInvViewMtx(), &sp8, o_dst);
+}
+#endif
+
static void dummy() {
std::tan(0.0f);
J3DAlphaComp* alphaComp = NULL;