summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorlouist103 <35883445+louist103@users.noreply.github.com>2021-11-03 14:09:43 -0400
committerGitHub <noreply@github.com>2021-11-03 15:09:43 -0300
commit8e88768a702c7888401a563620fbfe44769d3f4e (patch)
tree4994c81cbcef3d3a8e3c93e03d8e016d79571ccf /src/code
parent8250fd0941b3227d64aa4de253c96e7b9ed902ba (diff)
Fireobj Kinda OK (#400)
* done * format * PR fixes * revert formatting z64.h * Update warnings_build_current.txt
Diffstat (limited to 'src/code')
-rw-r--r--src/code/z_fireobj.c246
1 files changed, 235 insertions, 11 deletions
diff --git a/src/code/z_fireobj.c b/src/code/z_fireobj.c
index abc78fc4d..79041a713 100644
--- a/src/code/z_fireobj.c
+++ b/src/code/z_fireobj.c
@@ -1,27 +1,251 @@
#include "global.h"
+#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h"
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_InitWithParams.s")
+typedef enum {
+ FIRE_STATE_0,
+ FIRE_STATE_1,
+ FIRE_STATE_2,
+ FIRE_STATE_3,
+} FireState;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_SetState.s")
+ColliderCylinderInit sFireObjCollisionInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_NONE,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK4,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00000820, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
+ { 18, 67, 0, { 0, 0, 0 } },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_SetPosition.s")
+FireObjLightParams sFireObjLightParams[2] = {
+ { 255, 255, 0, 255, 128, 255, 0, 0 },
+ { 0, 200, 128, 128, 0, 127, 127, 0 },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_StepSize.s")
+void FireObj_InitLight(GlobalContext* globalCtx, FireObjLight* light, u8* param_3, Vec3f* pos);
+void FireObj_UpdateLight(GlobalContext* globalCtx, FireObjLight* light, FireObj* fire);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_UpdateStateTransitions.s")
+void FireObj_InitWithParams(GlobalContext* globalCtx, FireObj* fire, FireObjInitParams* init) {
+ fire->size = init->size;
+ fire->sizeInv = 1.0f / init->size;
+ fire->dynamicSizeStep = init->dynamicSizeStep;
+ fire->state = init->state;
+ fire->sizeGrowsCos2 = init->sizeGrowsCos2;
+ fire->unk27 = init->unkA;
+ fire->flags = init->flags;
+ fire->xScale = 0.0f;
+ fire->yScale = 0.0f;
+ fire->dynamicSize = 0.0f;
+ fire->unk26 = Rand_ZeroOne() * 20.0f;
+ fire->ignitionDelay = -1;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_Draw.s")
+void FireObj_SetState(FireObj* fire, f32 dynamicSizeStep, u8 newState) {
+ fire->state = newState & 0xFF;
+ if (fire->state == FIRE_STATE_3) {
+ fire->yScale = 0.0f;
+ fire->xScale = 0.0f;
+ fire->dynamicSize = 0.0f;
+ } else if (fire->state == FIRE_STATE_2) {
+ fire->xScale = fire->yScale = fire->size;
+ fire->dynamicSize = 1.0f;
+ }
+ fire->dynamicSizeStep = dynamicSizeStep;
+}
+void FireObj_SetPosition(FireObj* fire, Vec3f* pos) {
+ Math_Vec3f_Copy(&fire->position, pos);
+}
+
+void FireObj_StepSize(FireObj* fire) {
+ if (fire->state == FIRE_STATE_0) {
+ if (Math_StepToF(&fire->dynamicSize, 1.0f, fire->dynamicSizeStep) != 0) {
+ FireObj_SetState(fire, fire->dynamicSizeStep, FIRE_STATE_2);
+ }
+ } else if ((fire->state == FIRE_STATE_1) && (Math_StepToF(&fire->dynamicSize, 0.0f, fire->dynamicSizeStep) != 0)) {
+ FireObj_SetState(fire, fire->dynamicSizeStep, 3);
+ }
+ if (fire->sizeGrowsCos2 == 1) {
+ if ((fire->state == FIRE_STATE_0) || (fire->state == FIRE_STATE_1)) {
+ fire->xScale = (1.0f - Math_CosS((fire->dynamicSize * fire->dynamicSize * 16384.0f))) * fire->size;
+ fire->yScale = fire->dynamicSize * fire->size;
+ } else {
+ fire->yScale = fire->dynamicSize * fire->size;
+ fire->xScale = fire->dynamicSize * fire->size;
+ }
+ return;
+ } else {
+ fire->yScale = fire->dynamicSize * fire->size;
+ }
+ fire->xScale = fire->dynamicSize * fire->size;
+}
+
+void FireObj_UpdateStateTransitions(GlobalContext* globalCtx, FireObj* fire) {
+ Player* player = GET_PLAYER(globalCtx);
+ WaterBox* waterBox;
+ f32 sp44;
+ s32 sp40 = 0;
+ u8 nextState;
+ Vec3f dist;
+
+ FireObj_StepSize(fire);
+ fire->unk26++;
+ if (fire->ignitionDelay > 0) {
+ fire->ignitionDelay--;
+ } else if (fire->ignitionDelay == 0) {
+ fire->ignitionDelay = -1;
+ if ((fire->state == FIRE_STATE_3) || (fire->state == FIRE_STATE_1)) {
+ nextState = FIRE_STATE_0;
+ } else {
+ nextState = FIRE_STATE_1;
+ }
+ FireObj_SetState(fire, fire->dynamicSizeStep, nextState);
+ }
+ if ((fire->flags & 1) && (fire->state != FIRE_STATE_3) &&
+ (func_800CA1E8(globalCtx, &globalCtx->colCtx, fire->position.x, fire->position.z, &sp44, &waterBox) != 0) &&
+ ((fire->yScale * ((void)0, 6500.0f)) < (sp44 - fire->position.y))) { // Fake but IDK what else
+ FireObj_SetState(fire, fire->dynamicSizeStep, FIRE_STATE_3);
+ }
+ if ((fire->flags & 2) && (player->itemActionParam == 7)) {
+ Math_Vec3f_Diff(&player->swordInfo[0].tip, &fire->position, &dist);
+ if (Math3D_LengthSquared(&dist) < 400.0f) {
+ sp40 = 1;
+ }
+ }
+ if (sp40 != 0) {
+ if (fire->state == FIRE_STATE_3) {
+ if (player->unk_B28 > 0) {
+ FireObj_SetState(fire, fire->dynamicSizeStep, FIRE_STATE_0);
+ }
+ } else if (player->unk_B28 == 0) {
+ player->unk_B28 = 0xD2;
+ Audio_PlaySoundAtPosition(globalCtx, &fire->position, 20, NA_SE_EV_FLAME_IGNITION);
+ } else if (player->unk_B28 < 0xC8) {
+ player->unk_B28 = 0xC8;
+ }
+ }
+}
+
+void FireObj_Draw(GlobalContext* globalCtx, FireObj* fire) {
+ s32 pad;
+ FireObjLightParams* lightParams = &sFireObjLightParams[fire->unk27];
+
+ if (fire->state != FIRE_STATE_3) {
+ Vec3s vec;
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+ gSPSegment(
+ POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, (fire->unk26 * -20) & 511, 32, 128));
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, lightParams->unk4, lightParams->primColor.r, lightParams->primColor.g,
+ lightParams->primColor.b, lightParams->primColor.a);
+
+ gDPSetEnvColor(POLY_XLU_DISP++, lightParams->envColor.r, lightParams->envColor.g, lightParams->envColor.b, 0);
+
+ vec.x = 0;
+ vec.y = func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) + 0x8000;
+ vec.z = 0;
+ Matrix_SetStateRotationAndTranslation(fire->position.x, fire->position.y, fire->position.z, &vec);
+ Matrix_Scale(fire->xScale, fire->yScale, 1.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++, D_0407D590);
+ CLOSE_DISPS(globalCtx->state.gfxCtx);
+ }
+}
+
+#ifdef NON_EQUIVALENT
+// Accesses data incorrectly
+void FireObj_InitLight(GlobalContext* globalCtx, FireObjLight* light, u8* param_3, Vec3f* pos) {
+ FireObjLightParams* objectParams = &sFireObjLightParams[*param_3];
+
+ Lights_PointGlowSetInfo(&light->lightInfo, pos->x, pos->y, pos->z, objectParams->primColor.g,
+ objectParams->primColor.b, objectParams->primColor.a, objectParams->primColor.r);
+ light->light = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, (LightInfo*)&light->lightInfo);
+ light->unk12 = *param_3;
+}
+#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_InitLight.s")
+#endif
+
+void FireObj_DestroyLight(GlobalContext* globalCtx, FireObjLight* light) {
+ LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, light->light);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_FiniLight.s")
+#ifdef NON_EQUIVALENT
+// Accesses data incorrectly
+void FireObj_UpdateLight(GlobalContext* globalCtx, FireObjLight* light, FireObj* fire) {
+ FireObjLightParams* lightParams = &sFireObjLightParams[light->unk12];
+ s16 radius;
+ if (fire->state == FIRE_STATE_3) {
+ Lights_PointSetColorAndRadius((LightInfo*)&light->lightInfo, 0, 0, 0, -1);
+ } else {
+ radius = ((fire->yScale * 140.0f * fire->sizeInv) + 60.0f);
+
+ Lights_PointGlowSetInfo((LightInfo*)&light->lightInfo, fire->position.x,
+ (fire->position.y + (fire->yScale * 6500.0f)), fire->position.z,
+ ((s32)(Rand_ZeroOne() * lightParams->envColor.r) + lightParams->primColor.b),
+ ((s32)(Rand_ZeroOne() * lightParams->envColor.g) + lightParams->primColor.a),
+ ((s32)(Rand_ZeroOne() * lightParams->envColor.b) + lightParams->unk4), radius);
+ }
+}
+#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_UpdateLight.s")
+#endif
+
+void FireObj_Init(GlobalContext* globalCtx, FireObj* fire, FireObjInitParams* init, Actor* actor) {
+ FireObj* fire2 = fire;
+
+ FireObj_InitWithParams(globalCtx, fire, init);
+ Collider_InitCylinder(globalCtx, &fire->collision);
+ Collider_SetCylinder(globalCtx, &fire->collision, actor, &sFireObjCollisionInit);
+
+ fire2->collision.dim.radius = (fire->size * 4000.0f) + 2.5f;
+ fire2->collision.dim.height = fire->size * 16000.0f;
+ fire->collision.dim.yShift = fire->size * -1728.0f;
+ FireObj_InitLight(globalCtx, &fire->light, &init->unkC, &fire->position);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_Init.s")
+void FireObj_Destroy(GlobalContext* globalCtx, FireObj* fire) {
+ Collider_DestroyCylinder(globalCtx, &fire->collision);
+ FireObj_DestroyLight(globalCtx, &fire->light);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_Fini.s")
+void FireObj_SetState2(FireObj* fire, f32 dynamicSizeStep, u8 newState) {
+ FireObj_SetState(fire, dynamicSizeStep, newState);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_SetState2.s")
+void FireObj_Update(GlobalContext* globalCtx, FireObj* fire, Actor* actor) {
+ s32 pad; // Gamestate cast?
+ EnArrow* arrow = (EnArrow*)fire->collision.base.ac;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_Update.s")
+ FireObj_UpdateStateTransitions(globalCtx, fire);
+ if (fire->state == 3) {
+ if ((fire->collision.base.acFlags & 2) && (fire->collision.info.acHitInfo->toucher.dmgFlags & 0x800)) {
+ FireObj_SetState(fire, fire->dynamicSizeStep, 0);
+ }
+ } else if ((fire->collision.base.acFlags & 2) && (arrow->actor.update != NULL) &&
+ (arrow->actor.id == ACTOR_EN_ARROW)) {
+ arrow->actor.params = 0;
+ arrow->unk_1C0 = 0x800;
+ }
+ fire->collision.dim.pos.x = fire->position.x;
+ fire->collision.dim.pos.y = fire->position.y;
+ fire->collision.dim.pos.z = fire->position.z;
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &fire->collision.base);
+ FireObj_UpdateLight(globalCtx, &fire->light, fire);
+}