diff --git a/include/functions.h b/include/functions.h index 0e8e418b2f..66365fefe5 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1570,7 +1570,7 @@ void Check_RegionIsSupported(void); f32 Math3D_Normalize(Vec3f* vec); s32 Math3D_PlaneVsLineSegClosestPoint(f32 planeAA, f32 planeAB, f32 planeAC, f32 planeADist, f32 planeBA, f32 planeBB, f32 planeBC, f32 planeBDist, Vec3f* linePointA, Vec3f* linePointB, Vec3f* closestPoint); s32 func_80179798(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3, Vec3f* param_4, Vec3f* param_5, Vec3f* param_6); -void func_80179A44(Vec3f* arg0, PosRot* arg1, Vec3f* arg2); +f32 func_80179A44(Vec3f* arg0, PosRot* arg1, Vec3f* arg2); void func_80179B34(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32* arg7, f32* arg8); // UNK_TYPE4 func_80179B94(f32 fParm1, f32 fParm2, f32 fParm5, f32 param_4, f32 param_5, f32 param_6, f32 param_7, f32 param_8, Vec3f* param_9); // void func_80179D74(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10); diff --git a/spec b/spec index 4c1028b780..781efb202c 100644 --- a/spec +++ b/spec @@ -3644,8 +3644,7 @@ beginseg name "ovl_Obj_Wind" compress include "build/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.o" - include "build/data/ovl_Obj_Wind/ovl_Obj_Wind.data.o" - include "build/data/ovl_Obj_Wind/ovl_Obj_Wind.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Wind/ovl_Obj_Wind_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.c b/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.c index 5f53030f32..3b6b907312 100644 --- a/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.c +++ b/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.c @@ -5,6 +5,7 @@ */ #include "z_obj_wind.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS (ACTOR_FLAG_10) @@ -15,7 +16,6 @@ void ObjWind_Destroy(Actor* thisx, PlayState* play); void ObjWind_Update(Actor* thisx, PlayState* play); void ObjWind_Draw(Actor* thisx, PlayState* play); -#if 0 ActorInit Obj_Wind_InitVars = { ACTOR_OBJ_WIND, ACTORCAT_ITEMACTION, @@ -28,21 +28,140 @@ ActorInit Obj_Wind_InitVars = { (ActorFunc)ObjWind_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B24480[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 4000, ICHAIN_STOP), }; -#endif +void ObjWind_Init(Actor* thisx, PlayState* play) { + ObjWind* this = (ObjWind*)thisx; + s32 pad; + WaterBox* waterbox; + f32 ySurface; -extern InitChainEntry D_80B24480[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + if (WaterBox_GetSurface1(play, &play->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &ySurface, + &waterbox) && + (this->actor.world.pos.y < ySurface)) { + this->isUnderWater = true; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wind/ObjWind_Init.s") +void ObjWind_Destroy(Actor* thisx, PlayState* play) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wind/ObjWind_Destroy.s") +typedef struct ObjWindStruct { + /* 0x0 */ s16 unk_0; + /* 0x2 */ s16 unk_2; + /* 0x4 */ s16 unk_4; + /* 0x6 */ s16 unk_6; + /* 0x8 */ s16 unk_8; +} ObjWindStruct; // size = 0xA -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wind/ObjWind_Update.s") +static ObjWindStruct D_80B2448C[] = { + { 530, 90, 3000, 2000, 0 }, { 1120, 100, 2000, 1000, 0 }, { 620, 100, 2000, 1000, 0 }, + { 1620, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, + { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, + { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, + { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, + { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, + { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, + { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, + { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, { 400, 100, 2000, 1000, 0 }, + { 400, 100, 2000, 1000, 0 }, { 600, 120, 3000, 2000, 0 }, { 500, 80, 3000, 2000, 0 }, + { 400, 60, 2000, 2000, 0 }, { 470, 70, 2000, 1000, 0 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wind/ObjWind_Draw.s") +static s32 D_80B245CC = -1; + +void ObjWind_Update(Actor* thisx, PlayState* play) { + ObjWind* this = (ObjWind*)thisx; + ObjWindStruct* entry = &D_80B2448C[OBJ_WIND_GET_TYPE(thisx)]; + Player* player; + f32 upZ; + f32 upY; + f32 upX; + Vec3f posCopy; + Vec3f nearestPoint; + Vec3f sp54; + f32 upXZ; // reused temp + f32 distToNearestPoint; + + if (D_80B245CC != DREG(85)) { + if ((DREG(85) >= 0) && (DREG(85) < ARRAY_COUNT(D_80B2448C))) { + DREG(80) = D_80B2448C[DREG(85)].unk_0; + DREG(81) = D_80B2448C[DREG(85)].unk_2; + DREG(82) = D_80B2448C[DREG(85)].unk_4; + DREG(83) = D_80B2448C[DREG(85)].unk_6; + DREG(84) = D_80B2448C[DREG(85)].unk_8; + D_80B245CC = DREG(85); + } + } else { + D_80B2448C[DREG(85)].unk_0 = DREG(80); + D_80B2448C[DREG(85)].unk_2 = DREG(81); + D_80B2448C[DREG(85)].unk_4 = DREG(82); + D_80B2448C[DREG(85)].unk_6 = DREG(83); + D_80B2448C[DREG(85)].unk_8 = DREG(84); + } + + if ((OBJ_WIND_GET_SWITCH_FLAG(thisx) == 0x7F) || !Flags_GetSwitch(play, OBJ_WIND_GET_SWITCH_FLAG(thisx))) { + player = GET_PLAYER(play); + Math_Vec3f_Copy(&posCopy, &this->actor.world.pos); + upY = Math_CosS(this->actor.shape.rot.x); + upXZ = Math_SinS(this->actor.shape.rot.x); + upX = Math_SinS(this->actor.shape.rot.y) * upXZ; + upZ = Math_CosS(this->actor.shape.rot.y) * upXZ; + distToNearestPoint = func_80179A44(&posCopy, &player->actor.world, &nearestPoint); + if ((distToNearestPoint >= 0.0f) && (distToNearestPoint < entry->unk_0)) { + upXZ = Math_Vec3f_DistXYZAndStoreDiff(&player->actor.world.pos, &nearestPoint, &sp54); + if (upXZ < entry->unk_2) { + f32 var_fa0; + f32 windSpeedXZ = 1.0f; // reused temp + f32 windMagnitude; + f32 temp_ft0; + f32 windSpeedX; + f32 windSpeedY; + f32 windSpeedZ; + + var_fa0 = 1.0f - distToNearestPoint / entry->unk_0; + windMagnitude = ((f32)entry->unk_4 / 100.0f) * + ((var_fa0 * (1.0f - upXZ / entry->unk_2)) + ((f32)entry->unk_8 / 100.0f)); + if ((distToNearestPoint / entry->unk_0) > 0.8f) { + var_fa0 = windSpeedXZ - 1.0f; + } + temp_ft0 = ((f32)entry->unk_6 / 100.0f) * (upXZ / entry->unk_2 * var_fa0); + if (upXZ != 0.0f) { + // FAKE: + if (1) {} + upXZ = 1.0f / upXZ; + } + temp_ft0 *= upXZ; + windSpeedX = (upX * windMagnitude) + (sp54.x * temp_ft0); + windSpeedY = (upY * windMagnitude) + (sp54.y * temp_ft0); + windSpeedZ = (upZ * windMagnitude) + (sp54.z * temp_ft0); + player->windSpeed = sqrtf(SQ(windSpeedX) + SQ(windSpeedY) + SQ(windSpeedZ)); + player->windAngleY = Math_Atan2S_XY(windSpeedZ, windSpeedX); + + windSpeedXZ = sqrtf(SQ(windSpeedX) + SQ(windSpeedZ)); + player->windAngleX = Math_Atan2S_XY(windSpeedXZ, windSpeedY); + } + } + } + this->actor.scale.x = (f32)entry->unk_2 / 50.0f; + this->actor.scale.z = (f32)entry->unk_2 / 50.0f; + this->actor.scale.y = (f32)entry->unk_0 / 400.0f; +} + +void ObjWind_Draw(Actor* thisx, PlayState* play) { + ObjWind* this = (ObjWind*)thisx; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(&gameplay_keep_Matanimheader_07F218)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07E8C0); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.h b/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.h index 08db8914ad..7c1ecc66eb 100644 --- a/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.h +++ b/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.h @@ -3,11 +3,14 @@ #include "global.h" +#define OBJ_WIND_GET_TYPE(thisx) (((thisx)->params >> 7) & 0x1F) +#define OBJ_WIND_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) + struct ObjWind; typedef struct ObjWind { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x4]; + /* 0x144 */ u8 isUnderWater; } ObjWind; // size = 0x148 #endif // Z_OBJ_WIND_H diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index d856a56ddf..04d8933100 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -13845,7 +13845,7 @@ 0x80B23C70:("D_80B23C70","f32","",0x4), 0x80B23E80:("Obj_Dowsing_InitVars","UNK_TYPE1","",0x1), 0x80B24460:("Obj_Wind_InitVars","UNK_TYPE1","",0x1), - 0x80B24480:("D_80B24480","UNK_TYPE1","",0x1), + 0x80B24480:("sInitChain","UNK_TYPE1","",0x1), 0x80B2448C:("D_80B2448C","UNK_TYPE1","",0x1), 0x80B245CC:("D_80B245CC","UNK_TYPE4","",0x4), 0x80B245D0:("D_80B245D0","f32","",0x4),