1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-06 14:20:11 +00:00

ovl_En_Butte (#440)

* ovl_En_Butte

* Delete asm and inline static data

* Style

* PR review
This commit is contained in:
maekclena 2020-10-11 15:21:12 +02:00 committed by GitHub
parent 6b3b4aa883
commit 9d35542207
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 400 additions and 1479 deletions

View file

@ -1,3 +1,9 @@
/*
* File: z_en_butte.c
* Overlay: ovl_En_Butte
* Description: Butterfly
*/
#include "z_en_butte.h"
#define FLAGS 0x00000000
@ -9,7 +15,25 @@ void EnButte_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnButte_Update(Actor* thisx, GlobalContext* globalCtx);
void EnButte_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void EnButte_SetupFlyAround(EnButte* this);
void EnButte_FlyAround(EnButte* this, GlobalContext* globalCtx);
void EnButte_SetupFollowLink(EnButte* this);
void EnButte_FollowLink(EnButte* this, GlobalContext* globalCtx);
void EnButte_SetupTransformIntoFairy(EnButte* this);
void EnButte_TransformIntoFairy(EnButte* this, GlobalContext* globalCtx);
void EnButte_SetupWaitToDie(EnButte* this);
void EnButte_WaitToDie(EnButte* this, GlobalContext* globalCtx);
static ColliderJntSphItemInit sColliderItemInit[] = {
{ { 0x00, { 0x00000000, 0x00, 0x00 }, { 0xFFCFFFFF, 0x000, 0x00 }, 0x00, 0x00, 0x01 },
{ 0, { { 0, 0, 0 }, 5 }, 100 } }
};
static ColliderJntSphInit sColliderInit = {
{ COLTYPE_UNK10, 0x00, 0x00, 0x19, 0x10, COLSHAPE_JNTSPH },
1,
sColliderItemInit,
};
const ActorInit En_Butte_InitVars = {
ACTOR_EN_BUTTE,
ACTORTYPE_ITEMACTION,
@ -21,41 +45,374 @@ const ActorInit En_Butte_InitVars = {
(ActorFunc)EnButte_Update,
(ActorFunc)EnButte_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CD070.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CD0F8.s")
typedef struct {
/* 0x00 */ s16 minTime;
/* 0x02 */ s16 maxTime;
/* 0x04 */ f32 speedXZTarget;
/* 0x08 */ f32 speedXZScale;
/* 0x0C */ f32 speedXZStep;
/* 0x10 */ s16 rotYStep;
} EnButteFlightParams; // size = 0x14
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CD110.s")
static EnButteFlightParams sFlyAroundParams[] = {
{ 5, 35, 0.0f, 0.1f, 0.5f, 0 },
{ 10, 45, 1.1f, 0.1f, 0.25f, 1000 },
{ 10, 40, 1.5f, 0.1f, 0.3f, 2000 },
};
static EnButteFlightParams sFollowLinkParams[] = {
{ 3, 3, 0.8f, 0.1f, 0.2f, 0 },
{ 10, 20, 2.0f, 0.3f, 1.0f, 0 },
{ 10, 20, 2.4f, 0.3f, 1.0f, 0 },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CD144.s")
extern AnimationHeader D_05002470;
extern SkeletonHeader D_050036F0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/EnButte_Init.s")
void EnButte_SelectFlightParams(EnButte* this, EnButteFlightParams* flightParams) {
if (this->flightParamsIdx == 0) {
if (Math_Rand_ZeroOne() < 0.6f) {
this->flightParamsIdx = 1;
} else {
this->flightParamsIdx = 2;
}
} else {
this->flightParamsIdx = 0;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/EnButte_Destroy.s")
this->timer = Math_Rand_S16Offset(flightParams->minTime, flightParams->maxTime);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CD56C.s")
static f32 sTransformationEffectScale = 0.0f;
static s16 sTransformationEffectAlpha = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CD634.s")
void EnButte_ResetTransformationEffect(void) {
sTransformationEffectScale = 0.0f;
sTransformationEffectAlpha = 0;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CD6FC.s")
void EnButte_UpdateTransformationEffect(void) {
sTransformationEffectScale += 0.003f;
sTransformationEffectAlpha += 4000;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CD79C.s")
void EnButte_DrawTransformationEffect(EnButte* this, GlobalContext* globalCtx) {
static Vec3f D_809CE3C4 = { 0.0f, 0.0f, -3.0f };
Vec3f sp5C;
s32 alpha;
Vec3s camDir;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CD7E8.s")
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_choo.c", 295);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CDBCC.s")
func_80093C14(globalCtx->state.gfxCtx);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CDC18.s")
alpha = Math_Sins(sTransformationEffectAlpha) * 250;
alpha = CLAMP(alpha, 0, 255);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CDFC4.s")
func_8005A970(&camDir, ACTIVE_CAM);
Matrix_RotateY(camDir.y * (M_PI / 0x8000), MTXMODE_NEW);
Matrix_RotateX(camDir.x * (M_PI / 0x8000), MTXMODE_APPLY);
Matrix_RotateZ(camDir.z * (M_PI / 0x8000), MTXMODE_APPLY);
Matrix_MultVec3f(&D_809CE3C4, &sp5C);
func_800D1694(this->actor.posRot2.pos.x + sp5C.x, this->actor.posRot2.pos.y + sp5C.y,
this->actor.posRot2.pos.z + sp5C.z, &camDir);
Matrix_Scale(sTransformationEffectScale, sTransformationEffectScale, sTransformationEffectScale, MTXMODE_APPLY);
gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_choo.c", 317),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetPrimColor(oGfxCtx->polyXlu.p++, 0x80, 0x80, 200, 200, 180, alpha);
gDPSetEnvColor(oGfxCtx->polyXlu.p++, 200, 200, 210, 255);
gSPDisplayList(oGfxCtx->polyXlu.p++, SEGMENTED_TO_VIRTUAL(&D_04010130));
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CE014.s")
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_choo.c", 326);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CE0D0.s")
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 700, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 20, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 600, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/func_809CE0EC.s")
void EnButte_Init(Actor* thisx, GlobalContext* globalCtx) {
EnButte* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/EnButte_Update.s")
if (this->actor.params == -1) {
this->actor.params = 0;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Butte/EnButte_Draw.s")
Actor_ProcessInitChain(&this->actor, sInitChain);
if ((this->actor.params & 1) == 1) {
this->actor.uncullZoneScale = 200.0f;
}
SkelAnime_Init(globalCtx, &this->skelAnime, &D_050036F0, &D_05002470, this->limbDrawTable,
this->transitionDrawTable, 8);
Collider_InitJntSph(globalCtx, &this->collider);
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderInit, this->colliderItems);
this->actor.colChkInfo.mass = 0;
this->unk_25C = Math_Rand_ZeroOne() * 0xFFFF;
this->unk_25E = Math_Rand_ZeroOne() * 0xFFFF;
this->unk_260 = Math_Rand_ZeroOne() * 0xFFFF;
SkelAnime_ChangeAnim(&this->skelAnime, &D_05002470, 1.0f, 0.0f, 0.0f, 1, 0.0f);
EnButte_SetupFlyAround(this);
this->actor.shape.rot.x -= 0x2320;
this->drawSkelAnime = true;
// "field keep butterfly"
osSyncPrintf("(field keep 蝶)(%x)(arg_data 0x%04x)\n", this, this->actor.params);
}
void EnButte_Destroy(Actor* thisx, GlobalContext* globalCtx) {
Collider_DestroyJntSph(globalCtx, &THIS->collider);
}
void func_809CD56C(EnButte* this) {
static f32 D_809CE3E0[] = { 50.0f, 80.0f, 100.0f };
static f32 D_809CE3EC[] = { 30.0f, 40.0f, 50.0f };
this->actor.shape.unk_08 += Math_Sins(this->unk_25C) * D_809CE3E0[this->flightParamsIdx] +
Math_Sins(this->unk_25E) * D_809CE3EC[this->flightParamsIdx];
this->actor.shape.unk_08 = CLAMP(this->actor.shape.unk_08, -2000.0f, 2000.0f);
}
void func_809CD634(EnButte* this) {
static f32 D_809CE3F8[] = { 15.0f, 20.0f, 25.0f };
static f32 D_809CE404[] = { 7.5f, 10.0f, 12.5f };
this->actor.shape.unk_08 += Math_Sins(this->unk_25C) * D_809CE3F8[this->flightParamsIdx] +
Math_Sins(this->unk_25E) * D_809CE404[this->flightParamsIdx];
this->actor.shape.unk_08 = CLAMP(this->actor.shape.unk_08, -500.0f, 500.0f);
}
void EnButte_Turn(EnButte* this) {
s16 target = this->actor.posRot.rot.y + 0x8000;
s16 diff = target - this->actor.shape.rot.y;
Math_ApproxUpdateScaledS(&this->actor.shape.rot.y, target, ABS(diff) >> 3);
this->actor.shape.rot.x = (s16)(sinf(this->unk_260) * 600.0f) - 0x2320;
}
void EnButte_SetupFlyAround(EnButte* this) {
EnButte_SelectFlightParams(this, &sFlyAroundParams[this->flightParamsIdx]);
this->actionFunc = EnButte_FlyAround;
}
void EnButte_FlyAround(EnButte* this, GlobalContext* globalCtx) {
EnButteFlightParams* flightParams = &sFlyAroundParams[this->flightParamsIdx];
s16 yaw;
Player* player = PLAYER;
f32 distSqFromHome;
f32 maxDistSqFromHome;
f32 minAnimSpeed;
f32 animSpeed;
s16 rotStep;
distSqFromHome = Math3D_Dist2DSq(this->actor.posRot.pos.x, this->actor.posRot.pos.z, this->actor.initPosRot.pos.x,
this->actor.initPosRot.pos.z);
func_809CD56C(this);
Math_SmoothScaleMaxMinF(&this->actor.speedXZ, flightParams->speedXZTarget, flightParams->speedXZScale,
flightParams->speedXZStep, 0.0f);
if (this->unk_257 == 1) {
maxDistSqFromHome = SQ(100.0f);
rotStep = 1000;
} else {
maxDistSqFromHome = SQ(35.0f);
rotStep = 600;
}
minAnimSpeed = 0.0f;
this->posYTarget = this->actor.initPosRot.pos.y;
if ((this->flightParamsIdx != 0) && ((distSqFromHome > maxDistSqFromHome) || (this->timer < 4))) {
yaw = Math_Vec3f_Yaw(&this->actor.posRot.pos, &this->actor.initPosRot.pos);
if (Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, yaw, flightParams->rotYStep) == 0) {
minAnimSpeed = 0.5f;
}
} else if ((this->unk_257 == 0) && (this->actor.child != NULL) && (this->actor.child != &this->actor)) {
yaw = Math_Vec3f_Yaw(&this->actor.posRot.pos, &this->actor.child->posRot.pos);
if (Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, yaw, rotStep) == 0) {
minAnimSpeed = 0.3f;
}
} else if (this->unk_257 == 1) {
yaw = this->actor.yawTowardsLink + 0x8000 + (s16)((Math_Rand_ZeroOne() - 0.5f) * 0x6000);
if (Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, yaw, rotStep) == 0) {
minAnimSpeed = 0.4f;
}
} else {
this->actor.posRot.rot.y += (s16)(sinf(this->unk_25C) * 100.0f);
}
EnButte_Turn(this);
animSpeed = this->actor.speedXZ / 2.0f + Math_Rand_ZeroOne() * 0.2f + (1.0f - Math_Sins(this->unk_260)) * 0.15f +
(1.0f - Math_Sins(this->unk_25E)) * 0.3f + minAnimSpeed;
this->skelAnime.animPlaybackSpeed = CLAMP(animSpeed, 0.2f, 1.5f);
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (this->timer <= 0) {
EnButte_SelectFlightParams(this, &sFlyAroundParams[this->flightParamsIdx]);
}
if (((this->actor.params & 1) == 1) && (player->heldItemActionParam == 6) && (this->swordDownTimer <= 0) &&
((Math3D_Dist2DSq(player->actor.posRot.pos.x, player->actor.posRot.pos.z, this->actor.initPosRot.pos.x,
this->actor.initPosRot.pos.z) < SQ(120.0f)) ||
(this->actor.xzDistFromLink < 60.0f))) {
EnButte_SetupFollowLink(this);
this->unk_257 = 2;
} else if (this->actor.xzDistFromLink < 120.0) {
this->unk_257 = 1;
} else {
this->unk_257 = 0;
}
}
void EnButte_SetupFollowLink(EnButte* this) {
EnButte_SelectFlightParams(this, &sFollowLinkParams[this->flightParamsIdx]);
this->actionFunc = EnButte_FollowLink;
}
void EnButte_FollowLink(EnButte* this, GlobalContext* globalCtx) {
static s32 D_809CE410 = 1500;
EnButteFlightParams* flightParams = &sFollowLinkParams[this->flightParamsIdx];
Player* player = PLAYER;
f32 distSqFromHome;
Vec3f swordTip;
f32 animSpeed;
f32 minAnimSpeed;
f32 distSqFromSword;
s16 yaw;
func_809CD634(this);
Math_SmoothScaleMaxMinF(&this->actor.speedXZ, flightParams->speedXZTarget, flightParams->speedXZScale,
flightParams->speedXZStep, 0.0f);
minAnimSpeed = 0.0f;
if ((this->flightParamsIdx != 0) && (this->timer < 12)) {
swordTip.x = player->swordInfo[0].tip.x + Math_Sins(player->actor.shape.rot.y) * 10.0f;
swordTip.y = player->swordInfo[0].tip.y;
swordTip.z = player->swordInfo[0].tip.z + Math_Coss(player->actor.shape.rot.y) * 10.0f;
yaw = Math_Vec3f_Yaw(&this->actor.posRot.pos, &swordTip) + (s16)(Math_Rand_ZeroOne() * D_809CE410);
if (Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, yaw, 2000) != 0) {
if (globalCtx->gameplayFrames % 2) {
this->actor.posRot.rot.y += (s16)(sinf(this->unk_25C) * 60.0f);
}
} else {
minAnimSpeed = 0.3f;
}
}
this->posYTarget = MAX(player->actor.posRot.pos.y + 30.0f, player->swordInfo[0].tip.y);
EnButte_Turn(this);
animSpeed = this->actor.speedXZ / 2.0f + Math_Rand_ZeroOne() * 0.2f + (1.0f - Math_Sins(this->unk_260)) * 0.15f +
(1.0f - Math_Sins(this->unk_25E)) * 0.3f + minAnimSpeed;
this->skelAnime.animPlaybackSpeed = CLAMP(animSpeed, 0.2f, 1.5f);
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (this->timer <= 0) {
EnButte_SelectFlightParams(this, &sFollowLinkParams[this->flightParamsIdx]);
D_809CE410 = -D_809CE410;
}
distSqFromHome = Math3D_Dist2DSq(this->actor.posRot.pos.x, this->actor.posRot.pos.z, this->actor.initPosRot.pos.x,
this->actor.initPosRot.pos.z);
if (!((player->heldItemActionParam == 6) && (fabsf(player->actor.speedXZ) < 1.8f) && (this->swordDownTimer <= 0) &&
(distSqFromHome < SQ(320.0f)))) {
EnButte_SetupFlyAround(this);
} else if (distSqFromHome > SQ(240.0f)) {
distSqFromSword = Math3D_Dist2DSq(player->swordInfo[0].tip.x, player->swordInfo[0].tip.z,
this->actor.posRot.pos.x, this->actor.posRot.pos.z);
if (distSqFromSword < SQ(60.0f)) {
EnButte_SetupTransformIntoFairy(this);
}
}
}
void EnButte_SetupTransformIntoFairy(EnButte* this) {
this->timer = 9;
this->actor.flags |= 0x10;
this->skelAnime.animPlaybackSpeed = 1.0f;
EnButte_ResetTransformationEffect();
this->actionFunc = EnButte_TransformIntoFairy;
}
void EnButte_TransformIntoFairy(EnButte* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
EnButte_UpdateTransformationEffect();
if (this->timer == 5) {
Audio_PlaySoundAtPosition(globalCtx, &this->actor.posRot.pos, 60, NA_SE_EV_BUTTERFRY_TO_FAIRY);
} else if (this->timer == 4) {
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, this->actor.posRot2.pos.x, this->actor.posRot2.pos.y,
this->actor.posRot2.pos.z, 0, this->actor.shape.rot.y, 0, 2);
this->drawSkelAnime = false;
} else if (this->timer <= 0) {
EnButte_SetupWaitToDie(this);
}
}
void EnButte_SetupWaitToDie(EnButte* this) {
this->timer = 64;
this->actionFunc = EnButte_WaitToDie;
this->actor.draw = NULL;
}
void EnButte_WaitToDie(EnButte* this, GlobalContext* globalCtx) {
if (this->timer <= 0) {
Actor_Kill(&this->actor);
}
}
void EnButte_Update(Actor* thisx, GlobalContext* globalCtx) {
EnButte* this = THIS;
if ((this->actor.child != NULL) && (this->actor.child->update == NULL) && (this->actor.child != &this->actor)) {
this->actor.child = NULL;
}
if (this->timer > 0) {
this->timer--;
}
this->unk_25C += 0x222;
this->unk_25E += 0x1000;
this->unk_260 += 0x600;
if ((this->actor.params & 1) == 1) {
if (PLAYER->swordState == 0) {
if (this->swordDownTimer > 0) {
this->swordDownTimer--;
}
} else {
this->swordDownTimer = 80;
}
}
this->actionFunc(this, globalCtx);
if (this->actor.update != NULL) {
Actor_MoveForward(&this->actor);
Math_ApproxF(&this->actor.posRot.pos.y, this->posYTarget, 0.6f);
if (this->actor.xyzDistFromLinkSq < 5000.0f) {
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
Actor_SetHeight(&this->actor, this->actor.shape.unk_08 * this->actor.scale.y);
}
}
void EnButte_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnButte* this = THIS;
if (this->drawSkelAnime) {
func_80093D18(globalCtx->state.gfxCtx);
SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, NULL, NULL, NULL);
func_800628A4(0, &this->collider);
}
if (((this->actor.params & 1) == 1) && (this->actionFunc == EnButte_TransformIntoFairy)) {
EnButte_DrawTransformationEffect(this, globalCtx);
}
}

View file

@ -6,9 +6,25 @@
struct EnButte;
typedef void (*EnButteActionFunc)(struct EnButte*, GlobalContext*);
typedef struct EnButte {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x11C];
/* 0x014C */ ColliderJntSph collider;
/* 0x016C */ ColliderJntSphItem colliderItems[1];
/* 0x01AC */ SkelAnime skelAnime;
/* 0x01F0 */ Vec3s limbDrawTable[8];
/* 0x0220 */ Vec3s transitionDrawTable[8];
/* 0x0250 */ EnButteActionFunc actionFunc;
/* 0x0254 */ s16 timer;
/* 0x0256 */ u8 flightParamsIdx;
/* 0x0257 */ u8 unk_257;
/* 0x0258 */ u8 drawSkelAnime;
/* 0x025A */ s16 swordDownTimer;
/* 0x025C */ s16 unk_25C;
/* 0x025E */ s16 unk_25E;
/* 0x0260 */ s16 unk_260;
/* 0x0264 */ f32 posYTarget;
} EnButte; // size = 0x0268
extern const ActorInit En_Butte_InitVars;