diff --git a/assets/xml/objects/object_ikana_obj.xml b/assets/xml/objects/object_ikana_obj.xml index 6040495ab8..e0490a3495 100644 --- a/assets/xml/objects/object_ikana_obj.xml +++ b/assets/xml/objects/object_ikana_obj.xml @@ -17,15 +17,15 @@ - + - - + + - + - - + + @@ -39,7 +39,7 @@ - + @@ -51,11 +51,11 @@ - - - - - + + + + + diff --git a/spec b/spec index 251581be37..eda0cfe476 100644 --- a/spec +++ b/spec @@ -4137,8 +4137,7 @@ beginseg name "ovl_Bg_Ikana_Mirror" compress include "build/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.o" - include "build/data/ovl_Bg_Ikana_Mirror/ovl_Bg_Ikana_Mirror.data.o" - include "build/data/ovl_Bg_Ikana_Mirror/ovl_Bg_Ikana_Mirror.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Ikana_Mirror/ovl_Bg_Ikana_Mirror_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.c b/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.c index 0a3b7b4456..cfa67eb1de 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.c +++ b/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.c @@ -2,9 +2,15 @@ * File: z_bg_ikana_mirror.c * Overlay: ovl_Bg_Ikana_Mirror * Description: Stone Tower Temple - Mirror + * + * This mirror absorbs light reflected by the mirror shield or by another mirror of the same kind for a + * maximum of 400 frames (20 seconds) to then release light for the same number of frames it was charged. This number + * of frames is stored in the actor struct's lightRayCharge field and is updated in the BgIkanaMirror_Wait and + * BgIkanaMirror_EmitLight functions both described below. */ #include "z_bg_ikana_mirror.h" +#include "objects/object_ikana_obj/object_ikana_obj.h" #define FLAGS (ACTOR_FLAG_10) @@ -15,7 +21,11 @@ void BgIkanaMirror_Destroy(Actor* thisx, PlayState* play); void BgIkanaMirror_Update(Actor* thisx, PlayState* play); void BgIkanaMirror_Draw(Actor* thisx, PlayState* play); -#if 0 +void BgIkanaMirror_SetupWait(BgIkanaMirror* this); +void BgIkanaMirror_Wait(BgIkanaMirror* this, PlayState* play); +void BgIkanaMirror_SetupEmitLight(BgIkanaMirror* this); +void BgIkanaMirror_EmitLight(BgIkanaMirror* this, PlayState* play); + const ActorInit Bg_Ikana_Mirror_InitVars = { ACTOR_BG_IKANA_MIRROR, ACTORCAT_PROP, @@ -28,99 +38,371 @@ const ActorInit Bg_Ikana_Mirror_InitVars = { (ActorFunc)BgIkanaMirror_Draw, }; -// static ColliderTrisElementInit sTrisElementsInit[9] = { -static ColliderTrisElementInit D_80B7FF50[9] = { +static ColliderTrisElementInit sMirrorColliderElementsInit[] = { { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 0.0f, 21.600000381469727f, 13.699999809265137f }, { -25.299999237060547f, 6.0f, 8.399999618530273f }, { 25.299999237060547f, 6.0f, 8.399999618530273f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00200000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 0.0f, 21.6f, 13.7f }, { -25.3f, 6.0f, 8.4f }, { 25.3f, 6.0f, 8.4f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 0.0f, 45.0f, 13.699999809265137f }, { -25.299999237060547f, 6.0f, 8.399999618530273f }, { 0.0f, 21.600000381469727f, 13.699999809265137f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00200000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 0.0f, 45.0f, 13.7f }, { -25.3f, 6.0f, 8.4f }, { 0.0f, 21.6f, 13.7f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 0.0f, 45.0f, 13.699999809265137f }, { 0.0f, 21.600000381469727f, 13.699999809265137f }, { 25.299999237060547f, 6.0f, 8.399999618530273f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00200000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 0.0f, 45.0f, 13.7f }, { 0.0f, 21.6f, 13.7f }, { 25.3f, 6.0f, 8.4f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 0.0f, 45.0f, 13.699999809265137f }, { -25.299999237060547f, 45.0f, 8.399999618530273f }, { -25.299999237060547f, 6.0f, 8.399999618530273f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00200000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 0.0f, 45.0f, 13.7f }, { -25.3f, 45.0f, 8.4f }, { -25.3f, 6.0f, 8.4f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 0.0f, 45.0f, 13.699999809265137f }, { 25.299999237060547f, 6.0f, 8.399999618530273f }, { 25.299999237060547f, 45.0f, 8.399999618530273f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00200000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 0.0f, 45.0f, 13.7f }, { 25.3f, 6.0f, 8.4f }, { 25.3f, 45.0f, 8.4f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 0.0f, 45.0f, 13.699999809265137f }, { -17.899999618530273f, 64.0999984741211f, 8.399999618530273f }, { -25.299999237060547f, 45.0f, 8.399999618530273f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00200000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 0.0f, 45.0f, 13.7f }, { -17.9f, 64.1f, 8.4f }, { -25.3f, 45.0f, 8.4f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 0.0f, 45.0f, 13.699999809265137f }, { 25.299999237060547f, 45.0f, 8.399999618530273f }, { 17.899999618530273f, 64.0999984741211f, 8.399999618530273f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00200000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 0.0f, 45.0f, 13.7f }, { 25.3f, 45.0f, 8.4f }, { 17.9f, 64.1f, 8.4f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 0.0f, 45.0f, 13.699999809265137f }, { 0.0f, 72.0f, 8.399999618530273f }, { -17.899999618530273f, 64.0999984741211f, 8.399999618530273f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00200000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 0.0f, 45.0f, 13.7f }, { 0.0f, 72.0f, 8.4f }, { -17.9f, 64.1f, 8.4f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 0.0f, 45.0f, 13.699999809265137f }, { 17.899999618530273f, 64.0999984741211f, 8.399999618530273f }, { 0.0f, 72.0f, 8.399999618530273f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00200000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 0.0f, 45.0f, 13.7f }, { 17.9f, 64.1f, 8.4f }, { 0.0f, 72.0f, 8.4f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_80B8016C = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, OC1_NONE, OC2_NONE, COLSHAPE_TRIS, }, - 9, D_80B7FF50, // sTrisElementsInit, +static ColliderTrisInit sMirrorColliderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, + OC1_NONE, + OC2_NONE, + COLSHAPE_TRIS, + }, + ARRAY_COUNT(sMirrorColliderElementsInit), + sMirrorColliderElementsInit, }; -// static ColliderQuadInit sQuadInit = { -static ColliderQuadInit D_80B8017C = { - { COLTYPE_NONE, AT_ON | AT_TYPE_OTHER, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_QUAD, }, - { ELEMTYPE_UNK0, { 0x00200000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_NONE, }, - { { { 0.0f, 72.0f, 20.0f }, { 0.0f, 72.0f, 240.0f }, { 0.0f, 6.0f, 20.0f }, { 0.0f, 6.0f, 240.0f } } }, +static ColliderQuadInit sLightRaysCollidersInit[] = { + { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_OTHER, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK0, + { 0x00200000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_NONE, + }, + { { { 0.0f, 72.0f, 20.0f }, { 0.0f, 72.0f, 240.0f }, { 0.0f, 6.0f, 20.0f }, { 0.0f, 6.0f, 240.0f } } }, + }, + { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_OTHER, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK0, + { 0x00200000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_NONE, + }, + { { { 25.3f, 20.0f, 20.0f }, { 25.3f, 20.0f, 240.0f }, { -25.3f, 20.0f, 20.0f }, { -25.3f, 20.0f, 240.0f } } }, + } }; -// static ColliderQuadInit sQuadInit = { -static ColliderQuadInit D_80B801FC = { - { 0x41, AT_NONE | AT_TYPE_OTHER, AC_NONE, OC1_NONE, OC2_FIRST_ONLY | OC2_UNK1 | OC2_HIT_PLAYER, 0x70, }, - { 0xC1, { 0x41A00000, 0x41, 0xA0 }, { 0xC1CA6666, 0x41, 0xA0 }, TOUCH_ON | TOUCH_HIT | TOUCH_SFX_NORMAL | TOUCH_DREW_HITMARK, BUMP_NONE | BUMP_NO_DAMAGE | BUMP_NO_SWORD_SFX | BUMP_NO_HITMARK, OCELEM_NONE, }, - { { { -1.8339854079840734e-09f, -1.8626939990440405e-09f, -1.9208972190654094e-09f }, { 221185.5625f, 0.0f, 0.003921568859368563f }, { 0.0f, 0.0f, 0.0f }, { 2.8698592549372254e-42f, 1.0761972206014595e-42f, 2.2420775429197073e-44f } } }, -}; - -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B8021C[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 220, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void BgIkanaMirror_SetQuadVertices(BgIkanaMirror* this) { + ColliderQuadDimInit* dim; + ColliderQuad* lightRaysCollider; + Vec3f v0; + Vec3f v1; + Vec3f v2; + Vec3f v3; + s32 i; -extern ColliderTrisElementInit D_80B7FF50[9]; -extern ColliderTrisInit D_80B8016C; -extern ColliderQuadInit D_80B8017C; -extern ColliderQuadInit D_80B801FC; -extern InitChainEntry D_80B8021C[]; + Matrix_Push(); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + for (i = 0; i < ARRAY_COUNT(this->lightRaysColliders); i++) { + dim = &sLightRaysCollidersInit[i].dim; + Matrix_MultVec3f(&dim->quad[0], &v0); + Matrix_MultVec3f(&dim->quad[1], &v1); + Matrix_MultVec3f(&dim->quad[2], &v2); + Matrix_MultVec3f(&dim->quad[3], &v3); + lightRaysCollider = &this->lightRaysColliders[i]; + Collider_SetQuadVertices(lightRaysCollider, &v0, &v1, &v2, &v3); + } -extern UNK_TYPE D_06001E18; -extern UNK_TYPE D_06002358; + Matrix_Pop(); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Mirror/func_80B7F730.s") +void BgIkanaMirror_Init(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + BgIkanaMirror* this = THIS; + ColliderTrisElementInit* element; + Vec3f vertices[3]; + s32 i; + s32 j; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Mirror/BgIkanaMirror_Init.s") + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(play, &this->dyna, &gStoneTowerTempleMirrorCol); + Collider_InitTris(play, &this->mirrorCollider); + Collider_SetTris(play, &this->mirrorCollider, &this->dyna.actor, &sMirrorColliderInit, + this->mirrorColliderElements); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Mirror/BgIkanaMirror_Destroy.s") + for (i = 0; i < ARRAY_COUNT(sMirrorColliderElementsInit); i++) { + element = &sMirrorColliderInit.elements[i]; + for (j = 0; j < 3; j++) { + Matrix_MultVec3f(&element->dim.vtx[j], &vertices[j]); + } + Collider_SetTrisVertices(&this->mirrorCollider, i, &vertices[0], &vertices[1], &vertices[2]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Mirror/func_80B7FA84.s") + for (i = 0; i < ARRAY_COUNT(this->lightRaysColliders); i++) { + Collider_InitQuad(play, &this->lightRaysColliders[i]); + Collider_SetQuad(play, &this->lightRaysColliders[i], &this->dyna.actor, &sLightRaysCollidersInit[i]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Mirror/func_80B7FA9C.s") + BgIkanaMirror_SetQuadVertices(this); + this->lightAbsorptionTexScroll = Lib_SegmentedToVirtual(&gStoneTowerTempleMirrorLightAbsorptionTexAnim); + this->lightEmissionTexScroll = Lib_SegmentedToVirtual(&gStoneTowerTempleMirrorLightEmissionTexAnim); + BgIkanaMirror_SetupWait(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Mirror/func_80B7FB84.s") +void BgIkanaMirror_Destroy(Actor* thisx, PlayState* play) { + BgIkanaMirror* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Mirror/func_80B7FBA4.s") + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); + Collider_DestroyTris(play, &this->mirrorCollider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Mirror/BgIkanaMirror_Update.s") + for (i = 0; i < ARRAY_COUNT(this->lightRaysColliders); i++) { + Collider_DestroyQuad(play, &this->lightRaysColliders[i]); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Mirror/BgIkanaMirror_Draw.s") +void BgIkanaMirror_SetupWait(BgIkanaMirror* this) { + this->isEmittingLight = 0; + this->actionFunc = BgIkanaMirror_Wait; +} + +/** + * Charges the mirror with light, increment the alpha value for the light absorption textures and decrement the alpha + * value for the light emission textures. + */ +void BgIkanaMirror_Wait(BgIkanaMirror* this, PlayState* play) { + s8 isEmittingLight; + s32 startEmittingLight = false; + + // The light emission texture gradually fades. + if (this->lightEmissionAlpha > 100) { + this->lightEmissionAlpha -= 100; + } else { + this->lightEmissionAlpha = 0; + } + + // This checks if light is touching the mirror. + if (this->mirrorCollider.base.acFlags & AC_HIT) { + this->mirrorCollider.base.acFlags &= ~AC_HIT; + this->isEmittingLight = 0; + + if (this->lightRayCharge < 400) { + this->lightRayCharge++; + } + + if (this->lightAbsorptionAlpha < 195) { + this->lightAbsorptionAlpha += 60; + } else { + this->lightAbsorptionAlpha = 255; + } + + } else { + isEmittingLight = this->isEmittingLight; + + if (isEmittingLight > 0) { + startEmittingLight = true; + } else if (this->lightRayCharge > 0) { + this->isEmittingLight = isEmittingLight + 1; + } + } + + if (startEmittingLight) { + BgIkanaMirror_SetupEmitLight(this); + } else { + CollisionCheck_SetAC(play, &play->colChkCtx, &this->mirrorCollider.base); + } +} + +void BgIkanaMirror_SetupEmitLight(BgIkanaMirror* this) { + this->dyna.actor.flags |= ACTOR_FLAG_20; + this->actionFunc = BgIkanaMirror_EmitLight; +} + +/** + * Depletes the mirror's light and release it, increase alpha value for the light + * emission textures and decrease the alpha value for the light absorption textures. + */ +void BgIkanaMirror_EmitLight(BgIkanaMirror* this, PlayState* play) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->lightRaysColliders); i++) { + if (this->lightRaysColliders[i].base.atFlags & AT_HIT) { + this->lightRaysColliders[i].base.atFlags &= ~AT_HIT; + } + } + + if (this->lightEmissionAlpha < 155) { + this->lightEmissionAlpha += 100; + } else { + this->lightEmissionAlpha = 255; + } + + if (this->lightAbsorptionAlpha > 60) { + this->lightAbsorptionAlpha -= 60; + } else { + this->lightAbsorptionAlpha = 0; + } + + if (this->lightRayCharge > 0) { + this->lightRayCharge--; + + for (i = 0; i < ARRAY_COUNT(this->lightRaysColliders); i++) { + CollisionCheck_SetAT(play, &play->colChkCtx, &this->lightRaysColliders[i].base); + } + + } else { + this->dyna.actor.flags &= ~ACTOR_FLAG_20; + BgIkanaMirror_SetupWait(this); + } +} + +void BgIkanaMirror_Update(Actor* thisx, PlayState* play) { + BgIkanaMirror* this = THIS; + + this->actionFunc(this, play); +} + +void BgIkanaMirror_Draw(Actor* thisx, PlayState* play) { + s32 pad; + BgIkanaMirror* this = THIS; + + OPEN_DISPS(play->state.gfxCtx); + func_8012C28C(play->state.gfxCtx); + func_8012C2DC(play->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gStoneTowerTempleMirrorDL); + + if (this->lightAbsorptionAlpha > 0) { + AnimatedMat_Draw(play, this->lightAbsorptionTexScroll); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, this->lightAbsorptionAlpha); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gStoneTowerTempleMirrorLightAbsorptionDL); + } + + if (this->lightEmissionAlpha > 0) { + f32 alphaFraction = this->lightEmissionAlpha * (1.0f / 255.0f); + s32 primColorAlpha = (s32)(alphaFraction * 123.0f); + s32 envColorAlpha = (s32)(alphaFraction * 185.0f); + + AnimatedMat_Draw(play, this->lightEmissionTexScroll); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, primColorAlpha); + gDPSetEnvColor(POLY_XLU_DISP++, 215, 215, 255, envColorAlpha); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gStoneTowerTempleMirrorLightEmissionDL); + } + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.h b/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.h index c9f8812084..5bd2724804 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.h +++ b/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.h @@ -8,12 +8,17 @@ struct BgIkanaMirror; typedef void (*BgIkanaMirrorActionFunc)(struct BgIkanaMirror*, PlayState*); typedef struct BgIkanaMirror { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x474]; - /* 0x05B8 */ BgIkanaMirrorActionFunc actionFunc; - /* 0x05BC */ char unk_5BC[0x10]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ColliderTris mirrorCollider; + /* 0x17C */ ColliderTrisElement mirrorColliderElements[9]; + /* 0x4B8 */ ColliderQuad lightRaysColliders[2]; + /* 0x5B8 */ BgIkanaMirrorActionFunc actionFunc; + /* 0x5BC */ AnimatedMaterial* lightAbsorptionTexScroll; + /* 0x5C0 */ AnimatedMaterial* lightEmissionTexScroll; + /* 0x5C4 */ s16 lightRayCharge; + /* 0x5C6 */ u8 lightAbsorptionAlpha; + /* 0x5C7 */ u8 lightEmissionAlpha; + /* 0x5C8 */ s8 isEmittingLight; } BgIkanaMirror; // size = 0x5CC -extern const ActorInit Bg_Ikana_Mirror_InitVars; - #endif // Z_BG_IKANA_MIRROR_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index f861588a5f..2ad13737b6 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -14574,13 +14574,13 @@ 0x80B7F398:("func_80B7F398",), 0x80B7F474:("BgIkanaBlock_Update",), 0x80B7F564:("func_80B7F564",), - 0x80B7F730:("func_80B7F730",), + 0x80B7F730:("BgIkanaMirror_SetQuadVertices",), 0x80B7F850:("BgIkanaMirror_Init",), 0x80B7FA00:("BgIkanaMirror_Destroy",), - 0x80B7FA84:("func_80B7FA84",), - 0x80B7FA9C:("func_80B7FA9C",), - 0x80B7FB84:("func_80B7FB84",), - 0x80B7FBA4:("func_80B7FBA4",), + 0x80B7FA84:("BgIkanaMirror_SetupWait",), + 0x80B7FA9C:("BgIkanaMirror_Wait",), + 0x80B7FB84:("BgIkanaMirror_SetupEmitLight",), + 0x80B7FBA4:("BgIkanaMirror_EmitLight",), 0x80B7FCB8:("BgIkanaMirror_Update",), 0x80B7FCDC:("BgIkanaMirror_Draw",), 0x80B802E0:("func_80B802E0",),