diff options
| author | kroemker <lk1994@gmx.net> | 2020-09-27 03:06:30 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-26 21:06:30 -0400 |
| commit | 0dca636f4a678535dd6fa3d41f7f1bd7b3137cbc (patch) | |
| tree | e6f45fee566ec6526c75a75e8ff67b52e7a6214f /src | |
| parent | c864ce0de2012c686a4db83f0e21f83c1759d3f9 (diff) | |
BgMizuWater OK (#359)
* BgMizuWater OK
* Renaming
* Fix formatting
* Cleanup, use new gfx functions
* Fix stack issue
* PR fixes
* Apply suggestions from code review
Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com>
* PR fixes
* More PR fixes
* Fix formatting
Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.c | 330 | ||||
| -rw-r--r-- | src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.h | 8 |
2 files changed, 327 insertions, 11 deletions
diff --git a/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.c b/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.c index d61f00c3d..e498b4c71 100644 --- a/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.c +++ b/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.c @@ -1,3 +1,9 @@ +/* + * File: z_bg_mizu_water.c + * Overlay: ovl_Bg_Mizu_Water + * Description: Water plane in Water Temple. Changes height based on switches 0x1C, 0x1D, 0x1E. + */ + #include "z_bg_mizu_water.h" #define FLAGS 0x00000030 @@ -9,7 +15,23 @@ void BgMizuWater_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgMizuWater_Update(Actor* thisx, GlobalContext* globalCtx); void BgMizuWater_Draw(Actor* thisx, GlobalContext* globalCtx); -/* +void BgMizuWater_WaitForAction(BgMizuWater* this, GlobalContext* globalCtx); +void BgMizuWater_ChangeWaterLevel(BgMizuWater* this, GlobalContext* globalCtx); + +extern Gfx D_06004B20[]; + +typedef struct { + s32 switchFlag; + s32 yDiff; +} WaterLevel; + +static WaterLevel sWaterLevels[] = { + { 0x00, 0 }, + { 0x1E, 0 }, + { 0x1D, -320 }, + { 0x1C, -780 }, +}; + const ActorInit Bg_Mizu_Water_InitVars = { ACTOR_BG_MIZU_WATER, ACTORTYPE_BG, @@ -21,19 +43,307 @@ const ActorInit Bg_Mizu_Water_InitVars = { (ActorFunc)BgMizuWater_Update, (ActorFunc)BgMizuWater_Draw, }; -*/ -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/func_8089F8B0.s") -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/func_8089F9D0.s") +static f32 sUnused1 = 0; +static f32 sUnused2 = 110.0f; + +static u32 sWaterBoxIndexes[] = { 2, 3, 5, 7, 12, 20, 21, 22 }; + +static InitChainEntry sInitChain[] = { + ICHAIN_VEC3F(scale, 1, ICHAIN_STOP), +}; + +u32 BgMizuWater_GetWaterLevelActionIndex(s16 switchFlag, GlobalContext* globalCtx) { + u32 ret; + + if (bREG(0) != 0) { + switch (bREG(1)) { + case 0: + Flags_SetSwitch(globalCtx, 0x1C); + break; + case 1: + Flags_SetSwitch(globalCtx, 0x1D); + break; + case 2: + Flags_SetSwitch(globalCtx, 0x1E); + break; + } + bREG(0) = 0; + } + if (Flags_GetSwitch(globalCtx, 0x1C) && (switchFlag != 0x1C)) { + ret = 3; + } else if (Flags_GetSwitch(globalCtx, 0x1D) && (switchFlag != 0x1D)) { + ret = 2; + } else if (Flags_GetSwitch(globalCtx, 0x1E) && (switchFlag != 0x1E)) { + ret = 1; + } else { + ret = 0; + } + + return ret; +} + +void BgMizuWater_SetWaterBoxesHeight(WaterBox* waterBoxes, s16 height) { + u32 i; + + for (i = 0; i < 8; i++) { + waterBoxes[sWaterBoxIndexes[i]].unk_02 = height; + } +} + +void BgMizuWater_Init(Actor* thisx, GlobalContext* globalCtx) { + BgMizuWater* this = THIS; + f32 initialActorY; + WaterBox* waterBoxes; + s32 waterLevelActionIndex; + + waterBoxes = globalCtx->colCtx.stat.colHeader->waterBoxes; + this->type = this->actor.params & 0xFF; + this->switchFlag = (this->actor.params >> 8) & 0xFF; + Actor_ProcessInitChain(&this->actor, sInitChain); + initialActorY = this->actor.posRot.pos.y; + this->baseY = initialActorY; + this->targetY = initialActorY; + + switch (this->type) { + case 0: + if (bREG(15) == 0) { + osSyncPrintf("<コンストラクト>%x %x %x\n", Flags_GetSwitch(globalCtx, 0x1C), + Flags_GetSwitch(globalCtx, 0x1D), Flags_GetSwitch(globalCtx, 0x1E)); + } + waterLevelActionIndex = BgMizuWater_GetWaterLevelActionIndex(-1, globalCtx); + this->actor.posRot.pos.y = sWaterLevels[waterLevelActionIndex].yDiff + this->baseY; + BgMizuWater_SetWaterBoxesHeight(waterBoxes, this->actor.posRot.pos.y); + this->actor.params = sWaterLevels[waterLevelActionIndex].switchFlag; + Flags_UnsetSwitch(globalCtx, 0x1C); + Flags_UnsetSwitch(globalCtx, 0x1D); + Flags_UnsetSwitch(globalCtx, 0x1E); + + switch (this->actor.params) { + case 0x1E: + Flags_SetSwitch(globalCtx, 0x1E); + break; + case 0x1D: + Flags_SetSwitch(globalCtx, 0x1D); + break; + case 0x1C: + default: + Flags_SetSwitch(globalCtx, 0x1C); + break; + } + this->targetY = this->actor.posRot.pos.y; + break; + case 1: + break; + case 2: + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->actor.posRot.pos.y = this->baseY + 85.0f; + } + waterBoxes[6].unk_02 = this->actor.posRot.pos.y; + break; + case 3: + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->actor.posRot.pos.y = this->baseY + 110.0f; + if (1) {} + this->targetY = this->actor.posRot.pos.y; + } + waterBoxes[8].unk_02 = this->actor.posRot.pos.y; + break; + case 4: + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->actor.posRot.pos.y = this->baseY + 160.0f; + if (1) {} + this->targetY = this->actor.posRot.pos.y; + } + waterBoxes[16].unk_02 = this->actor.posRot.pos.y; + break; + } + + this->actionFunc = BgMizuWater_WaitForAction; +} + +void BgMizuWater_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void BgMizuWater_WaitForAction(BgMizuWater* this, GlobalContext* globalCtx) { + s32 pad; + s32 waterLevelActionIndex; + s16 prevSwitchFlag; + + switch (this->type) { + case 0: + prevSwitchFlag = this->actor.params; + waterLevelActionIndex = BgMizuWater_GetWaterLevelActionIndex(this->actor.params, globalCtx); + if (waterLevelActionIndex != 0) { + if (prevSwitchFlag != sWaterLevels[waterLevelActionIndex].switchFlag) { + func_800800F8(globalCtx, 0xC30, -0x64 - waterLevelActionIndex, 0, 0); + this->actor.params = sWaterLevels[waterLevelActionIndex].switchFlag; + this->targetY = sWaterLevels[waterLevelActionIndex].yDiff + this->baseY; + } + } + if ((prevSwitchFlag != this->actor.params) && (prevSwitchFlag != 0)) { + Flags_UnsetSwitch(globalCtx, prevSwitchFlag); + } + break; + case 1: + break; + case 2: + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->targetY = this->baseY + 85.0f; + } else { + this->targetY = this->baseY; + } + break; + case 3: + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->targetY = this->baseY + 110.0f; + } else { + this->targetY = this->baseY; + } + break; + case 4: + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->targetY = this->baseY + 160.0f; + } else { + this->targetY = this->baseY; + } + } + + if (this->targetY != this->actor.posRot.pos.y) { + this->actionFunc = BgMizuWater_ChangeWaterLevel; + } +} + +void BgMizuWater_ChangeWaterLevel(BgMizuWater* this, GlobalContext* globalCtx) { + s32 pad; + s16 prevSwitchFlag; + s32 waterLevelActionIndex; + WaterBox* waterBoxes; + + waterBoxes = globalCtx->colCtx.stat.colHeader->waterBoxes; + switch (this->type) { + case 0: + prevSwitchFlag = this->actor.params; + waterLevelActionIndex = BgMizuWater_GetWaterLevelActionIndex(this->actor.params, globalCtx); + if (waterLevelActionIndex != 0) { + if (prevSwitchFlag != sWaterLevels[waterLevelActionIndex].switchFlag) { + this->actor.params = sWaterLevels[waterLevelActionIndex].switchFlag; + this->targetY = sWaterLevels[waterLevelActionIndex].yDiff + this->baseY; + } + } + + if ((prevSwitchFlag != this->actor.params) && (prevSwitchFlag != 0)) { + Flags_UnsetSwitch(globalCtx, prevSwitchFlag); + } + + if (Math_ApproxF(&this->actor.posRot.pos.y, this->targetY, 5.0f)) { + globalCtx->unk_11D30[0] = 0; + this->actionFunc = BgMizuWater_WaitForAction; + func_80106CCC(globalCtx); + } + BgMizuWater_SetWaterBoxesHeight(globalCtx->colCtx.stat.colHeader->waterBoxes, this->actor.posRot.pos.y); + break; + case 1: + break; + case 2: + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->targetY = this->baseY + 85.0f; + } else { + this->targetY = this->baseY; + } + if (Math_ApproxF(&this->actor.posRot.pos.y, this->targetY, 1.0f)) { + globalCtx->unk_11D30[0] = 0; + this->actionFunc = BgMizuWater_WaitForAction; + } + waterBoxes[6].unk_02 = this->actor.posRot.pos.y; + break; + case 3: + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->targetY = this->baseY + 110.0f; + } else { + this->targetY = this->baseY; + } + if (Math_ApproxF(&this->actor.posRot.pos.y, this->targetY, 1.0f)) { + globalCtx->unk_11D30[0] = 0; + this->actionFunc = BgMizuWater_WaitForAction; + } + waterBoxes[8].unk_02 = this->actor.posRot.pos.y; + break; + case 4: + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->targetY = this->baseY + 160.0f; + } else { + this->targetY = this->baseY; + } + if (Math_ApproxF(&this->actor.posRot.pos.y, this->targetY, 1.0f)) { + globalCtx->unk_11D30[0] = 0; + this->actionFunc = BgMizuWater_WaitForAction; + } + waterBoxes[16].unk_02 = this->actor.posRot.pos.y; + break; + } + + if (this->targetY < this->actor.posRot.pos.y) { + func_800AA000(0.0f, 0x78, 0x14, 0xA); + func_8002F948(&this->actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); + } else if (this->targetY > this->actor.posRot.pos.y) { + func_800AA000(0.0f, 0x78, 0x14, 0xA); + func_8002F948(&this->actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); + } +} + +void BgMizuWater_Update(Actor* thisx, GlobalContext* globalCtx) { + BgMizuWater* this = THIS; + s32 posY; + s32 unk0; + s32 unk1; + s32 pad; + + if (bREG(15) == 0) { + osSyncPrintf("%x %x %x\n", Flags_GetSwitch(globalCtx, 0x1C), Flags_GetSwitch(globalCtx, 0x1D), + Flags_GetSwitch(globalCtx, 0x1E)); + } + + if (this->type == 0) { + posY = this->actor.posRot.pos.y; + unk0 = 0; + unk1 = 0; + if (posY < -15.0f) { + unk0 = 0; + unk1 = ((posY - -835.0f) / 820.0f) * 200.0f; + } else if (posY < 445.0f) { + unk0 = 1; + unk1 = 0xFF - (s32)(((posY - -15.0f) / 460.0f) * 95.0f); + } else if (posY <= 765.0f) { + unk0 = 2; + unk1 = 0xFF - (s32)(((posY - 445.0f) / 320.0f) * 95.0f); + } + globalCtx->unk_11D30[1] = ((u8)unk0 << 8) | (unk1 & 0xFF); + } + + this->actionFunc(this, globalCtx); +} + +void BgMizuWater_Draw(Actor* thisx, GlobalContext* globalCtx) { + BgMizuWater* this = THIS; + s32 gameplayFrames; + + OPEN_DISPS(globalCtx->state.gfxCtx, "../z_bg_mizu_water.c", 738); + gameplayFrames = globalCtx->gameplayFrames; + func_80093D84(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/BgMizuWater_Init.s") + gSPSegment(oGfxCtx->polyXlu.p++, 0x0C, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, -gameplayFrames * 1, gameplayFrames * 1, 32, 32, 1, 0, + -gameplayFrames * 1, 32, 32)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/BgMizuWater_Destroy.s") + gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_bg_mizu_water.c", 749), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/func_8089FCF8.s") + gDPSetEnvColor(oGfxCtx->polyXlu.p++, 255, 255, 255, 128); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/func_8089FEC4.s") + gDPSetPrimColor(oGfxCtx->polyXlu.p++, 0, 0, 255, 255, 255, 102); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/BgMizuWater_Update.s") + gSPDisplayList(oGfxCtx->polyXlu.p++, D_06004B20); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/BgMizuWater_Draw.s") + CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_bg_mizu_water.c", 756); +} diff --git a/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.h b/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.h index bb4439e87..a1f0b5188 100644 --- a/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.h +++ b/src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.h @@ -6,9 +6,15 @@ struct BgMizuWater; +typedef void (*BgMizuWaterActionFunc)(struct BgMizuWater*, GlobalContext*); + typedef struct BgMizuWater { /* 0x0000 */ Actor actor; - /* 0x014C */ char unk_14C[0x14]; + /* 0x014C */ BgMizuWaterActionFunc actionFunc; + /* 0x0150 */ s32 type; + /* 0x0154 */ f32 targetY; + /* 0x0158 */ f32 baseY; + /* 0x015C */ s32 switchFlag; // only used for types 2-4 } BgMizuWater; // size = 0x0160 extern const ActorInit Bg_Mizu_Water_InitVars; |
