mirror of https://github.com/zeldaret/mm.git
Arrow_Ice OK (#314)
* Migrate data and ArrowIce_Init OK * ArrowIce_Destroy OK (also define func_80115D5C in functions.h, maybe a bad thing???) * ArrowIce_SetupAction OK * func_809224DC OK * ArrowIce_Update OK * func_809227F4 OK (but with hacky float constant) * func_809225D0 OK and use float constant in func_809227F4 * func_80922628 OK * ArrowIce_Draw OK * Migrate D_80924200.s to C * Apply better names in ice_gfx, and document Draw slightly * Name struct vars to match OoT * Update function names to match OoT * Explain that arrow's timer and hitFlags came from OoT * Update spec + "migrate" bss to C * Do a hex -> decimal conversion I missed * Remove blank line in-between headers * Remove extraneous forward declare * Move initialization of arrow up one line * Remove parentheses * Use else if * Use decrement operation * Use decimal for an alpha calculation * Switch func_80115D5C to take GameState* * Put pad on the top of Draw * Move initialization of arrow up (again) * Early return from Update if we're killed * Extract assets instead of putting them in the repo * Add explanatory comment to top of file * += 1 -> ++ * Use VEC3F_LERPIMPDST macro * Force a jenkins rerun by adding a space * Remove the space from the last commit * Move literal to the back of the conditional * Respond to review feedback * Add ArrowIce_LerpFiredPosition to functions.txt
This commit is contained in:
parent
bd9e21b165
commit
fbd1a79942
|
|
@ -0,0 +1,11 @@
|
|||
<Root>
|
||||
<File Name="ovl_Arrow_Ice" BaseAddress="0x80922430" RangeStart="0x980" RangeEnd="0x1DA0" Segment="128">
|
||||
<Texture Name="sIceArrow1Tex" OutName="ice_tex_1" Format="ia8" Width="32" Height="64" Offset="0x980"/>
|
||||
<Texture Name="sIceArrow2Tex" OutName="ice_tex_2" Format="ia8" Width="32" Height="64" Offset="0x1180"/>
|
||||
<Array Name="sIceArrowVtx" Count="43" Offset="0x1980">
|
||||
<Vtx/>
|
||||
</Array>
|
||||
<DList Name="sIceArrowDL" Offset="0x1C30"/>
|
||||
<DList Name="sIceArrowVtxDL" Offset="0x1CE0"/>
|
||||
</File>
|
||||
</Root>
|
||||
|
|
@ -2162,7 +2162,7 @@ void func_801159c0(s16 param_1);
|
|||
void func_801159EC(s16 arg0);
|
||||
void func_80115A14(s32 arg0, s16 arg1);
|
||||
// void Parameter_AddMagic(void);
|
||||
// void func_80115D5C(void);
|
||||
void func_80115D5C(GameState* gamestate);
|
||||
// void func_80115DB4(void);
|
||||
// void func_80116088(void);
|
||||
// void func_80116114(void);
|
||||
|
|
|
|||
4
spec
4
spec
|
|
@ -1414,9 +1414,7 @@ beginseg
|
|||
name "ovl_Arrow_Ice"
|
||||
compress
|
||||
include "build/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.o"
|
||||
include "build/data/ovl_Arrow_Ice/ovl_Arrow_Ice.data.o"
|
||||
include "build/data/ovl_Arrow_Ice/ovl_Arrow_Ice.bss.o"
|
||||
include "build/data/ovl_Arrow_Ice/ovl_Arrow_Ice.reloc.o"
|
||||
include "build/src/overlays/actors/ovl_Arrow_Ice/ovl_Arrow_Ice_reloc.o"
|
||||
endseg
|
||||
|
||||
beginseg
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
/*
|
||||
* File: z_arrow_ice.c
|
||||
* Overlay: ovl_Arrow_Ice
|
||||
* Description: Ice Arrow. Spawned as a child of a normal arrow.
|
||||
*/
|
||||
|
||||
#include "z_arrow_ice.h"
|
||||
#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h"
|
||||
|
||||
#define FLAGS 0x02000010
|
||||
|
||||
|
|
@ -9,13 +16,14 @@ void ArrowIce_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void ArrowIce_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void ArrowIce_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
void func_809224DC(ArrowIce* this, GlobalContext* globalCtx);
|
||||
void func_80922628(ArrowIce* this, GlobalContext* globalCtx);
|
||||
void func_809227F4(ArrowIce* this, GlobalContext* globalCtx);
|
||||
void ArrowIce_Charge(ArrowIce* this, GlobalContext* globalCtx);
|
||||
void ArrowIce_Hit(ArrowIce* this, GlobalContext* globalCtx);
|
||||
void ArrowIce_Fly(ArrowIce* this, GlobalContext* globalCtx);
|
||||
|
||||
void ArrowIce_SetupAction(ArrowIce* this, ArrowIceActionFunc actionFunc);
|
||||
#include "overlays/ovl_Arrow_Ice/ovl_Arrow_Ice.c"
|
||||
|
||||
s32 unused; // Needed for bss
|
||||
|
||||
#if 0
|
||||
const ActorInit Arrow_Ice_InitVars = {
|
||||
ACTOR_ARROW_ICE,
|
||||
ACTORCAT_ITEMACTION,
|
||||
|
|
@ -28,33 +36,207 @@ const ActorInit Arrow_Ice_InitVars = {
|
|||
(ActorFunc)ArrowIce_Draw,
|
||||
};
|
||||
|
||||
// static InitChainEntry sInitChain[] = {
|
||||
static InitChainEntry D_809241F0[] = {
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
#endif
|
||||
extern Gfx D_0E0002E0[];
|
||||
|
||||
extern InitChainEntry D_809241F0[];
|
||||
void ArrowIce_SetupAction(ArrowIce* this, ArrowIceActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
}
|
||||
|
||||
extern UNK_TYPE D_0E0002E0;
|
||||
void ArrowIce_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
ArrowIce* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Ice/D_80924200.s")
|
||||
Actor_ProcessInitChain(&this->actor, sInitChain);
|
||||
this->radius = 0;
|
||||
this->height = 1.0f;
|
||||
ArrowIce_SetupAction(this, ArrowIce_Charge);
|
||||
Actor_SetScale(&this->actor, 0.01f);
|
||||
this->alpha = 100;
|
||||
this->timer = 0;
|
||||
this->blueingEffectMagnitude = 0.0f;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Ice/ArrowIce_SetupAction.s")
|
||||
void ArrowIce_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
func_80115D5C(&globalCtx->state);
|
||||
(void)"消滅"; // Unreferenced in retail, means "Disappearance"
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Ice/ArrowIce_Init.s")
|
||||
void ArrowIce_Charge(ArrowIce* this, GlobalContext* globalCtx) {
|
||||
EnArrow* arrow = (EnArrow*)this->actor.parent;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Ice/ArrowIce_Destroy.s")
|
||||
if ((arrow == NULL) || (arrow->actor.update == NULL)) {
|
||||
Actor_MarkForDeath(&this->actor);
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Ice/func_809224DC.s")
|
||||
if (this->radius < 10) {
|
||||
this->radius++;
|
||||
}
|
||||
// copy position and rotation from arrow
|
||||
this->actor.world.pos = arrow->actor.world.pos;
|
||||
this->actor.shape.rot = arrow->actor.shape.rot;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Ice/func_809225D0.s")
|
||||
func_800B9010(&this->actor, NA_SE_PL_ARROW_CHARGE_ICE - SFX_FLAG);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Ice/func_80922628.s")
|
||||
// if arrow has no parent, player has fired the arrow
|
||||
if (arrow->actor.parent == NULL) {
|
||||
this->firedPos = this->actor.world.pos;
|
||||
this->radius = 10;
|
||||
ArrowIce_SetupAction(this, ArrowIce_Fly);
|
||||
this->alpha = 255;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Ice/func_809227F4.s")
|
||||
void ArrowIce_LerpFiredPosition(Vec3f* firedPos, Vec3f* icePos, f32 scale) {
|
||||
VEC3F_LERPIMPDST(firedPos, firedPos, icePos, scale);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Ice/ArrowIce_Update.s")
|
||||
void ArrowIce_Hit(ArrowIce* this, GlobalContext* globalCtx) {
|
||||
f32 scale;
|
||||
f32 offset;
|
||||
u16 timer;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Ice/ArrowIce_Draw.s")
|
||||
if (this->actor.projectedW < 50.0f) {
|
||||
scale = 10.0f;
|
||||
} else if (this->actor.projectedW > 950.0f) {
|
||||
scale = 310.0f;
|
||||
} else {
|
||||
scale = this->actor.projectedW;
|
||||
scale = (scale - 50.0f) * (1.0f / 3.0f) + 10.0f;
|
||||
}
|
||||
|
||||
timer = this->timer;
|
||||
if (timer != 0) {
|
||||
this->timer--;
|
||||
|
||||
if (this->timer >= 8) {
|
||||
offset = ((this->timer - 8) * (1.0f / 24.0f));
|
||||
offset = SQ(offset);
|
||||
this->radius = (((1.0f - offset) * scale) + 10.0f);
|
||||
this->height += ((2.0f - this->height) * 0.1f);
|
||||
if (this->timer < 16) {
|
||||
if (1) {}
|
||||
this->alpha = ((this->timer * 35) - 280);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this->timer >= 9) {
|
||||
if (this->blueingEffectMagnitude < 1.0f) {
|
||||
this->blueingEffectMagnitude += 0.25f;
|
||||
}
|
||||
} else {
|
||||
if (this->blueingEffectMagnitude > 0.0f) {
|
||||
this->blueingEffectMagnitude -= 0.125f;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->timer < 8) {
|
||||
this->alpha = 0;
|
||||
}
|
||||
|
||||
if (this->timer == 0) {
|
||||
this->timer = 255;
|
||||
Actor_MarkForDeath(&this->actor);
|
||||
}
|
||||
}
|
||||
|
||||
void ArrowIce_Fly(ArrowIce* this, GlobalContext* globalCtx) {
|
||||
EnArrow* arrow = (EnArrow*)this->actor.parent;
|
||||
f32 distanceScaled;
|
||||
s32 pad;
|
||||
|
||||
if ((arrow == NULL) || (arrow->actor.update == NULL)) {
|
||||
Actor_MarkForDeath(&this->actor);
|
||||
return;
|
||||
}
|
||||
// copy position and rotation from arrow
|
||||
this->actor.world.pos = arrow->actor.world.pos;
|
||||
this->actor.shape.rot = arrow->actor.shape.rot;
|
||||
distanceScaled = Math_Vec3f_DistXYZ(&this->firedPos, &this->actor.world.pos) * (1.0f / 24.0f);
|
||||
this->height = distanceScaled;
|
||||
if (distanceScaled < 1.0f) {
|
||||
this->height = 1.0f;
|
||||
}
|
||||
ArrowIce_LerpFiredPosition(&this->firedPos, &this->actor.world.pos, 0.05f);
|
||||
|
||||
if (arrow->unk_261 & 1) {
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_IT_EXPLOSION_ICE);
|
||||
ArrowIce_SetupAction(this, ArrowIce_Hit);
|
||||
this->timer = 32;
|
||||
this->alpha = 255;
|
||||
} else if (arrow->unk_260 < 34) {
|
||||
if (this->alpha < 35) {
|
||||
Actor_MarkForDeath(&this->actor);
|
||||
} else {
|
||||
this->alpha -= 25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArrowIce_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
ArrowIce* this = THIS;
|
||||
|
||||
if ((globalCtx->msgCtx.unk11F22 == 0xE) || (globalCtx->msgCtx.unk11F22 == 0x12)) {
|
||||
Actor_MarkForDeath(&this->actor);
|
||||
return;
|
||||
} else {
|
||||
this->actionFunc(this, globalCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void ArrowIce_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
ArrowIce* this = THIS;
|
||||
Actor* transform;
|
||||
u32 stateFrames = globalCtx->state.frames;
|
||||
EnArrow* arrow = (EnArrow*)this->actor.parent;
|
||||
|
||||
if ((arrow != NULL) && (arrow->actor.update != NULL) && (this->timer < 255)) {
|
||||
transform = (arrow->unk_261 & 2) ? &this->actor : &arrow->actor;
|
||||
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx);
|
||||
|
||||
SysMatrix_InsertTranslation(transform->world.pos.x, transform->world.pos.y, transform->world.pos.z,
|
||||
MTXMODE_NEW);
|
||||
Matrix_RotateY(transform->shape.rot.y, MTXMODE_APPLY);
|
||||
SysMatrix_InsertXRotation_s(transform->shape.rot.x, MTXMODE_APPLY);
|
||||
SysMatrix_InsertZRotation_s(transform->shape.rot.z, MTXMODE_APPLY);
|
||||
Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY);
|
||||
|
||||
// Draw blue effect over the screen when arrow hits
|
||||
if (this->blueingEffectMagnitude > 0.0f) {
|
||||
POLY_XLU_DISP = func_8012BFC4(POLY_XLU_DISP);
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, (s32)(this->blueingEffectMagnitude * 10.0f) & 0xFF,
|
||||
(s32)(50.0f * this->blueingEffectMagnitude) & 0xFF,
|
||||
(s32)(150.0f * this->blueingEffectMagnitude) & 0xFF);
|
||||
gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE);
|
||||
gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE);
|
||||
gSPDisplayList(POLY_XLU_DISP++, D_0E0002E0);
|
||||
}
|
||||
|
||||
// Draw ice on the arrow
|
||||
func_8012C2DC(globalCtx->state.gfxCtx);
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 170, 255, 255, (s32)(this->alpha * 0.5f) & 0xFF);
|
||||
gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 255, 128);
|
||||
SysMatrix_InsertRotation(0x4000, 0, 0, MTXMODE_APPLY);
|
||||
if (this->timer != 0) {
|
||||
SysMatrix_InsertTranslation(0.0f, 0.0f, 0.0f, MTXMODE_APPLY);
|
||||
} else {
|
||||
SysMatrix_InsertTranslation(0.0f, 1500.0f, 0.0f, MTXMODE_APPLY);
|
||||
}
|
||||
Matrix_Scale(this->radius * 0.2f, this->height * 3.0f, this->radius * 0.2f, MTXMODE_APPLY);
|
||||
SysMatrix_InsertTranslation(0.0f, -700.0f, 0.0f, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_XLU_DISP++, sIceArrowDL);
|
||||
gSPDisplayList(POLY_XLU_DISP++,
|
||||
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 511 - (stateFrames * 5) % 512, 0, 128, 32, 1,
|
||||
511 - (stateFrames * 10) % 512, 511 - (stateFrames * 10) % 512, 4, 16));
|
||||
gSPDisplayList(POLY_XLU_DISP++, sIceArrowVtxDL);
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,12 @@ typedef void (*ArrowIceActionFunc)(struct ArrowIce*, GlobalContext*);
|
|||
|
||||
typedef struct ArrowIce {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x0144 */ char unk_144[0x1C];
|
||||
/* 0x0144 */ s16 radius;
|
||||
/* 0x0146 */ u16 timer;
|
||||
/* 0x0148 */ u8 alpha;
|
||||
/* 0x014C */ Vec3f firedPos;
|
||||
/* 0x0158 */ f32 height;
|
||||
/* 0x015C */ f32 blueingEffectMagnitude;
|
||||
/* 0x0160 */ ArrowIceActionFunc actionFunc;
|
||||
} ArrowIce; // size = 0x164
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ typedef struct EnArrow {
|
|||
/* 0x0000 */ Actor actor;
|
||||
/* 0x0144 */ char unk_144[0x7C];
|
||||
/* 0x01C0 */ s32 unk_1C0;
|
||||
/* 0x01C4 */ char unk_1C4[0xB0];
|
||||
/* 0x01C4 */ char unk_1C4[0x9C];
|
||||
/* 0x0260 */ u8 unk_260; // timer in OoT
|
||||
/* 0x0261 */ u8 unk_261; // hitFlags in OoT
|
||||
/* 0x0262 */ char unk_262[0x12];
|
||||
/* 0x0274 */ EnArrowActionFunc actionFunc;
|
||||
} EnArrow; // size = 0x278
|
||||
|
||||
|
|
|
|||
|
|
@ -7014,10 +7014,10 @@
|
|||
0x80922430:("ArrowIce_SetupAction",),
|
||||
0x8092243C:("ArrowIce_Init",),
|
||||
0x809224B8:("ArrowIce_Destroy",),
|
||||
0x809224DC:("func_809224DC",),
|
||||
0x809225D0:("func_809225D0",),
|
||||
0x80922628:("func_80922628",),
|
||||
0x809227F4:("func_809227F4",),
|
||||
0x809224DC:("ArrowIce_Charge",),
|
||||
0x809225D0:("ArrowIce_LerpFiredPosition",),
|
||||
0x80922628:("ArrowIce_Hit",),
|
||||
0x809227F4:("ArrowIce_Fly",),
|
||||
0x80922948:("ArrowIce_Update",),
|
||||
0x8092299C:("ArrowIce_Draw",),
|
||||
0x80924300:("ArrowLight_SetupAction",),
|
||||
|
|
|
|||
Loading…
Reference in New Issue