1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-07 06:40:15 +00:00

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>
This commit is contained in:
kroemker 2020-09-27 03:06:30 +02:00 committed by GitHub
parent c864ce0de2
commit 0dca636f4a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 334 additions and 1019 deletions

View file

@ -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;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/BgMizuWater_Init.s")
static u32 sWaterBoxIndexes[] = { 2, 3, 5, 7, 12, 20, 21, 22 };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/BgMizuWater_Destroy.s")
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F(scale, 1, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/func_8089FCF8.s")
u32 BgMizuWater_GetWaterLevelActionIndex(s16 switchFlag, GlobalContext* globalCtx) {
u32 ret;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/func_8089FEC4.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/BgMizuWater_Update.s")
return ret;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mizu_Water/BgMizuWater_Draw.s")
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);
gSPSegment(oGfxCtx->polyXlu.p++, 0x0C,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, -gameplayFrames * 1, gameplayFrames * 1, 32, 32, 1, 0,
-gameplayFrames * 1, 32, 32));
gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_bg_mizu_water.c", 749),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetEnvColor(oGfxCtx->polyXlu.p++, 255, 255, 255, 128);
gDPSetPrimColor(oGfxCtx->polyXlu.p++, 0, 0, 255, 255, 255, 102);
gSPDisplayList(oGfxCtx->polyXlu.p++, D_06004B20);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_bg_mizu_water.c", 756);
}

View file

@ -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;