From fda302008e559e2776ca94bc1dadd662e7e5fbc9 Mon Sep 17 00:00:00 2001 From: Daniel Hajjar <33489389+DanTGL@users.noreply.github.com> Date: Sat, 22 Jun 2024 02:31:43 +0200 Subject: [PATCH] d_a_sea (#659) * d_a_sea fixes * daSea_ChkArea matching * daSea_calcWave WIP * daSea_GetPoly WIP * d_a_sea Added Nonmatching comments * daSea_calcWave matching * daSea_calcWave fakematch * daSea_packet_c::CalcFlatInterTarget matching * daSea_GetPoly matching * daSea_packet_c::SetCullStopFlag matching * d_a_sea Misc fixes * daSea_packet_c::execute matching * daSea_packet_c::execute cleanup * daSea_packet_c::create matching * daSea_packet_c::CalcFlatInter matching * daSea_packet_c::draw WIP * daSea_packet_c::draw more WIP * daSea_packet_c::draw work * daSea_packet_c::draw even more WIP * d_a_sea matching Co-authored-by: LagoLunatic * d_a_sea cleanup * updated configure.py * d_a_sea minor cleanup --------- Co-authored-by: LagoLunatic --- include/SSystem/SComponent/c_m2d_g_box.h | 2 + include/d/actor/d_a_sea.h | 10 +- include/dolphin/gx/GXBump.h | 1 + src/d/actor/d_a_sea.cpp | 874 +++++++++++++++++++++-- 4 files changed, 831 insertions(+), 56 deletions(-) diff --git a/include/SSystem/SComponent/c_m2d_g_box.h b/include/SSystem/SComponent/c_m2d_g_box.h index 1a0bbda9c..c58917a06 100644 --- a/include/SSystem/SComponent/c_m2d_g_box.h +++ b/include/SSystem/SComponent/c_m2d_g_box.h @@ -7,6 +7,8 @@ class cM2dGBox { public: cXy mP0, mP1; + virtual ~cM2dGBox() {} + void Set(cXy& pA, cXy& pB); f32 GetLen(const cXy& pXy) const; }; diff --git a/include/d/actor/d_a_sea.h b/include/d/actor/d_a_sea.h index c77769a71..96c4d882a 100644 --- a/include/d/actor/d_a_sea.h +++ b/include/d/actor/d_a_sea.h @@ -13,8 +13,8 @@ public: public: int Pos2Index(f32, f32*); - u32 GetHeight(f32, f32); - u32 GetHeight(int, int); + int GetHeight(f32, f32); + int GetHeight(int, int); void GetArea(int, int, f32*, f32*, f32*, f32*); void SetInf(); virtual ~daSea_WaterHeightInfo_Mng() {} @@ -78,7 +78,7 @@ public: GXTexObj* getYuraTexObj() { return &mTexYura; } void ChkNowUse() {} void GetSrcDataHeight(f32, f32) {} - void ChkCullStop() {} + bool ChkCullStop() { return mCullStopFlag == 1; } void end() {} void getPos() {} void GetCenterP() {} @@ -101,7 +101,7 @@ public: /* 0x120 */ f32 mDrawMaxZ; /* 0x124 */ f32* mpHeightTable; /* 0x128 */ cXyz mCurPos; - /* 0x134 */ cXyz* mpDrawVtx; + /* 0x134 */ cXyz* m_draw_vtx; /* 0x138 */ u8 mInitFlag; /* 0x139 */ u8 mCullStopFlag; /* 0x13A */ u8 m13A; @@ -120,7 +120,7 @@ class sea_class : public fopAc_ac_c { }; void daSea_Init(); -void daSea_ChkAreaBeforePos(f32, f32); +bool daSea_ChkAreaBeforePos(f32, f32); bool daSea_ChkArea(f32, f32); f32 daSea_calcWave(f32, f32); void daSea_GetPoly(void*, void (*)(void*, cXyz&, cXyz&, cXyz&), const cXyz&, const cXyz&); diff --git a/include/dolphin/gx/GXBump.h b/include/dolphin/gx/GXBump.h index ddb8d6774..07f933f74 100644 --- a/include/dolphin/gx/GXBump.h +++ b/include/dolphin/gx/GXBump.h @@ -15,6 +15,7 @@ void GXSetIndTexCoordScale(GXIndTexStageID texStage, GXIndTexScale scaleS, GXInd void GXSetIndTexOrder(GXIndTexStageID stage, GXTexCoordID coord, GXTexMapID map); void GXSetNumIndStages(u8 num); void GXSetTevDirect(GXTevStageID stage); +void GXSetTevIndWarp(GXTevStageID tevStage, GXIndTexStageID texStage, GXBool, GXBool, GXIndTexMtxID mtxID); // Might be incorrect #ifdef __cplusplus }; diff --git a/src/d/actor/d_a_sea.cpp b/src/d/actor/d_a_sea.cpp index 1a2cac069..39385365a 100644 --- a/src/d/actor/d_a_sea.cpp +++ b/src/d/actor/d_a_sea.cpp @@ -8,7 +8,9 @@ #include "d/d_procname.h" #include "d/d_stage.h" #include "m_Do/m_Do_lib.h" +#include "m_Do/m_Do_graphic.h" #include "d/actor/d_a_daiocta.h" +#include "SSystem/SComponent/c_m2d_g_box.h" daSea_packet_c l_cloth; @@ -49,23 +51,26 @@ daSea_WaveInfoDat wi_prm_ocean[4] = { }, }; -u8 pos_around[16] = { - 0xFF, 0xFF, 0x00, 0XFF, - 0x01, 0xFF, 0x01, 0x00, - 0x01, 0x01, 0x00, 0x01, - 0xFF, 0x01, 0xFF, 0x00, +s8 pos_around[16] = { + -1, -1, 0, -1, + 1, -1, 1, 0, + 1, 1, 0, 1, + -1, 1, -1, 0, }; +extern void dKy_usonami_set(f32 param_0); + /* 8015B0A4-8015B0FC .text Pos2Index__25daSea_WaterHeightInfo_MngFfPf */ int daSea_WaterHeightInfo_Mng::Pos2Index(f32 v, f32* dst) { - int idx = (v + 450000.0f) / 100000.0f; + f32 f = 450000.0f; + int idx = (v + f) / 100000.0f; if (dst != NULL) - *dst = (v + 450000.0f) - idx * 100000.0f; + *dst = (v + f) - idx * 100000.0f; return idx; } /* 8015B0FC-8015B164 .text GetHeight__25daSea_WaterHeightInfo_MngFff */ -u32 daSea_WaterHeightInfo_Mng::GetHeight(f32 x, f32 z) { +int daSea_WaterHeightInfo_Mng::GetHeight(f32 x, f32 z) { int xi = Pos2Index(x, NULL); int zi = Pos2Index(z, NULL); return GetHeight(xi, zi); @@ -86,7 +91,7 @@ int get_wave_max(int roomNo) { } /* 8015B1E8-8015B288 .text GetHeight__25daSea_WaterHeightInfo_MngFii */ -u32 daSea_WaterHeightInfo_Mng::GetHeight(int x, int z) { +int daSea_WaterHeightInfo_Mng::GetHeight(int x, int z) { if (x < 0 || 9 <= x || z < 0 || 9 <= z) return 10; @@ -138,9 +143,7 @@ daSea_WaveInfo::daSea_WaveInfo() { } /* 8015B43C-8015B484 .text __dt__14daSea_WaveInfoFv */ -daSea_WaveInfo::~daSea_WaveInfo() { - /* Nonmatching */ -} +daSea_WaveInfo::~daSea_WaveInfo() {} /* 8015B484-8015B4D4 .text AddCounter__14daSea_WaveInfoFv */ void daSea_WaveInfo::AddCounter() { @@ -169,7 +172,6 @@ f32 daSea_WaveInfo::GetScale(f32 v) { /* 8015B56C-8015B7A0 .text create__14daSea_packet_cFR4cXyz */ bool daSea_packet_c::create(cXyz& pos) { - /* Nonmatching */ BASE_HEIGHT = 1.0f; BASE_HEIGHT = pos.y + 1.0f; @@ -187,18 +189,22 @@ bool daSea_packet_c::create(cXyz& pos) { mAnimCounter = 0; ResTIMG* timg = (ResTIMG*)dComIfG_getObjectRes("Always", ALWAYS_BTI_B_SEA_TEX0AND2); + + GXBool mipmap = timg->mipmapCount > 1; GXInitTexObj(&mTexSea0, (char*)timg + timg->imageOffset, timg->width, timg->height, (GXTexFmt)timg->format, (GXTexWrapMode)timg->wrapS, (GXTexWrapMode)timg->wrapT, - (GXBool)(timg->mipmapCount > 1)); + mipmap); GXInitTexObjLOD(&mTexSea0, (GXTexFilter)timg->minFilter, (GXTexFilter)timg->magFilter, - timg->minLOD * 0.125f, timg->maxLOD * 0.125f, 0.9f, + timg->minLOD * 0.125f, timg->maxLOD * 0.125f, -0.9f, (GXBool)timg->biasClamp, (GXBool)timg->doEdgeLOD, (GXAnisotropy)timg->maxAnisotropy); + + mipmap = timg->mipmapCount > 1; GXInitTexObj(&mTexSea1, (char*)timg + timg->imageOffset, timg->width, timg->height, (GXTexFmt)timg->format, (GXTexWrapMode)timg->wrapS, (GXTexWrapMode)timg->wrapT, - (GXBool)(timg->mipmapCount > 1)); + mipmap); GXInitTexObjLOD(&mTexSea1, (GXTexFilter)timg->minFilter, (GXTexFilter)timg->magFilter, - timg->minLOD * 0.125f, timg->maxLOD * 0.125f, 0.0f, + timg->minLOD * 0.125f, timg->maxLOD * 0.125f, 1.0f, (GXBool)timg->biasClamp, (GXBool)timg->doEdgeLOD, (GXAnisotropy)timg->maxAnisotropy); @@ -234,15 +240,56 @@ void daSea_packet_c::ClrFlat() { } /* 8015B884-8015BA18 .text CalcFlatInterTarget__14daSea_packet_cFR4cXyz */ -f32 daSea_packet_c::CalcFlatInterTarget(cXyz&) { - /* Nonmatching */ +f32 daSea_packet_c::CalcFlatInterTarget(cXyz& pos) { + cM2dGBox box; + cXy xzPos; + xzPos.x = pos.x; + xzPos.y = pos.z; + + if (mWaterHeightMgr.GetHeight(mIdxX, mIdxZ) == 0) { + return 0.0f; + } + + f32 result = 1.0f; + + for (int i = 0; i < 8; i++) { + int ix = mIdxX + pos_around[2 * i]; + int iz = mIdxZ + pos_around[(2 * i) + 1]; + + if (mWaterHeightMgr.GetHeight(ix, iz) == 0) { + cXy min; + cXy max; + + mWaterHeightMgr.GetArea(ix, iz, &min.x, &min.y, &max.x, &max.y); + + min.x -= 12800.0f; + min.y -= 12800.0f; + max.x += 12800.0f; + max.y += 12800.0f; + + box.Set(min, max); + + f32 len = box.GetLen(xzPos); + + if (len > 12800.0f) { + len = 12800.0f; + } + + len /= 12800.0f; + if (result > len) { + result = len; + } + } + } + + return result; } /* 8015BA18-8015BAD8 .text CalcFlatInter__14daSea_packet_cFv */ void daSea_packet_c::CalcFlatInter() { if (mFlags & 1) { if (mFlatInterCounter != 0.0f) { - mFlatInter += (mFlatTarget - mFlatInter) / mFlatInterCounter; + mFlatInter = mFlatInter + (mFlatTarget - mFlatInter) / mFlatInterCounter; mFlatInterCounter--; } else { mFlatInter = mFlatTarget; @@ -250,7 +297,7 @@ void daSea_packet_c::CalcFlatInter() { } else { f32 target = CalcFlatInterTarget(mPlayerPos); if (mFlatInterCounter != 0.0f) { - mFlatInter += (target - mFlatInter) / mFlatInterCounter; + mFlatInter = mFlatInter + (target - mFlatInter) / mFlatInterCounter; mFlatInterCounter--; } else { mFlatInter = target; @@ -266,49 +313,160 @@ void daSea_Init() { } /* 8015BAF8-8015BB60 .text daSea_ChkAreaBeforePos__Fff */ -void daSea_ChkAreaBeforePos(f32, f32) { - /* Nonmatching */ +bool daSea_ChkAreaBeforePos(f32 x, f32 z) { + if (l_cloth.mInitFlag == 0) { + return false; + } + + if (l_cloth.mWaterHeightMgr.GetHeight(x, z) == 0 && l_cloth.mCullStopFlag != 0) { + return false; + } + + return true; } /* 8015BB60-8015BBFC .text daSea_ChkArea__Fff */ -bool daSea_ChkArea(f32, f32) { - /* Nonmatching */ +bool daSea_ChkArea(f32 x, f32 z) { + if (!daSea_ChkAreaBeforePos(x, z)) { + return false; + } + + if (l_cloth.getMinX() < x && x < l_cloth.getMaxX() && l_cloth.getMinZ() < z && z < l_cloth.getMaxZ()) { + return true; + } + + return false; } +// Fakematch +#pragma opt_dead_assignments off /* 8015BBFC-8015BDB0 .text daSea_calcWave__Fff */ -f32 daSea_calcWave(f32, f32) { - /* Nonmatching */ +f32 daSea_calcWave(f32 x, f32 z) { + if (!daSea_ChkArea(x, z)) { + return daSea_packet_c::BASE_HEIGHT; + } + + f32 frac = 1.0f / 800.0f; + + int x0 = (x - l_cloth.getMinX()) * frac; + int z0 = (z - l_cloth.getMinZ()) * frac; + + f32* pY = l_cloth.mpHeightTable; + pY += x0; + pY += z0 * 65; + + //f32 minX = (x0 * 800) + l_cloth.getMinX(); + //f32 maxX = minX + 800.0f; + //f32 minZ = (z0 * 800) + l_cloth.getMinZ(); + //f32 maxZ = minZ + 800.0f; + + Vec v00, v01, v10, v11; + + v00.x = (x0 * 800) + l_cloth.getMinX(); + v00.y = pY[0]; + v00.z = (z0 * 800) + l_cloth.getMinZ(); + + v01.x = (x0 * 800) + l_cloth.getMinX(); + v01.y = pY[65]; + v01.z = v00.z + 800.0f; + + v10.x = v01.x + 800.0f; + v10.y = pY[1]; + v10.z = (z0 * 800) + l_cloth.getMinZ(); + + v11.x = v10.x; + v11.y = pY[66]; + v11.z = v01.z; + + Vec norm; + f32 baseY; + + f32 f0, f1; + f1 = x - v01.x; + f0 = z - v10.z; + f1 *= frac; + f0 *= frac; + + if (f1 + f0 >= 1.0f) { + cM3d_CalcPla(&v01, &v10, &v11, &norm, &baseY); + } else { + cM3d_CalcPla(&v00, &v01, &v10, &norm, &baseY); + } + + return -((norm.x * x) + (norm.z * z) + baseY) / norm.y; } +#pragma opt_dead_assignments reset + /* 8015BDB0-8015C010 .text daSea_GetPoly__FPvPFPvR4cXyzR4cXyzR4cXyz_vRC4cXyzRC4cXyz */ -void daSea_GetPoly(void*, void (*)(void*, cXyz&, cXyz&, cXyz&), const cXyz&, const cXyz&) { - /* Nonmatching */ +void daSea_GetPoly(void* param_1, void (*callback)(void*, cXyz&, cXyz&, cXyz&), const cXyz& param_3, const cXyz& param_4) { + if (!daSea_ChkArea(param_3.x, param_3.z) || !daSea_ChkArea(param_4.x, param_4.z)) return; + + f32 frac = 1.0f / 800.0f; + int x0 = (param_3.x - l_cloth.getMinX()) * frac; + int z0 = (param_3.z - l_cloth.getMinZ()) * frac; + int x1 = (param_4.x - l_cloth.getMinX()) * frac; + int z1 = (param_4.z - l_cloth.getMinZ()) * frac; + + if (!(x0 >= 0 && x0 <= 0x3F && z0 >= 0 && z0 <= 0x3F && x1 >= 0 && x1 <= 0x3F && z1 >= 0 && z1 <= 0x3F)) { + return; + } + + for (int z = z0; z < z1 + 1; z++) { + for (int x = x0; x < x1 + 1; x++) { + f32* pY = l_cloth.mpHeightTable; + pY += x; + pY += z * 65; + cXyz v00, v01, v10, v11; + + v00.x = (x * 800) + l_cloth.getMinX(); + v00.y = pY[0]; + v00.z = (z * 800) + l_cloth.getMinZ(); + + v01.x = v00.x; + v01.y = pY[65]; + v01.z = v00.z + 800.0f; + + v10.x = v00.x + 800.0f; + v10.y = pY[1]; + v10.z = v00.z; + + v11.x = v10.x; + v11.y = pY[66]; + v11.z = v01.z; + + callback(param_1, v00, v01, v11); + callback(param_1, v00, v11, v10); + } + } } /* 8015C010-8015C11C .text SetCullStopFlag__14daSea_packet_cFv */ void daSea_packet_c::SetCullStopFlag() { - /* Nonmatching */ if (strcmp(dComIfGp_getStartStageName(), "A_umikz") == 0) { mCullStopFlag = false; - } else { - s32 height = mWaterHeightMgr.GetHeight(mIdxX, mIdxZ); - if (height != 0) { - mCullStopFlag = false; - } else { - f32 minX, minZ, maxX, maxZ; - mWaterHeightMgr.GetArea(mIdxX, mIdxZ, &minX, &minZ, &maxX, &maxZ); - - f32 gridZ1 = minZ + 25600.0f; - f32 gridZ0 = minZ - 25600.0f; - f32 gridX1 = minX + 25600.0f; - f32 gridX0 = minX - 25600.0f; - - if ((gridX0 < mPlayerPos.x) && (mPlayerPos.x < gridX1) && (gridZ0 < mPlayerPos.z) && (mPlayerPos.z < gridZ1)) - mCullStopFlag = true; - else - mCullStopFlag = false; - } + return; } + + if (mWaterHeightMgr.GetHeight(mIdxX, mIdxZ) != 0) { + mCullStopFlag = false; + return; + } + + f32 minX, minZ, maxX, maxZ; + mWaterHeightMgr.GetArea(mIdxX, mIdxZ, &minX, &minZ, &maxX, &maxZ); + + minX += 25600.0f; + minZ += 25600.0f; + maxX -= 25600.0f; + maxZ -= 25600.0f; + + if ((minX < mPlayerPos.x) && (mPlayerPos.x < maxX) && (minZ < mPlayerPos.z) && (mPlayerPos.z < maxZ)) { + mCullStopFlag = true; + return; + } + + mCullStopFlag = false; } /* 8015C11C-8015C1DC .text CheckRoomChange__14daSea_packet_cFv */ @@ -339,13 +497,627 @@ void daSea_execute(cXyz& pos) { } /* 8015C214-8015C75C .text execute__14daSea_packet_cFR4cXyz */ -void daSea_packet_c::execute(cXyz&) { - /* Nonmatching */ +void daSea_packet_c::execute(cXyz& pos) { + mPlayerPos = pos; + mIdxX = mWaterHeightMgr.Pos2Index(mPlayerPos.x, NULL); + mIdxZ = mWaterHeightMgr.Pos2Index(mPlayerPos.z, NULL); + + if (strcmp(dComIfGp_getStartStageName(), "ADMumi") == 0) { + mFlatInter = 0.0f; + } + + if (mRoomNo != dComIfGp_roomControl_getStayNo() && dComIfGp_roomControl_getStayNo() != 0) { + CheckRoomChange(); + } + + CalcFlatInter(); + dKy_usonami_set(mFlatInter); + mDrawMinX = pos.x - 25600.0f; + mDrawMaxX = pos.x + 25600.0f; + mDrawMinZ = pos.z - 25600.0f; + mDrawMaxZ = pos.z + 25600.0f; + SetCullStopFlag(); + + if (mCullStopFlag == 1) { + return; + } + + int h = mWaterHeightMgr.GetHeight(pos.x, pos.z); + + f32 scale = mFlatInter * mWaveInfo.GetScale(h); + + // Vectorization? + s16 aOffsAnimTable [4]; + f32 aThetaXTable [4]; + f32 aThetaZTable [4]; + f32 aHeightTable [4]; + + for (int i = 0; i < 4; i++) { + aThetaXTable[i] = mWaveInfo.GetKm(i) * mWaveInfo.GetVx(i); + aThetaZTable[i] = mWaveInfo.GetKm(i) * mWaveInfo.GetVz(i); + + aOffsAnimTable[i] = 65536.0f * (mWaveInfo.GetRatio(i) - 0.5f); + aHeightTable[i] = mWaveInfo.GetBaseHeight(i) * scale; + } + + scale = mDrawMinZ + 800.0f; + + // Unrolled loops? + + s16 iVar[4]; + // Split up to prevent integer promotion + iVar[0] = cM_rad2s(aThetaZTable[0] * scale); + iVar[1] = cM_rad2s(aThetaZTable[1] * scale); + iVar[2] = cM_rad2s(aThetaZTable[2] * scale); + iVar[3] = cM_rad2s(aThetaZTable[3] * scale); + + iVar[0] -= aOffsAnimTable[0]; + iVar[1] -= aOffsAnimTable[1]; + iVar[2] -= aOffsAnimTable[2]; + iVar[3] -= aOffsAnimTable[3]; + + iVar[0] += mWaveInfo.GetPhai(0); + iVar[1] += mWaveInfo.GetPhai(1); + iVar[2] += mWaveInfo.GetPhai(2); + iVar[3] += mWaveInfo.GetPhai(3); + + s16 waveTheta_DeltaZ[4]; + waveTheta_DeltaZ[0] = cM_rad2s(aThetaZTable[0] * 800.0f); + waveTheta_DeltaZ[1] = cM_rad2s(aThetaZTable[1] * 800.0f); + waveTheta_DeltaZ[2] = cM_rad2s(aThetaZTable[2] * 800.0f); + waveTheta_DeltaZ[3] = cM_rad2s(aThetaZTable[3] * 800.0f); + + s16 waveTheta_DeltaX[4]; + waveTheta_DeltaX[0] = cM_rad2s(aThetaXTable[0] * 800.0f); + waveTheta_DeltaX[1] = cM_rad2s(aThetaXTable[1] * 800.0f); + waveTheta_DeltaX[2] = cM_rad2s(aThetaXTable[2] * 800.0f); + waveTheta_DeltaX[3] = cM_rad2s(aThetaXTable[3] * 800.0f); + + scale = mDrawMinX + 800.0f; + + s16 waveTheta_Phase[4]; + waveTheta_Phase[0] = cM_rad2s(aThetaXTable[0] * scale); + waveTheta_Phase[1] = cM_rad2s(aThetaXTable[1] * scale); + waveTheta_Phase[2] = cM_rad2s(aThetaXTable[2] * scale); + waveTheta_Phase[3] = cM_rad2s(aThetaXTable[3] * scale); + + f32 aFadeTable [65]; + + for (int fadeZ = 0; fadeZ < 65; fadeZ++) { + aFadeTable[fadeZ] = 1.0f; + } + + // Probably unrolled loop + f32 frac = 1.0f / 6; + aFadeTable[64] = frac * 0; + aFadeTable[0] = frac * 0; + aFadeTable[63] = frac * 1; + aFadeTable[1] = frac * 1; + aFadeTable[62] = frac * 2; + aFadeTable[2] = frac * 2; + aFadeTable[61] = frac * 3; + aFadeTable[3] = frac * 3; + aFadeTable[60] = frac * 4; + aFadeTable[4] = frac * 4; + aFadeTable[59] = frac * 5; + aFadeTable[5] = frac * 5; + + for (int z = 1; z < 0x40; z++) { + f32* pHeight = mpHeightTable + 65 * z + 1; + s16 waveTheta0 = waveTheta_Phase[0]; + waveTheta0 += iVar[0]; + s16 waveTheta1 = waveTheta_Phase[1]; + waveTheta1 += iVar[1]; + s16 waveTheta2 = waveTheta_Phase[2]; + waveTheta2 += iVar[2]; + s16 waveTheta3 = waveTheta_Phase[3]; + waveTheta3 += iVar[3]; + + for (int x = 1; x < 0x40; x++) { + *pHeight = aHeightTable[0] * cM_scos(waveTheta0) + + aHeightTable[1] * cM_scos(waveTheta1) + + aHeightTable[2] * cM_scos(waveTheta2) + + aHeightTable[3] * cM_scos(waveTheta3) + + BASE_HEIGHT; + + *pHeight *= aFadeTable[z] * aFadeTable[x]; + waveTheta0 += waveTheta_DeltaX[0]; + waveTheta1 += waveTheta_DeltaX[1]; + waveTheta2 += waveTheta_DeltaX[2]; + waveTheta3 += waveTheta_DeltaX[3]; + + pHeight++; + } + + iVar[0] += waveTheta_DeltaZ[0]; + iVar[1] += waveTheta_DeltaZ[1]; + iVar[2] += waveTheta_DeltaZ[2]; + iVar[3] += waveTheta_DeltaZ[3]; + } + + mWaveInfo.AddCounter(); + mCurPos = pos; } /* 8015C75C-8015D80C .text draw__14daSea_packet_cFv */ void daSea_packet_c::draw() { - /* Nonmatching */ + if (ChkCullStop()) return; + + m_draw_vtx = (cXyz*)mDoGph_gInf_c::alloc(0xC60C, 0x20); + if (m_draw_vtx == NULL) { + return; + } + + JUT_ASSERT(0x518, m_draw_vtx != 0); // Redundant assert + + j3dSys.reinitGX(); + + + cXyz* vtx = m_draw_vtx; + f32* pY = mpHeightTable; + + f32 minZ = getMinZ(); + for (int z = 0; z < 65; z++) { + f32 minX = getMinX(); + for (int x = 0; x < 65; x++) { + (*vtx).x = minX; + (*vtx).y = *pY; + (*vtx).z = minZ; + minX += 800.0f; + vtx++; + pY++; + } + + minZ += 800.0f; + } + + DCStoreRange(m_draw_vtx, 0xC60C); + + ResTIMG* pResTIMG = static_cast(dComIfG_getObjectRes("Always", ALWAYS_BTI_B_SEA_TEX0AND2)); + + GXBool mipmap = pResTIMG->mipmapCount > 1; + GXInitTexObj(&mTexSea0, (&pResTIMG->format + pResTIMG->imageOffset), pResTIMG->width, pResTIMG->height, + (GXTexFmt)pResTIMG->format, (GXTexWrapMode)pResTIMG->wrapS, (GXTexWrapMode)pResTIMG->wrapT, + mipmap); + + GXInitTexObjLOD(&mTexSea0, (GXTexFilter)pResTIMG->minFilter, (GXTexFilter)pResTIMG->magFilter, + pResTIMG->minLOD * 0.125f, pResTIMG->maxLOD * 0.125f, -0.9f, + (GXBool)pResTIMG->biasClamp, (GXBool)pResTIMG->doEdgeLOD, + (GXAnisotropy)pResTIMG->maxAnisotropy); + + mipmap = pResTIMG->mipmapCount > 1; + GXInitTexObj(&mTexSea1, (&pResTIMG->format + pResTIMG->imageOffset), pResTIMG->width, pResTIMG->height, + (GXTexFmt)pResTIMG->format, (GXTexWrapMode)pResTIMG->wrapS, (GXTexWrapMode)pResTIMG->wrapT, + mipmap); + + GXInitTexObjLOD(&mTexSea1, (GXTexFilter)pResTIMG->minFilter, (GXTexFilter)pResTIMG->magFilter, + pResTIMG->minLOD * 0.125f, pResTIMG->maxLOD * 0.125f, 1.0f, + (GXBool)pResTIMG->biasClamp, (GXBool)pResTIMG->doEdgeLOD, + (GXAnisotropy)pResTIMG->maxAnisotropy); + + pResTIMG = static_cast(dComIfG_getObjectRes("Always", ALWAYS_BTI_B_WYURAYURA_TEX1)); + mDoLib_setResTimgObj(pResTIMG, &mTexYura, 0, NULL); + mDoMtx_stack_c::scaleS(1.5f, 1.5f, 1.0f); + GXLoadTexMtxImm(mDoMtx_stack_c::get(), GX_TEXMTX0, GX_MTX2x4); + GXLoadTexObj(&mTexSea0, GX_TEXMAP0); + + mAnimCounter += 1; + + if (mAnimCounter > 300) { + mAnimCounter = 0; + } + + mDoMtx_stack_c::transS(0.0f, mAnimCounter / 300.0f, 0.0f); + GXLoadTexMtxImm(mDoMtx_stack_c::get(), GX_TEXMTX1, GX_MTX2x4); + GXLoadTexObj(&mTexYura, GX_TEXMAP1); + GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD1, GX_TEXMAP1); + + static f32 offset[6]; + + offset[0] = 0.3f; + offset[1] = 0.0f; + offset[2] = 0.0f; + offset[3] = 0.0f; + offset[4] = 0.3f; + offset[5] = 0.0f; + + GXSetIndTexMtx(GX_ITM_0, (f32*) offset, -1); + GXSetTevIndWarp(GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_TRUE, GX_FALSE, GX_ITM_0); + GXSetTevIndWarp(GX_TEVSTAGE1, GX_INDTEXSTAGE0, GX_TRUE, GX_FALSE, GX_ITM_0); + mDoMtx_stack_c::transS(0.2f, -0.2f, 0.0f); + GXLoadTexMtxImm(mDoMtx_stack_c::get(), GX_TEXMTX2, GX_MTX2x4); + GXLoadTexObj(&mTexSea1, GX_TEXMAP2); + + GXColor colorAmb, colorDif; + dKy_get_seacolor(&colorAmb, &colorDif); + + f32 tmp = mFlatInter * mFlatInter; + + GXColor color1; + color1.r = colorDif.r + tmp * ((f32)colorAmb.r - (f32)colorDif.r); + color1.g = colorDif.g + tmp * ((f32)colorAmb.g - (f32)colorDif.g); + color1.b = colorDif.b + tmp * ((f32)colorAmb.b - (f32)colorDif.b); + color1.a = 0xFF; + + f32 f = 1.0f / 10; + + f32 r; + f32 g; + f32 b; + f32 tmp_2; + tmp_2 = 1.0f - f * tmp; + + r = colorDif.r * tmp_2; + g = colorDif.g * tmp_2; + b = colorDif.b * tmp_2; + + if (r > 255.0f) { + r = 255.0f; + } + + if (g > 255.0f) { + g = 255.0f; + } + + if (b > 255.0f) { + b = 255.0f; + } + + GXColor color2;// = {(u8) r, (u8) g, (u8) b}; + color2.r = r; + color2.g = g; + color2.b = b; + color2.a = 0xFF; + + GXSetTevColor(GX_TEVREG0, colorDif); + GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + GXSetTevKColorSel(GX_TEVSTAGE1, GX_TEV_KCSEL_K1); + + GXSetTevKColor(GX_KCOLOR0, color1); + GXSetTevKColor(GX_KCOLOR1, color2); + + GXSetNumIndStages(1); + GXSetNumChans(0); + GXSetNumTexGens(3); + GXSetNumTevStages(3); + GXSetCullMode(GX_CULL_BACK); + GXSetCoPlanar(GX_FALSE); + + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX1, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX2, GX_FALSE, GX_PTIDENTITY); + + GXSetTevOrder(GX_TEVSTAGE0,GX_TEXCOORD0,GX_TEXMAP0,GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE0,GX_CC_C0,GX_CC_KONST,GX_CC_TEXC,GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0,GX_TEV_ADD,GX_TB_ZERO,GX_CS_SCALE_1,true,GX_TEVREG2); + GXSetTevAlphaIn(GX_TEVSTAGE0,GX_CA_ZERO,GX_CA_KONST,GX_CA_TEXA,GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0,GX_TEV_ADD,GX_TB_ZERO,GX_CS_SCALE_1,true,GX_TEVPREV); + GXSetTevSwapMode(GX_TEVSTAGE0,GX_TEV_SWAP0,GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE1,GX_TEXCOORD2,GX_TEXMAP2,GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1,GX_CC_C0,GX_CC_KONST,GX_CC_TEXC,GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1,GX_TEV_ADD,GX_TB_ZERO,GX_CS_SCALE_1,true,GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1,GX_CA_APREV,GX_CA_ZERO,GX_CA_ZERO,GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE1,GX_TEV_ADD,GX_TB_ZERO,GX_CS_SCALE_1,true,GX_TEVPREV); + GXSetTevSwapMode(GX_TEVSTAGE1,GX_TEV_SWAP0,GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE2,GX_TEXCOORD_NULL,GX_TEXMAP_NULL,GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE2,GX_CC_CPREV,GX_CC_C2,GX_CC_APREV,GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE2,GX_TEV_ADD,GX_TB_ZERO,GX_CS_SCALE_1,true,GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE2,GX_CA_ZERO,GX_CA_KONST,GX_CA_APREV,GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE2,GX_TEV_ADD,GX_TB_ZERO,GX_CS_SCALE_1,true,GX_TEVPREV); + GXSetTevSwapMode(GX_TEVSTAGE2,GX_TEV_SWAP0,GX_TEV_SWAP0); + GXSetAlphaCompare(GX_ALWAYS,0,GX_AOP_OR,GX_ALWAYS,0); + GXSetZCompLoc(GX_TRUE); + GXSetPixelFmt(GX_PF_RGBA6_Z24,GX_ZC_LINEAR); + GXSetZMode(true,GX_LEQUAL,true); + GXSetBlendMode(GX_BM_NONE,GX_BL_ZERO,GX_BL_ZERO,GX_LO_CLEAR); + GXSetColorUpdate(GX_TRUE); + GXSetAlphaUpdate(GX_FALSE); + GXSetDither(GX_TRUE); + + dKy_GxFog_sea_set(); + + GXLoadPosMtxImm(j3dSys.getViewMtx(), 0); + GXSetClipMode(GX_CLIP_ENABLE); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS,GX_INDEX16); + GXSetVtxDesc(GX_VA_TEX0,GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0,GX_VA_POS,GX_CLR_RGBA,GX_F32,0); + GXSetVtxAttrFmt(GX_VTXFMT0,GX_VA_TEX0,GX_CLR_RGBA,GX_F32,0); + GXSetArray(GX_VA_POS, this->m_draw_vtx, 0xc); + + // TODO: Remove magic numbers + + // 1.0f / 2000 + f32 frac = 0.0005000001f; // Fakematch + + cXyz* pVtx; + u16 idx2; + int z; + u16 idx1; + idx1 = 0; + idx2 = 65; + + pVtx = m_draw_vtx; + + f32 prevTexZ; + f32 texZ = frac * (*pVtx).z; + for (z = 0; z < 64; z++) { + prevTexZ = texZ; + texZ = frac * ((*pVtx).z + 800.0f); + + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 65 * 2); + + for (int x = 0; x < 65; x++) { + f32 texX = frac * (*pVtx).x; + GXPosition1x16(idx2); + GXTexCoord2f32(texX, texZ); + GXPosition1x16(idx1); + GXTexCoord2f32(texX, prevTexZ); + idx1++; + idx2++; + + pVtx++; + }; + + GXEnd(); + } + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + + f32 dVar14; + + f32 posZ; + if (getMinZ() > -450000.0f) { + int end = (getMinZ() - (-450000.0f)) / 225000.0f; + posZ = -450000.0f; + texZ = posZ * frac; + + for (int z = 0; z < end; z++) { + prevTexZ = texZ; + dVar14 = 225000.0f + posZ; + texZ = frac * dVar14; + + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 10); + f32 texX; + f32 posX = -450000.0f; + for (int x = 0; x < 5; x++) { + texX = frac * posX; + GXPosition3f32(posX, BASE_HEIGHT, dVar14); + GXTexCoord2f32(texX, texZ); + + GXPosition3f32(posX, BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + + posX += 225000.0f; + } + + GXEnd(); + + posZ += 225000.0f; + } + + if (posZ < getMinZ()) { + prevTexZ = texZ; + texZ = getMinZ() * frac; + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 10); + f32 texX; + f32 posX = -450000.0f; + for (int i = 0; i < 5; i++) { + texX = frac * posX; + GXPosition3f32(posX, BASE_HEIGHT, getMinZ()); + GXTexCoord2f32(texX, texZ); + GXPosition3f32(posX, BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + + posX += 225000.0f; + } + + GXEnd(); + } + } + + if (getMaxZ() < 450000.0f) { + posZ = getMaxZ(); + int i; + int end = (450000.0f - getMaxZ()) / 225000.0f; + texZ = frac * posZ; + + for (i = 0; i < end; i++) { + prevTexZ = texZ; + f32 f30 = posZ + 225000.0f; + texZ = frac * f30; + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 10); + f32 texX; + f32 posX = -450000.0f; + for (int x = 0; x < 5; x++) { + texX = frac * posX; + GXPosition3f32(posX, BASE_HEIGHT, f30); + GXTexCoord2f32(texX, texZ); + + GXPosition3f32(posX, BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + + posX += 225000.0f; + } + + GXEnd(); + + posZ += 225000.0f; + } + + if (posZ < 450000.0f) { + prevTexZ = texZ; + texZ = 450000.0f * frac; + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 10); + f32 texX; + f32 posX = -450000.0f; + for (int x = 0; x < 5; x++) { + texX = frac * posX; + GXPosition3f32(posX, BASE_HEIGHT, 450000.0f); + GXTexCoord2f32(texX, texZ); + GXPosition3f32(posX, BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + + posX += 225000.0f; + } + } + } + + if (getMaxZ() > getMinZ()) { + int temp_r26; + int end = (getMaxZ() - getMinZ()) / 225000.0f; + posZ = getMinZ(); + if (getMinX() > -450000.0f) { + f32 temp_f3 = getMinX() - (-450000.0f); + temp_r26 = temp_f3 / 225000.0f; + + // Check if value gets truncated? + int trunc = 225000.0f * temp_r26 < temp_f3 ? 1 : 0; + + texZ = frac * posZ; + int z = 0; + + // Might be equivalent to ceil(temp_f3 / 225000.0f) + int count = temp_r26 + trunc; + + for (; z < end; z++) { + prevTexZ = texZ; + texZ = frac * 450000.0f; + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, (1+count) * 2); + + f32 texX; + f32 posX = -450000.0f; + + for (int x = 0; x <= temp_r26; x++) { + texX = frac * posX; + + GXPosition3f32(posX, BASE_HEIGHT, posZ + 225000.0f); + GXTexCoord2f32(texX, frac * 450000.0f); + GXPosition3f32(posX, BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + posX += 225000.0f; + } + + if (trunc) { + texX = frac * getMinX(); + GXPosition3f32(getMinX(), BASE_HEIGHT, posZ + 225000.0f); + GXTexCoord2f32(texX, frac * 450000.0f); + GXPosition3f32(getMinX(), BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + } + + GXEnd(); + + posZ += 225000.0f; + } + + if (posZ < getMaxZ()) { + prevTexZ = texZ; + texZ = frac * getMaxZ(); + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, (1+count) * 2); + + f32 texX; + f32 posX = -450000.0f; + for (int x = 0; x <= temp_r26; x++) { + texX = frac * posX; + GXPosition3f32(posX, BASE_HEIGHT, getMaxZ()); + GXTexCoord2f32(texX, texZ); + GXPosition3f32(posX, BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + posX += 225000.0f; + } + + if (trunc != 0) { + texX = frac * getMinX(); + GXPosition3f32(getMinX(), BASE_HEIGHT, getMaxZ()); + GXTexCoord2f32(texX, texZ); + GXPosition3f32(getMinX(), BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + } + + GXEnd(); + } + } + + if (getMaxX() < 450000.0f) { + int z; + f32 temp_f3_3 = 450000.0f - getMaxX(); + int temp_r26_2 = temp_f3_3 / 225000.0f; + + // Check if value gets truncated? + int trunc = 225000.0f * temp_r26_2 < temp_f3_3 ? 1 : 0; + + posZ = getMinZ(); + texZ = frac * posZ; + z = 0; + + // Might be equivalent to ceil(temp_3_3 / 225000.0f) + int count = temp_r26_2 + trunc; + + for (; z < end; z++) { + + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, (1+count) * 2); + + f32 texX; + f32 posX = getMaxX(); + for (int x = 0; x <= temp_r26_2; x++) { + texX = frac * posX; + GXPosition3f32(posX, BASE_HEIGHT, posZ + 225000.0f); + GXTexCoord2f32(texX, texZ); + GXPosition3f32(posX, BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + + posX += 225000.0f; + } + + if (trunc != 0) { + GXPosition3f32(450000.0f, BASE_HEIGHT, posZ + 225000.0f); + GXTexCoord2f32(frac * 450000.0f, texZ); + GXPosition3f32(450000.0f, BASE_HEIGHT, posZ); + GXTexCoord2f32(frac * 450000.0f, prevTexZ); + } + + GXEnd(); + + posZ += 225000.0f; + } + + if (posZ < getMaxZ()) { + prevTexZ = texZ; + texZ = frac * getMaxZ(); + + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, (1+count) * 2); + + f32 texX; + f32 posX = getMaxX(); + + for (int x = 0; x <= temp_r26_2; x++) { + texX = frac * posX; + GXPosition3f32(posX, BASE_HEIGHT, getMaxZ()); + GXTexCoord2f32(texX, texZ); + GXPosition3f32(posX, BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + + posX += 225000.0f; + } + + if (trunc != 0) { + texX = 450000.0f * frac; + GXPosition3f32(450000.0f, BASE_HEIGHT, getMaxZ()); + GXTexCoord2f32(texX, texZ); + GXPosition3f32(450000.0f, BASE_HEIGHT, posZ); + GXTexCoord2f32(texX, prevTexZ); + } + + GXEnd(); + } + } + } + + GXSetNumIndStages(0); + J3DShape::resetVcdVatCache(); } /* 8015D80C-8015D87C .text daSea_Draw__FP9sea_class */