diff --git a/include/d/d_tree.h b/include/d/d_tree.h index a09c41e55..eae4824dd 100644 --- a/include/d/d_tree.h +++ b/include/d/d_tree.h @@ -25,19 +25,19 @@ public: void WorkCo(fopAc_ac_c*, u32, int); void WorkAt_NoCutAnim(fopAc_ac_c*, u32, int, dCcMassS_HitInf*, cCcD_Obj*); void WorkAt(fopAc_ac_c*, u32, int, dCcMassS_HitInf*); - void hitCheck(fopAc_ac_c*, int); + BOOL hitCheck(fopAc_ac_c*, int); void animation(int); - /* 0x000 */ u8 field_0x000; + /* 0x000 */ u8 mState; /* 0x001 */ u8 field_0x001; - /* 0x002 */ u8 mAnimIdx; - /* 0x003 */ s8 field_0x003; + /* 0x002 */ s8 mAnimIdx; + /* 0x003 */ u8 field_0x003; /* 0x004 */ cXyz mPos; /* 0x010 */ Mtx field_0x010; /* 0x040 */ Mtx field_0x040; /* 0x070 */ Mtx field_0x070; /* 0x0A0 */ Mtx mShadowMtx; - /* 0x0D0 */ u8 field_0x0D0[0x100 - 0x0D0]; + /* 0x0D0 */ Mtx field_0x0d0; /* 0x100 */ dTree_data_c* mpNext; static dPa_smokeEcallBack mSmokeEcallback; @@ -48,10 +48,10 @@ public: ~dTree_anm_c(); dTree_anm_c(); - /* 0x00 */ u8 field_0x00[0x02 - 0x00]; + /* 0x00 */ u8 mState; /* 0x02 */ s16 field_0x02; /* 0x04 */ s16 field_0x04; - /* 0x06 */ u8 field_0x06[0x08 - 0x06]; + /* 0x06 */ s16 field_0x06; /* 0x08 */ s16 field_0x08; /* 0x0A */ s16 field_0x0a; /* 0x0C */ f32 mAnimTimer; @@ -61,7 +61,7 @@ public: /* 0x1C */ f32 field_0x1c; /* 0x20 */ f32 field_0x20; /* 0x24 */ Mtx field_0x24; - /* 0x54 */ u8 field_0x54[0x84 - 0x54]; + /* 0x54 */ Mtx field_0x54; }; class dTree_room_c { @@ -71,7 +71,9 @@ public: void newData(dTree_data_c*); void deleteData(); - /* 0x0 */ dTree_data_c* mpHead; + dTree_data_c* getData() { return mpData; } + + /* 0x0 */ dTree_data_c* mpData; }; class dTree_packet_c : public J3DPacket { @@ -81,22 +83,36 @@ public: void calc(); void update(); void setData(dTree_data_c*, int, cXyz&, u8, int); - void newData(cXyz&, u8, int); - void newAnm(s16); + dTree_data_c* newData(cXyz&, u8, int); + s32 newAnm(s16); void setAnm(int, s16); void deleteRoom(s32 roomNo) { mRoom[roomNo].deleteData(); } + void deleteAnm(int idx) { mAnm[idx].mState = 0; } + + dTree_anm_c* getAnm() { return mAnm; } + dTree_anm_c& getAnm(int idx) { return mAnm[idx]; } + dTree_data_c* getData() { return mData; } + + void setPlayerCutFlg(int i_flg) { mPlayerCutFlg = i_flg; } + void setPlayerSwordTop(cXyz& i_pos) { mPlayerSwordTop = i_pos; } + void setPlayerSwordMoveAngY(s16 i_ang) { mPlayerSwordMoveAngY = i_ang; } + cXyz& getPlayerSwordTop() { return mPlayerSwordTop; } + void setPlayerSwordAngY(s16 i_ang) { mPlayerSwordAngY = i_ang;} + s16 getPlayerSwordMoveAngY() { return mPlayerSwordMoveAngY; } + + int getNum() {} virtual void draw(); virtual ~dTree_packet_c(); - /* 0x0010 */ s16 field_0x0010; + /* 0x0010 */ u16 mNextIdx; /* 0x0014 */ dTree_data_c mData[64]; /* 0x4114 */ dTree_anm_c mAnm[72]; /* 0x6634 */ dTree_room_c mRoom[64]; - /* 0x6734 */ u8 field_0x6734; - /* 0x6736 */ s16 field_0x6736; - /* 0x6738 */ s16 field_0x6738; - /* 0x673C */ cXyz field_0x673c; + /* 0x6734 */ u8 mPlayerCutFlg; + /* 0x6736 */ s16 mPlayerSwordAngY; + /* 0x6738 */ s16 mPlayerSwordMoveAngY; + /* 0x673C */ cXyz mPlayerSwordTop; }; #endif /* D_TREE_H */ diff --git a/src/d/d_tree.cpp b/src/d/d_tree.cpp index 3ababa53c..b0512b531 100644 --- a/src/d/d_tree.cpp +++ b/src/d/d_tree.cpp @@ -1,12 +1,10 @@ -// -// Generated by dtk -// Translation Unit: d_tree.cpp -// - #include "d/dolzel.h" // IWYU pragma: keep #include "d/d_tree.h" -#include "dolphin/types.h" - +#include "d/actor/d_a_player.h" +#include "dolphin/gf/GF.h" +#include "SSystem/SComponent/c_counter.h" +#include "m_Do/m_Do_lib.h" +#include "f_op/f_op_overlap_mng.h" #include "assets/l_Txa_swood_aTEX.h" const u16 l_Txa_swood_aTEX__width = 64; @@ -163,61 +161,299 @@ g_dTree_shadowMatDL(l_Txa_kage_32TEX); const u32 g_dTree_Oba_kage_32DL_SIZE = sizeof(g_dTree_Oba_kage_32DL); const u32 g_dTree_shadowMatDL_SIZE = sizeof(g_dTree_shadowMatDL); -dPa_smokeEcallBack dTree_data_c::mSmokeEcallback(1, 1, 0, 1); +static bool l_CutSoundFlag; /* 800787BC-80078960 .text WorkCo__12dTree_data_cFP10fopAc_ac_cUli */ -void dTree_data_c::WorkCo(fopAc_ac_c*, u32, int) { - /* Nonmatching */ +// NONMATCHING - small float regalloc +void dTree_data_c::WorkCo(fopAc_ac_c* i_actor, u32, int) { + if (field_0x001) { + return; + } + + if (mAnimIdx < 8) { + dTree_anm_c& anm = dComIfGp_getTree()->getAnm(mAnimIdx); + s32 newAnm = dComIfGp_getTree()->newAnm(anm.field_0x02); + if (newAnm < 0) { + return; + } + mAnimIdx = newAnm; + } + + cXyz vel; + vel.x = mPos.x - i_actor->current.pos.x; + vel.y = mPos.y - i_actor->current.pos.y; + vel.z = mPos.z - i_actor->current.pos.z; + vel.abs2XZ(); + + dTree_anm_c& anm = dComIfGp_getTree()->getAnm(mAnimIdx); + + s16 angle = cM_atan2s(vel.x, vel.z); + f32 cos = cM_scos(i_actor->current.angle.y - angle); + if (cos > 0.9f && fopAcM_GetName(i_actor) == fpcNm_PLAYER_e) { + ((daPy_py_c*)i_actor)->onFrollCrashFlg(7); + } + + f32 var_f1 = cLib_maxLimit(std::abs(i_actor->speedF * 50.0f), 4000.0f); + if (std::fabsf(anm.mAnimTimer) < std::fabsf(var_f1 * cos)) { + anm.mAnimTimer = var_f1 * cos; + anm.field_0x0a = angle; + } } /* 80078960-80078CC0 .text WorkAt_NoCutAnim__12dTree_data_cFP10fopAc_ac_cUliP15dCcMassS_HitInfP8cCcD_Obj */ -void dTree_data_c::WorkAt_NoCutAnim(fopAc_ac_c*, u32, int, dCcMassS_HitInf*, cCcD_Obj*) { - /* Nonmatching */ +void dTree_data_c::WorkAt_NoCutAnim(fopAc_ac_c* i_actor, u32, int i_roomNo, dCcMassS_HitInf* i_hitInf, cCcD_Obj* i_hitObj) { + if (field_0x001) { + return; + } + + if (mAnimIdx < 8) { + dTree_anm_c& anm = dComIfGp_getTree()->getAnm(mAnimIdx); + s32 newAnm = dComIfGp_getTree()->newAnm(anm.field_0x02); + if (newAnm < 0) { + return; + } + mAnimIdx = newAnm; + } + + dCcD_GObjInf* hitObjInf = dCcD_GetGObjInf(i_hitObj); + cXyz vel = *hitObjInf->GetAtVecP(); + f32 mag = vel.absXZ(); + + if (cM3d_IsZero(mag)) { + if (fopAcM_GetName(i_actor) == fpcNm_PLAYER_e) { + vel.x = mPos.x - i_actor->current.pos.x; + vel.y = mPos.y - i_actor->current.pos.y; + vel.z = mPos.z - i_actor->current.pos.z; + mag = vel.absXZ(); + } else if (fopAcM_GetName(i_actor) == fpcNm_BOMB_e || fopAcM_GetName(i_actor) == fpcNm_Bomb2_e) { + vel.x = mPos.x - i_actor->current.pos.x; + vel.y = mPos.y - i_actor->current.pos.y; + vel.z = mPos.z - i_actor->current.pos.z; + mag = 200.0f - vel.absXZ(); + if (mag < 0.0f) { + mag = 0.0f; + } + + VECNormalize(&vel, &vel); + VECScale(&vel, &vel, mag); + } + } + + dTree_anm_c& anm = dComIfGp_getTree()->getAnm(mAnimIdx); + + s16 var_r30 = cM_atan2s(vel.x, vel.z); + f32 var_f0 = mag * 50.0f; + f32 anm_timer = var_f0 > 4000.0f ? 4000.0f : var_f0; + if (std::fabsf(anm.mAnimTimer) < std::fabsf(anm_timer)) { + anm.mAnimTimer = anm_timer; + anm.field_0x0a = var_r30; + } } /* 80078CC0-80078ED4 .text WorkAt__12dTree_data_cFP10fopAc_ac_cUliP15dCcMassS_HitInf */ -void dTree_data_c::WorkAt(fopAc_ac_c*, u32, int, dCcMassS_HitInf*) { - /* Nonmatching */ +void dTree_data_c::WorkAt(fopAc_ac_c* i_actor, u32 param_1, int i_roomNo, dCcMassS_HitInf* i_hitInf) { + cCcD_Obj* hitObj = i_hitInf->GetAtHitObj(); + if (hitObj != NULL && (hitObj->ChkAtType(AT_TYPE_WIND) || + hitObj->ChkAtType(AT_TYPE_BOMB) || + hitObj->ChkAtType(AT_TYPE_FIRE) || + hitObj->ChkAtType(AT_TYPE_NORMAL_ARROW) || + hitObj->ChkAtType(AT_TYPE_FIRE_ARROW) || + hitObj->ChkAtType(AT_TYPE_ICE_ARROW) || + hitObj->ChkAtType(AT_TYPE_LIGHT_ARROW) || + hitObj->ChkAtType(AT_TYPE_HOOKSHOT))) + { + WorkAt_NoCutAnim(i_actor, param_1, i_roomNo, i_hitInf, hitObj); + } else { + cXyz vel; + vel.x = mPos.x - i_actor->current.pos.x; + vel.y = mPos.y - i_actor->current.pos.y; + vel.z = mPos.z - i_actor->current.pos.z; + vel.abs2XZ(); + + s16 var_r30 = cM_atan2s(vel.x, vel.z); + + if (field_0x001) { + return; + } + + if (mAnimIdx < 8) { + dTree_anm_c& anm = dComIfGp_getTree()->getAnm(mAnimIdx); + s32 newAnm = dComIfGp_getTree()->newAnm(anm.field_0x02); + if (newAnm < 0) { + return; + } + mAnimIdx = newAnm; + } + + field_0x001 = 1; + dTree_packet_c* tree = dComIfGp_getTree(); + dTree_anm_c& anm = tree->getAnm(mAnimIdx); + anm.field_0x0a = tree->mPlayerSwordMoveAngY; + anm.mAnimTimer = 0.0f; + anm.field_0x10 = -2.0f; + anm.field_0x14 = 12.0f; + + Mtx m; + MTXScale(m, 0.4f, 1.0f, 0.4f); + MTXConcat(mShadowMtx, m, mShadowMtx); + + if (!l_CutSoundFlag) { + l_CutSoundFlag = true; + mDoAud_seStart(JA_SE_OBJ_CUT_TREE_DOWN, &mPos, 0, dComIfGp_getReverb(i_roomNo)); + } + + dComIfGp_getVibration().StartShock(4, -0x21, cXyz(0.0f, 1.0f, 0.0f)); + } } /* 80078ED4-80078FA8 .text hitCheck__12dTree_data_cFP10fopAc_ac_ci */ -void dTree_data_c::hitCheck(fopAc_ac_c*, int) { - /* Nonmatching */ +BOOL dTree_data_c::hitCheck(fopAc_ac_c*, int i_roomNo) { + fopAc_ac_c* actor = NULL; + dCcMassS_HitInf hitInf; + u32 ret = dComIfG_Ccsp()->ChkMass(&mPos, &actor, &hitInf); + + if (ret == 0 || actor == NULL) { + return 0; + } + + if (ret & 2) + WorkCo(actor, ret, i_roomNo); + if (ret & 1) + WorkAt(actor, ret, i_roomNo, &hitInf); + + return 0; } /* 80078FA8-8007945C .text animation__12dTree_data_cFi */ -void dTree_data_c::animation(int) { - /* Nonmatching */ +// NONMATCHING - small float math issues +void dTree_data_c::animation(int i_roomNo) { + dTree_anm_c& anm = dComIfGp_getTree()->getAnm(mAnimIdx); + + if (!field_0x001) { + anm.mAnimTimer += anm.field_0x08 * -1.0f; + anm.mAnimTimer *= 0.9f; + anm.field_0x08 += (s16)anm.mAnimTimer; + + if (anm.field_0x08 * anm.mAnimTimer >= 0.0f) { + f32 var_f0 = std::fabsf(anm.mAnimTimer); + if (var_f0 < 40.0f) { + anm.field_0x08 = 0; + anm.mAnimTimer = 0.0f; + + int idx = (anm.field_0x02 >> 13) & 7; + dTree_anm_c& anm2 = dComIfGp_getTree()->getAnm(idx); + if (cLib_chaseAngleS(&anm.field_0x04, anm2.field_0x04, 800) + && cLib_chaseAngleS(&anm.field_0x06, anm2.field_0x06, 800)) + { + dComIfGp_getTree()->deleteAnm(mAnimIdx); + mAnimIdx = idx; + } + } else if (var_f0 > 400.0f) { + cXyz pos(mPos.x, mPos.y + 203.0f, mPos.z); + dComIfGp_particle_setSimple(dPa_name::ID_IT_JN_O_HAPPA01, &pos); + mDoAud_seStart(JA_SE_OBJ_TREE_SWING, &mPos, 0, dComIfGp_getReverb(i_roomNo)); + } + } + + anm.field_0x04 = anm.field_0x08; + } else { + f32 var_f0 = anm.field_0x10 * cM_ssin(anm.field_0x0a); + f32 var_f0_2 = anm.field_0x10 * cM_scos(anm.field_0x0a); + + anm.field_0x14 += -2.0f; + if (anm.field_0x14 < -40.0f) { + anm.field_0x14 = -40.0f; + } + + anm.field_0x18 += var_f0; + anm.field_0x20 += var_f0_2; + anm.field_0x1c += anm.field_0x14; + + if (anm.field_0x1c < -5.0f) { + anm.field_0x1c = -5.0f; + anm.field_0x10 = 0.0f; + } + + cLib_chaseF(&anm.mAnimTimer, 1500.0f, 40.0f); + + if (anm.field_0x04 != 13600) { + if (cLib_chaseAngleS(&anm.field_0x04, 13600, anm.mAnimTimer)) { + static cXyz l_particleOffset(0.0f, 150.0f, 0.0f); + static cXyz l_scale(1.6f, 1.6f, 1.6f); + + cXyz sp18; + MTXMultVec(anm.field_0x24, &l_particleOffset, &sp18); + + JPABaseEmitter* emitter = dComIfGp_particle_setToon(0x2022, &sp18, NULL, &l_scale, 0xAA, &mSmokeEcallback, i_roomNo, NULL, NULL, NULL); + if (emitter != NULL) { + emitter->setRate(20.0f); + emitter->setSpread(1.0f); + emitter->setDirectionalSpeed(15.0f); + emitter->setLifeTime(60); + emitter->setMaxFrame(1); + } + + sp18.y -= 50.0f; + dComIfGp_particle_set(0x3df, &sp18); + } + } else if (anm.field_0x10 == 0.0f) { + mState |= 8; + MTXCopy(anm.field_0x24, field_0x070); + field_0x070[0][3] = mPos.x + anm.field_0x18; + field_0x070[1][3] = mPos.y + anm.field_0x1c; + field_0x070[2][3] = mPos.z + anm.field_0x20; + + dComIfGp_getTree()->deleteAnm(mAnimIdx); + mAnimIdx = (anm.field_0x02 >> 13) & 7; + } + } } /* 8007945C-8007946C .text newData__12dTree_room_cFP12dTree_data_c */ -void dTree_room_c::newData(dTree_data_c*) { - /* Nonmatching */ +void dTree_room_c::newData(dTree_data_c* i_data) { + i_data->mpNext = mpData; + mpData = i_data; } /* 8007946C-800794D0 .text deleteData__12dTree_room_cFv */ void dTree_room_c::deleteData() { - /* Nonmatching */ + while (mpData != NULL) { + mpData->mState = 0; + mDoAud_seDeleteObject(&mpData->mPos); + mpData = mpData->mpNext; + } } /* 800794D0-800795E8 .text __ct__14dTree_packet_cFv */ dTree_packet_c::dTree_packet_c() { - /* Nonmatching */ + dTree_data_c* data = getData(); + for (s32 i = 0; i < ARRAY_SIZE(mData); i++, data++) + data->mState = 0; + + dTree_anm_c* anm = getAnm(); + for (s32 i = 0; i < ARRAY_SIZE(mAnm); i++, anm++) + anm->mState = 0; + + s16 angle = 0; + for (s32 i = 0; i < 8; i++, angle += 0x2000) + setAnm(i, angle); } +dPa_smokeEcallBack dTree_data_c::mSmokeEcallback(1, 1, 0, 1); + /* 800795E8-800795F4 .text __ct__12dTree_room_cFv */ dTree_room_c::dTree_room_c() { - /* Nonmatching */ + mpData = NULL; } /* 800795F4-80079600 .text __ct__11dTree_anm_cFv */ dTree_anm_c::dTree_anm_c() { - /* Nonmatching */ + mState = 0; } /* 80079600-8007960C .text __ct__12dTree_data_cFv */ dTree_data_c::dTree_data_c() { - /* Nonmatching */ + mState = 0; } /* 8007960C-80079898 .text draw__14dTree_packet_cFv */ @@ -255,39 +491,302 @@ void dTree_packet_c::draw() { {&l_Oba_swood_a_cuttDL, 0xA0}, {&l_Oba_swood_a_cutuDL, 0x60}, }; + + static GXColor l_shadowColor = {0x00, 0x00, 0x00, 0x64}; + + static u8 l_modelStatus[2][3] = {0, 1, 2, 3, 1, 4}; + + j3dSys.reinitGX(); + GXSetNumIndStages(0); + GFSetVtxDescv(l_shadowVtxDescList); + GFSetVtxAttrFmtv(GX_VTXFMT0, l_shadowVtxAttrFmtList); + GFSetArray(GX_VA_POS, g_dTree_shadowPos, 3); + GFSetArray(GX_VA_TEX0, g_dTree_shadowTexCoord, 2); + GXCallDisplayList(g_dTree_shadowMatDL, 0x80); + GFSetTevColor(GX_TEVREG0, l_shadowColor); + + dTree_room_c* room = &mRoom[0]; + for (s32 i = 0; i < (s32)ARRAY_SIZE(mRoom); room++, i++) { + dKy_tevstr_c* tevstr = dComIfGp_roomControl_getTevStr(i); + dKy_GfFog_tevstr_set(tevstr); + for (dTree_data_c* data = room->mpData; data != NULL; data = data->mpNext) { + if (!cLib_checkBit(data->mState, 0x04)) { + GFLoadPosMtxImm(data->field_0x0d0, GX_PNMTX0); + GXCallDisplayList(g_dTree_Oba_kage_32DL, 0x20); + } + } + } + + GFSetVtxDescv(l_vtxDescList); + GFSetVtxAttrFmtv(GX_VTXFMT0, l_vtxAttrFmtList); + GFSetArray(GX_VA_POS, l_pos, sizeof(cXyz)); + GFSetArray(GX_VA_CLR0, l_color, sizeof(GXColor)); + GFSetArray(GX_VA_TEX0, l_texCoord, sizeof(cXy)); + GXCallDisplayList(l_matDL, 0xA0); + + room = &mRoom[0]; + for (s32 i = 0; i < (s32)ARRAY_SIZE(mRoom); room++, i++) { + dKy_tevstr_c* tevstr = dComIfGp_roomControl_getTevStr(i); + GFSetTevColorS10(GX_TEVREG0, tevstr->mColorC0); + GFSetTevColor(GX_TEVREG1, tevstr->mColorK0); + dKy_GfFog_tevstr_set(tevstr); + for (dTree_data_c* data = room->mpData; data != NULL; data = data->mpNext) { + if (!cLib_checkBit(data->mState, 0x04)) { + u8* var_r25 = l_modelStatus[data->field_0x001]; + if (data->field_0x003 != 0) { + GXColor sp; + sp.a = data->field_0x003; + GFSetTevColor(GX_TEVREG2, sp); + GFLoadPosMtxImm(data->field_0x010, GX_PNMTX0); + GXCallDisplayList(l_modelDataStatus[var_r25[0]].list, + l_modelDataStatus[var_r25[0]].nbytes); + GXCallDisplayList(l_modelDataStatus[var_r25[1]].list, + l_modelDataStatus[var_r25[1]].nbytes); + } + + GFLoadPosMtxImm(data->field_0x040, GX_PNMTX0); + GXCallDisplayList(l_modelDataStatus[var_r25[2]].list, + l_modelDataStatus[var_r25[2]].nbytes); + } + } + } + + J3DShape::resetVcdVatCache(); } /* 80079898-80079B24 .text calc__14dTree_packet_cFv */ +// NONMATCHING - some regalloc void dTree_packet_c::calc() { - /* Nonmatching */ + dTree_anm_c* anm = getAnm(); + + int var_r3 = 0; + for (s32 i = 0; i < 8; anm++, var_r3 += 250, i++) { + anm->field_0x06 = anm->field_0x02 + 100.0f + cM_scos((g_Counter.mTimer + var_r3) * 4000.0f) * 100.0f; + anm->field_0x04 = 100.0f + cM_scos((g_Counter.mTimer + var_r3) * 1000.0f) * 100.0f; + } + + int roomNo = dComIfGp_roomControl_getStayNo(); + dTree_data_c* data = mRoom[roomNo].getData(); + if (data != NULL) { + daPy_py_c* player = daPy_getPlayerActorClass(); + mPlayerCutFlg = player->checkNoResetFlg0(daPy_py_c::daPyFlg0_CUT_AT_FLG) != 0; + + cXyz sp38; + cXyz sp2C; + sp38 = player->getSwordTopPos(); + + sp2C = sp38 - player->current.pos; + mPlayerSwordAngY = cM_atan2s(sp2C.x, sp2C.z); + + sp2C = mPlayerSwordTop - sp38; + mPlayerSwordMoveAngY = cM_atan2s(sp2C.x, sp2C.z); + + mPlayerSwordTop = sp38; + + l_CutSoundFlag = false; + dComIfG_Ccsp()->SetMassAttr(40.0f, 200.0f, 19, 1); + + while (true) { + if (!cLib_checkBit(data->mState, 0x08)) + data->hitCheck(player, roomNo); + + if (data->mAnimIdx >= 8) + data->animation(roomNo); + + data = data->mpNext; + if (data == NULL) + break; + } + } } /* 80079B24-80079E6C .text checkGroundY__FP12dTree_data_cR4cXyz */ -void checkGroundY(dTree_data_c*, cXyz&) { - /* Nonmatching */ +f32 checkGroundY(dTree_data_c* i_data, cXyz& i_pos) { + dBgS_GndChk chk; + i_pos.y += 50.0f; + chk.SetPos(&i_pos); + f32 y = dComIfG_Bgsp()->GroundCross(&chk); + i_pos.y -= 50.0f; + + cXyz norm; + if (y <= -G_CM3D_F_INF) { + y = i_pos.y; + norm.set(0.0f, 1.0f, 0.0f); + } else { + norm = *dComIfG_Bgsp()->GetTriPla(chk)->GetNP(); + } + + f32 var_f4 = std::sqrtf(1.0f - (norm.x * norm.x)); + f32 var_f2; + f32 var_f3; + if (var_f4 != 0.0f) { + var_f2 = norm.y * var_f4; + var_f3 = -norm.z * var_f4; + } else { + var_f2 = 0.0f; + var_f3 = 0.0f; + } + + i_data->mShadowMtx[0][0] = var_f4; + i_data->mShadowMtx[0][1] = norm.x; + i_data->mShadowMtx[0][2] = 0.0f; + i_data->mShadowMtx[0][3] = i_pos.x; + + i_data->mShadowMtx[1][0] = -norm.x * var_f2; + i_data->mShadowMtx[1][1] = norm.y; + i_data->mShadowMtx[1][2] = var_f3; + i_data->mShadowMtx[1][3] = y + 1.0f; + + i_data->mShadowMtx[2][0] = norm.x * var_f3; + i_data->mShadowMtx[2][1] = norm.z; + i_data->mShadowMtx[2][2] = var_f2; + i_data->mShadowMtx[2][3] = i_pos.z; + + return y; } /* 80079E6C-8007A14C .text update__14dTree_packet_cFv */ void dTree_packet_c::update() { - /* Nonmatching */ + dTree_anm_c* anm = getAnm(); + for (int i = 0; i < (s32)ARRAY_SIZE(mAnm); i++, anm++) { + mDoMtx_stack_c::YrotS(anm->field_0x0a); + mDoMtx_stack_c::XrotM(anm->field_0x04); + mDoMtx_stack_c::YrotM(anm->field_0x06 - anm->field_0x0a); + mDoMtx_copy(mDoMtx_stack_c::get(), anm->field_0x24); + + mDoMtx_stack_c::YrotS(anm->field_0x0a); + mDoMtx_stack_c::XrotM(anm->field_0x08); + mDoMtx_stack_c::YrotM(anm->field_0x02 - anm->field_0x0a); + mDoMtx_copy(mDoMtx_stack_c::get(), anm->field_0x54); + } + + dTree_data_c* data = getData(); + anm = getAnm(); + + s32 numPerFrame = 0; + mDoLib_clipper::changeFar(mDoLib_clipper::getFar() * 1.8181819f); + + for (int i = 0; i < (s32)ARRAY_SIZE(mData); i++) { + if (data->mState & 2) { + if ((data->mState & 0x10) && numPerFrame < 4) { + data->mPos.y = checkGroundY(data, data->mPos); + data->mState &= ~0x10; + numPerFrame++; + } + + cXyz pos(data->mPos.x, data->mPos.y + 260.0f, data->mPos.z); + if (mDoLib_clipper::clip(j3dSys.getViewMtx(), pos, 260.0f)) { + cLib_onBit(data->mState, 0x04); + } else { + cLib_offBit(data->mState, 0x04); + + dTree_anm_c* var_r22 = &anm[data->mAnimIdx]; + if (data->mState & 8) { + mDoMtx_concat(j3dSys.getViewMtx(), data->field_0x070, data->field_0x010); + cLib_chaseUC(&data->field_0x003, 0, 8); + } else { + var_r22->field_0x24[0][3] = data->mPos.x + var_r22->field_0x18; + var_r22->field_0x24[1][3] = data->mPos.y + var_r22->field_0x1c; + var_r22->field_0x24[2][3] = data->mPos.z + var_r22->field_0x20; + mDoMtx_concat(j3dSys.getViewMtx(), var_r22->field_0x24, data->field_0x010); + } + + var_r22->field_0x54[0][3] = data->mPos.x; + var_r22->field_0x54[1][3] = data->mPos.y; + var_r22->field_0x54[2][3] = data->mPos.z; + + mDoMtx_concat(j3dSys.getViewMtx(), var_r22->field_0x54, data->field_0x040); + mDoMtx_concat(j3dSys.getViewMtx(), data->mShadowMtx, data->field_0x0d0); + } + } + data++; + } + + mDoLib_clipper::resetFar(); + dComIfGd_setXluListBG(); + j3dSys.getDrawBuffer(1)->entryImm(this, 0); + dComIfGd_setXluList(); } /* 8007A14C-8007A238 .text setData__14dTree_packet_cFP12dTree_data_ciR4cXyzUci */ -void dTree_packet_c::setData(dTree_data_c*, int, cXyz&, u8, int) { - /* Nonmatching */ +void dTree_packet_c::setData(dTree_data_c* i_data, int i_nextIdx, cXyz& i_pos, u8 param_3, int i_roomNo) { + f32 y; + if (fopOvlpM_IsPeek()) { + y = checkGroundY(i_data, i_pos); + i_data->mState = 6; + } else { + y = i_pos.y; + i_data->mState = 22; + } + + i_data->field_0x001 = param_3; + i_data->field_0x003 = param_3 == 1 ? 0 : 0xFF; + i_data->mAnimIdx = (u8)cM_rndF(7.0f); + i_data->mPos.set(i_pos.x, y, i_pos.z); + mRoom[i_roomNo].newData(i_data); + mNextIdx = i_nextIdx; } /* 8007A238-8007A36C .text newData__14dTree_packet_cFR4cXyzUci */ -void dTree_packet_c::newData(cXyz&, u8, int) { - /* Nonmatching */ +dTree_data_c* dTree_packet_c::newData(cXyz& i_pos, u8 param_1, int i_roomNo) { + JUT_ASSERT(1608, 0 <= i_roomNo && i_roomNo < 64); + + dTree_data_c* data = &mData[mNextIdx]; + s32 i = mNextIdx; + for (; i < (s32)ARRAY_SIZE(mData); data++, i++) { + if (!(data->mState & 2)) { + setData(data, i, i_pos, param_1, i_roomNo); + return data; + } + } + + data = getData(); + for (i = 0; i < mNextIdx; data++, i++) { + if (!(data->mState & 2)) { + setData(data, i, i_pos, param_1, i_roomNo); + return data; + } + } + + return NULL; } /* 8007A36C-8007A3DC .text newAnm__14dTree_packet_cFs */ -void dTree_packet_c::newAnm(s16) { - /* Nonmatching */ +s32 dTree_packet_c::newAnm(s16 param_0) { + dTree_anm_c* anm = &getAnm(8); + for (s32 i = 8; i < 64 + 8; anm++, i++) { + if (anm->mState == 0) { + anm->mState = 1; + anm->field_0x02 = param_0; + anm->field_0x06 = param_0; + anm->field_0x04 = 0; + anm->field_0x08 = 0; + anm->field_0x0a = 0; + anm->mAnimTimer = 0; + anm->field_0x10 = 0; + anm->field_0x14 = 0; + anm->field_0x18 = 0; + anm->field_0x1c = 0; + anm->field_0x20 = 0; + return i; + } + } + return -1; } /* 8007A3DC-8007A428 .text setAnm__14dTree_packet_cFis */ -void dTree_packet_c::setAnm(int, s16) { - /* Nonmatching */ +void dTree_packet_c::setAnm(int i_no, s16 param_1) { + dTree_anm_c& anm = getAnm(i_no); + anm.mState = 1; + anm.field_0x02 = param_1; + anm.field_0x06 = param_1; + anm.field_0x04 = 0; + anm.field_0x08 = 0; + anm.field_0x0a = 0; + anm.mAnimTimer = 0; + anm.field_0x10 = 0; + anm.field_0x14 = 0; + anm.field_0x18 = 0; + anm.field_0x1c = 0; + anm.field_0x20 = 0; }