diff --git a/include/d/d_grass.h b/include/d/d_grass.h index eaa79f329..b0956f181 100644 --- a/include/d/d_grass.h +++ b/include/d/d_grass.h @@ -21,7 +21,7 @@ public: /* 0x00 */ u8 mState; /* 0x01 */ u8 mInitFlags; - /* 0x02 */ u8 mAnimIdx; + /* 0x02 */ s8 mAnimIdx; /* 0x03 */ u8 mItemIdx; /* 0x04 */ cXyz mPos; /* 0x10 */ Mtx mModelMtx; @@ -54,15 +54,15 @@ public: void calc(); void update(); void setData(dGrass_data_c*, int, cXyz&, int, s8); - void newData(cXyz&, int, s8); - void newAnm(); + dGrass_data_c* newData(cXyz&, int, s8); + s32 newAnm(); void setAnm(int, s16); void deleteRoom(s32 roomNo) { mGrassRoom[roomNo].deleteData(); } virtual void draw(); virtual ~dGrass_packet_c(); - /* 0x00010 */ s16 mRndm; + /* 0x00010 */ s16 mNextIdx; /* 0x00012 */ u8 field_0x00012[0x00014 - 0x00012]; /* 0x00014 */ dGrass_data_c mGrassData[1500]; /* 0x18E84 */ dGrass_anm_c mGrassAnm[104]; diff --git a/include/d/d_kankyo.h b/include/d/d_kankyo.h index ad5d84518..4ac8f2c4b 100644 --- a/include/d/d_kankyo.h +++ b/include/d/d_kankyo.h @@ -432,6 +432,7 @@ void dKy_setLight_again(); void dKy_GxFog_set(); void dKy_GxFog_sea_set(); void dKy_GxFog_tevstr_set(dKy_tevstr_c*); +void dKy_GfFog_tevstr_set(dKy_tevstr_c*); void GxXFog_set(); void dKy_set_actcol_ratio(f32 ratio); void dKy_set_bgcol_ratio(f32 ratio); @@ -445,5 +446,6 @@ cXyz dKy_get_orion_pos(); cXyz dKy_get_hokuto_pos(); void dKy_DayProc(); u8 dKy_get_schbit(); +int dKy_rain_check(); #endif /* D_KANKYO_D_KANKYO_H */ diff --git a/src/d/d_grass.cpp b/src/d/d_grass.cpp index 56782abdf..d92dde627 100644 --- a/src/d/d_grass.cpp +++ b/src/d/d_grass.cpp @@ -4,11 +4,19 @@ // #include "d/d_grass.h" -#include "dolphin/types.h" +#include "f_op/f_op_overlap_mng.h" +#include "d/d_bg_s_gnd_chk.h" +#include "d/d_com_inf_game.h" +#include "d/d_kankyo.h" +#include "m_Do/m_Do_mtx.h" +#include "m_Do/m_Do_lib.h" +#include "dolphin/gf/GFGeometry.h" +#include "dolphin/gf/GFTev.h" /* 80077048-8007712C .text setBatta__FP4cXyzP8_GXColor */ -void setBatta(cXyz*, _GXColor*) { - /* Nonmatching */ +void setBatta(cXyz* pos, GXColor* color) { + if (!dKy_rain_check() && !dComIfGp_event_runCheck() && strncmp(dComIfGp_getStartStageName(), "kin", 3) != 0 && strcmp(dComIfGp_getStartStageName(), "Xboss1") != 0 && cM_rnd() > 0.99f) + dComIfGp_particle_set(0x453, pos, NULL, NULL, 0xFF, NULL, -1, color, color); } /* 8007712C-8007734C .text WorkCo__13dGrass_data_cFP10fopAc_ac_cUli */ @@ -32,13 +40,18 @@ void dGrass_data_c::hitCheck(int) { } /* 80077A1C-80077A2C .text newData__13dGrass_room_cFP13dGrass_data_c */ -void dGrass_room_c::newData(dGrass_data_c*) { - /* Nonmatching */ +void dGrass_room_c::newData(dGrass_data_c* data) { + data->mpNextData = mpData; + mpData = data; } /* 80077A2C-80077A90 .text deleteData__13dGrass_room_cFv */ void dGrass_room_c::deleteData() { - /* Nonmatching */ + while (mpData != NULL) { + mpData->mState = 0; + mDoAud_seDeleteObject(&mpData->mPos); + mpData = mpData->mpNextData; + } } /* 80077A90-80077CB8 .text __ct__15dGrass_packet_cFv */ @@ -48,22 +61,64 @@ dGrass_packet_c::dGrass_packet_c() { /* 80077CB8-80077CC4 .text __ct__13dGrass_room_cFv */ dGrass_room_c::dGrass_room_c() { - /* Nonmatching */ + mpData = NULL; } /* 80077CC4-80077CD0 .text __ct__12dGrass_anm_cFv */ dGrass_anm_c::dGrass_anm_c() { - /* Nonmatching */ + mState = 0; } /* 80077CD0-80077CDC .text __ct__13dGrass_data_cFv */ dGrass_data_c::dGrass_data_c() { - /* Nonmatching */ + mState = 0; } /* 80077CDC-80077E58 .text draw__15dGrass_packet_cFv */ void dGrass_packet_c::draw() { /* Nonmatching */ + j3dSys.reinitGX(); + GXSetNumIndStages(0); + + static GXVtxDescList l_vtxDescList[] = { + {GX_VA_POS, GX_INDEX8}, + {GX_VA_CLR0, GX_INDEX8}, + {GX_VA_TEX0, GX_INDEX8}, + {GX_VA_NULL, GX_NONE}, + }; + + static GXVtxAttrFmtList l_vtxAttrFmtList[] = { + {GX_VA_POS, GX_POS_XYZ, GX_F32, 0x00}, + {GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0x00}, + {GX_VA_TEX0, GX_TEX_ST, GX_F32, 0x00}, + {GX_VA_NULL, GX_POS_XYZ, GX_F32, 0x00}, + }; + + GFSetVtxDescv(l_vtxDescList); + GFSetVtxAttrFmtv(GX_VTXFMT0, l_vtxAttrFmtList); + GFSetArray(GX_VA_POS, mpPosArr, sizeof(cXyz)); + GFSetArray(GX_VA_CLR0, mpColorArr, sizeof(*mpColorArr)); + GFSetArray(GX_VA_TEX0, mpTexCoordArr, sizeof(cXy)); + GXCallDisplayList(mpMatDL, mMatDLSize); + + dGrass_room_c* room = &mGrassRoom[0]; + for (s32 i = 0; i < (s32)ARRAY_SIZE(mGrassRoom); 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 (dGrass_data_c* data = room->mpData; data != NULL; data = data->mpNextData) { + if (!(data->mInitFlags & 2)) { + GXLoadPosMtxImm(data->mModelMtx, GX_PNMTX0); + if (data->mAnimIdx >= 0) + GXCallDisplayList(mpDL, mDLSize); + else + GXCallDisplayList(mpDLCut, mDLCutSize); + } + } + } + + J3DShape::resetVcdVatCache(); } /* 80077E58-80078008 .text calc__15dGrass_packet_cFv */ @@ -72,31 +127,113 @@ void dGrass_packet_c::calc() { } /* 80078008-800782B8 .text checkGroundY__FR4cXyz */ -static void checkGroundY(cXyz&) { - /* Nonmatching */ +static f32 checkGroundY(cXyz& pos) { + dBgS_GndChk chk; + pos.y += 50.0f; + chk.SetPos(&pos); + f32 y = dComIfG_Bgsp()->GroundCross(&chk); + pos.y -= 50.0f; + if (y <= -1000000000.0f) + return pos.y; + else + return y; } /* 800782B8-800784E8 .text update__15dGrass_packet_cFv */ void dGrass_packet_c::update() { /* Nonmatching */ + dGrass_anm_c* anm = &mGrassAnm[0]; + for (s32 i = 0; i < (s32)ARRAY_SIZE(mGrassAnm); anm++, i++) { + mDoMtx_stack_c::YrotS(anm->mRotY); + mDoMtx_stack_c::XrotM(anm->mRotX); + mDoMtx_stack_c::YrotM(-anm->mRotY); + mDoMtx_copy(mDoMtx_stack_c::get(), anm->mAnimMtx); + } + + dGrass_data_c* data = &mGrassData[0]; + mDoLib_clipper::changeFar(mDoLib_clipper::getFar() * 1.636364f); + s32 numPerFrame = 0; + s32 angle = 0; + for (s32 i = 0; i < (s32)ARRAY_SIZE(mGrassData); data++, i++) { + if (data->mState != 0) { + if (data->mState == 1 && numPerFrame < 30) { + data->mPos.y = checkGroundY(data->mPos); + data->mState = 2; + numPerFrame++; + } + + cXyz pos; + pos.z = data->mPos.z; + pos.y = data->mPos.y + 260.0f; + pos.x = data->mPos.x; + if (mDoLib_clipper::clip(j3dSys.getViewMtx(), pos, 260.0f)) { + data->mInitFlags |= 2; + } else { + data->mInitFlags &= ~2; + if (data->mAnimIdx >= 0) { + Mtx& mtx = mGrassAnm[data->mAnimIdx].mAnimMtx; + mtx[0][3] = pos.x; + mtx[1][3] = pos.y; + mtx[2][3] = pos.z; + mDoMtx_concat(j3dSys.getViewMtx(), mtx, data->mModelMtx); + } else { + mDoMtx_trans(data->mModelMtx, pos.x, pos.y, pos.z); + mDoMtx_YrotM(data->mModelMtx, angle); + mDoMtx_concat(j3dSys.getViewMtx(), data->mModelMtx, data->mModelMtx); + } + } + } + angle += 3535; + } + mDoLib_clipper::resetFar(); + j3dSys.getDrawBuffer(0)->entryImm(this, 0); } /* 800784E8-800785C0 .text setData__15dGrass_packet_cFP13dGrass_data_ciR4cXyziSc */ -void dGrass_packet_c::setData(dGrass_data_c*, int, cXyz&, int, s8) { +void dGrass_packet_c::setData(dGrass_data_c* data, int nextIdx, cXyz& pos, int i_roomNo, s8 itemIdx) { /* Nonmatching */ + f32 y; + if (fopOvlpM_IsPeek()) { + y = checkGroundY(pos); + data->mState = 2; + } else { + y = pos.y; + data->mState = 1; + } + data->mInitFlags = 2; + data->mAnimIdx = (u8)cM_rndF(7.0f); + data->mPos.set(pos.x, y, pos.z); + data->mItemIdx = itemIdx; + mGrassRoom[i_roomNo].newData(data); + mNextIdx = nextIdx; } /* 800785C0-800786FC .text newData__15dGrass_packet_cFR4cXyziSc */ -void dGrass_packet_c::newData(cXyz&, int, s8) { +dGrass_data_c* dGrass_packet_c::newData(cXyz& pos, int i_roomNo, s8 itemIdx) { /* Nonmatching */ + JUT_ASSERT(0x600, 0 <= i_roomNo && i_roomNo < 64); + s16 idx = mNextIdx; + dGrass_data_c* data = &mGrassData[idx]; } /* 800786FC-80078748 .text newAnm__15dGrass_packet_cFv */ -void dGrass_packet_c::newAnm() { - /* Nonmatching */ +s32 dGrass_packet_c::newAnm() { + dGrass_anm_c* anm = &mGrassAnm[8]; + for (s32 i = 8; i < 104; anm++, i++) { + if (anm->mState == 0) { + anm->mState = 1; + anm->mRotY = 0; + anm->mRotX = 0; + return i; + } + } + return -1; } /* 80078748-80078770 .text setAnm__15dGrass_packet_cFis */ -void dGrass_packet_c::setAnm(int, s16) { - /* Nonmatching */ +void dGrass_packet_c::setAnm(int idx, s16 angleY) { + dGrass_anm_c& anm = mGrassAnm[idx]; + anm.mState = 1; + anm.mRotY = angleY; + anm.mRotX = 0; }