diff --git a/include/functions.h b/include/functions.h index 747e604c33..d2eee60615 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1691,19 +1691,12 @@ void SkelCurve_SetAnim(SkelAnimeCurve* skelCurve, TransformUpdateIndex* transUpd s32 SkelCurve_Update(GlobalContext* globalCtx, SkelAnimeCurve* skelCurve); void SkelCurve_Draw(Actor* actor, GlobalContext* globalCtx, SkelAnimeCurve* skelCurve, OverrideCurveLimbDraw overrideLimbDraw, PostCurveLimbDraw postLimbDraw, s32 lod, Actor* thisx); -void FireObj_InitWithParams(GlobalContext* globalCtx, FireObj* fire, FireObjInitParams* init); -void FireObj_SetState(FireObj* fire, f32 dynamicSizeStep, u8 newState); void FireObj_SetPosition(FireObj* fire, Vec3f* pos); -void FireObj_StepSize(FireObj* fire); -void FireObj_UpdateStateTransitions(GlobalContext* globalCtx, FireObj* fire); void FireObj_Draw(GlobalContext* globalCtx, FireObj* fire); -void FireObj_InitLight(GlobalContext* globalCtx, FireObjLight* light, u8* param_3, Vec3f* pos); -void FireObj_FiniLight(GlobalContext* globalCtx, FireObjLight* light); -void FireObj_UpdateLight(GlobalContext* globalCtx, FireObjLight* light, FireObj* fire); void FireObj_Init(GlobalContext* globalCtx, FireObj* fire, FireObjInitParams* init, Actor* actor); -void FireObj_Fini(GlobalContext* globalCtx, FireObj* fire); +void FireObj_Destroy(GlobalContext* globalCtx, FireObj* fire); void FireObj_SetState2(FireObj* fire, f32 dynamicSizeStep, u8 newState); -void FireObj_Update(GlobalContext* globalCtx, FireObj* fire); +void FireObj_Update(GlobalContext* globalCtx, FireObj* fire, Actor* actor); // void func_800F3940(void); // void func_800F39B4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_800F3A64(void); diff --git a/include/variables.h b/include/variables.h index 3770820bfa..8105107d4b 100644 --- a/include/variables.h +++ b/include/variables.h @@ -914,8 +914,6 @@ extern Actor* actorCutsceneCurrentCutsceneActor; extern GlobalContext* actorCutscenesGlobalCtxt; extern s16 actorCutsceneReturnCamera; extern s16 D_801BD8C6; -extern ColliderCylinderInit fireObjCollisionInit; -extern FireObjLightParams D_801BD8FC[2]; extern GameStateOverlay gGameStateOverlayTable[]; extern s32 graphNumGameStates; // extern UNK_TYPE2 D_801BDA70; @@ -2515,8 +2513,6 @@ extern f32 D_801DD774; extern f32 D_801DD780; extern f32 D_801DD7B0; extern f32 D_801DD7C0; -extern f32 D_801DD7D0; -extern f32 D_801DD7D4; extern f32 D_801DD7E0; extern f32 D_801DD7E4; extern f32 D_801DD7E8; @@ -4074,4 +4070,5 @@ extern GfxMasterList D_0E000000; extern UNK_TYPE D_0F000000; + #endif diff --git a/include/z64.h b/include/z64.h index dae4195b2a..533677efde 100644 --- a/include/z64.h +++ b/include/z64.h @@ -213,14 +213,9 @@ typedef struct { } FireObjInitParams; // size = 0xD typedef struct { - /* 0x0 */ u8 unk0; - /* 0x1 */ u8 unk1; - /* 0x2 */ u8 unk2; - /* 0x3 */ u8 unk3; + /* 0x0 */ Color_RGBA8 primColor; /* 0x4 */ u8 unk4; - /* 0x5 */ u8 unk5; - /* 0x6 */ u8 unk6; - /* 0x7 */ u8 unk7; + /* 0x5 */ Color_RGB8 envColor; } FireObjLightParams; // size = 0x8 //! @TODO: Make this use `sizeof(AnyFontTextureSymbol)` diff --git a/include/z64player.h b/include/z64player.h index 8bab2605fe..4f70c793d8 100644 --- a/include/z64player.h +++ b/include/z64player.h @@ -251,7 +251,7 @@ typedef struct Player { /* 0xAEC */ f32 unk_AEC; /* 0xAF0 */ Vec3f unk_AF0[2]; /* 0xB08 */ f32 unk_B08[8]; - /* 0xB28 */ s16 unk_B28; + /* 0xB28 */ s16 unk_B28; //Burning stick timer? /* 0xB2A */ s8 unk_B2A; /* 0xB2B */ s8 unk_B2B; /* 0xB2C */ f32 windSpeed; diff --git a/spec b/spec index 7251410c28..961e5328c8 100644 --- a/spec +++ b/spec @@ -491,7 +491,6 @@ beginseg include "build/src/code/z_fcurve_data_skelanime.o" include "build/data/code/code_801BD830.data.o" include "build/src/code/z_fireobj.o" - include "build/data/code/z_fireobj.data.o" include "build/src/code/z_game_dlftbls.o" include "build/src/code/z_horse.o" include "build/data/code/z_horse.data.o" diff --git a/src/code/z_fireobj.c b/src/code/z_fireobj.c index abc78fc4d3..79041a7137 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 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_FiniLight.s") +void FireObj_DestroyLight(GlobalContext* globalCtx, FireObjLight* light) { + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, light->light); +} +#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 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_Init.s") +void FireObj_Init(GlobalContext* globalCtx, FireObj* fire, FireObjInitParams* init, Actor* actor) { + FireObj* fire2 = fire; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_Fini.s") + FireObj_InitWithParams(globalCtx, fire, init); + Collider_InitCylinder(globalCtx, &fire->collision); + Collider_SetCylinder(globalCtx, &fire->collision, actor, &sFireObjCollisionInit); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_SetState2.s") + 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_Update.s") +void FireObj_Destroy(GlobalContext* globalCtx, FireObj* fire) { + Collider_DestroyCylinder(globalCtx, &fire->collision); + FireObj_DestroyLight(globalCtx, &fire->light); +} + +void FireObj_SetState2(FireObj* fire, f32 dynamicSizeStep, u8 newState) { + FireObj_SetState(fire, dynamicSizeStep, newState); +} + +void FireObj_Update(GlobalContext* globalCtx, FireObj* fire, Actor* actor) { + s32 pad; // Gamestate cast? + EnArrow* arrow = (EnArrow*)fire->collision.base.ac; + + 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); +} diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index b2e4792887..9ecd227629 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -1677,10 +1677,10 @@ 0x800F2FFC:("FireObj_UpdateStateTransitions",), 0x800F31EC:("FireObj_Draw",), 0x800F33F4:("FireObj_InitLight",), - 0x800F34C4:("FireObj_FiniLight",), + 0x800F34C4:("FireObj_DestroyLight",), 0x800F34EC:("FireObj_UpdateLight",), 0x800F36CC:("FireObj_Init",), - 0x800F37B0:("FireObj_Fini",), + 0x800F37B0:("FireObj_Destroy",), 0x800F37F0:("FireObj_SetState2",), 0x800F3820:("FireObj_Update",), 0x800F3940:("func_800F3940",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 3b4818a6e0..3ca0fa02e1 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -941,8 +941,8 @@ 0x801BD8C0:("actorCutscenesGlobalCtxt","GlobalContext*","",0x4), 0x801BD8C4:("actorCutsceneReturnCamera","s16","",0x2), 0x801BD8C6:("D_801BD8C6","s16","",0x2), - 0x801BD8D0:("fireObjCollisionInit","ColliderCylinderInit","",0x2c), - 0x801BD8FC:("D_801BD8FC","FireObjLightParams","[2]",0x10), + 0x801BD8D0:("sFireObjCollisionInit","ColliderCylinderInit","",0x2c), + 0x801BD8FC:("sFireObjLightParams","FireObjLightParams","[2]",0x10), 0x801BD910:("gGameStateOverlayTable","GameStateOverlay","[7]",0x150), 0x801BDA60:("graphNumGameStates","UNK_TYPE4","",0x4), 0x801BDA70:("D_801BDA70","UNK_TYPE2","",0x2),