En_Holl (Loading Halls/Holes) OK and mostly documented. (#270)

* EnHoll_Destroy() matching.

* EnHoll_Update() matching.

* EnHoll_Draw() matching and mostly documented.

* func_808999B0() matching and mostly documented.

* En_Holl OK (some asm remains)

* Renamed macros.

* func_80899B88 matching, but control flow could use some work.

* Got rid of GOTO in func_80899B88.

* Removed as many returns and magic numbers as currently possible.

* Renamed previous two functions to EnHoll_ChangeRooms and
EnHoll_VisibleIdle.

* EnHoll_SetAlwaysZero matching.

* EnHoll_TransparentIdle matching.

* func_8089A0C0 matching and mostly documented.

* func_8089A238 matching and mostly documented.

* Deleted last GLOBAL_ASM pragma.

* Final documentation for En_Holl PR.

* Switched spec to generated reloc.

* Clean up macros.

* Rename functions.

* Simplify name of ActionFunc array.

* Renamed globalCtx->unk_18878 to bgCoverAlpha.

* Ran format.sh.

* Added c file header.

* Update src/overlays/actors/ovl_En_Holl/z_en_holl.c

add trailing comma to sActionFuncs[]

Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com>

* Update src/overlays/actors/ovl_En_Holl/z_en_holl.c

replace UNK_TYPE with s32.

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* Run format.sh.

* s32 pad and declaration formatting

* Remove comma in EnHoll_TransparentIdle.

* Renamed sThis to sInstancePlayingSound.

* renamed gfxP to dl

* Improved affine transformation documentation.

* ran format.sh

* Updated documentation to be doxygen compatible.

* Extracted assets.

* fix bss

* Update src/overlays/actors/ovl_En_Holl/z_en_holl.c

replace bitmask == 0 with !

Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com>

* Rename extracted asset variables.

* Renamed argument to macro functions to match .c

* renamed Vertices to Vtx.

* Renamed Vtx and DL.

* Update src/overlays/actors/ovl_En_Holl/z_en_holl.c

Shorten documentation.

Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>

* Apply suggestions from code review

Newline changes for readability.

Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>

* Update src/overlays/actors/ovl_En_Holl/z_en_holl.c

* Update src/overlays/actors/ovl_En_Holl/z_en_holl.c

Change oldCurrRoom to tempRoom.

* Apply suggestions from code review

engineer124's suggestions

Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>

Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com>
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
This commit is contained in:
rylieb 2021-09-01 17:39:01 -06:00 committed by GitHub
parent c96d1df320
commit 6fb180d0e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 404 additions and 47 deletions

View File

@ -0,0 +1,9 @@
<Root>
<File Name="ovl_En_Holl" BaseAddress="0x80899960" RangeStart="0x0BF0" RangeEnd="0x0C58" Segment="128">
<Array Name="gEnHollCentralPlaneVtx" Count="4" Offset="0x0BF0">
<Vtx/>
</Array>
<DList Name="gEnHollCentralPlaneDL" Offset="0x0C30"/>
</File>
</Root>

View File

@ -427,7 +427,7 @@ extern s801AEC84 D_801AEC84[13];
extern f32 actorMovementScale;
extern f32 D_801AECF0;
extern f32 D_801AECF4;
// extern UNK_TYPE1 D_801AED48;
extern s16 D_801AED48[8];
// extern UNK_TYPE4 D_801AED58;
extern Color_RGBA8 actorDefaultHitColor;
// extern UNK_TYPE1 D_801AED8C;

View File

@ -1553,7 +1553,7 @@ struct GlobalContext {
/* 0x18780 */ void (*func_18780)(Player* player, struct GlobalContext* globalCtx);
/* 0x18784 */ s32 (*damagePlayer)(struct GlobalContext* globalCtx, s32 damage);
/* 0x18788 */ void (*talkWithPlayer)(struct GlobalContext* globalCtx, Actor* actor);
/* 0x1878C */ void* unk_1878C; //! @TODO: Determine function prototype
/* 0x1878C */ void (*unk_1878C)(struct GlobalContext* globalCtx);
/* 0x18790 */ void* unk_18790; //! @TODO: Determine function prototype
/* 0x18794 */ void* unk_18794; //! @TODO: Determine function prototype
/* 0x18798 */ s32 (*setPlayerTalkAnim)(struct GlobalContext* globalCtx, void* talkAnim, s32 arg2);
@ -1580,7 +1580,7 @@ struct GlobalContext {
/* 0x18874 */ u8 skyboxId;
/* 0x18875 */ s8 sceneLoadFlag; // "fade_direction"
/* 0x18876 */ s16 unk_18876;
/* 0x18878 */ s16 unk_18878;
/* 0x18878 */ s16 bgCoverAlpha;
/* 0x1887A */ u16 nextEntranceIndex;
/* 0x1887C */ s8 unk_1887C;
/* 0x1887D */ s8 unk_1887D;

3
spec
View File

@ -905,8 +905,7 @@ beginseg
name "ovl_En_Holl"
compress
include "build/src/overlays/actors/ovl_En_Holl/z_en_holl.o"
include "build/data/ovl_En_Holl/ovl_En_Holl.data.o"
include "build/data/ovl_En_Holl/ovl_En_Holl.reloc.o"
include "build/src/overlays/actors/ovl_En_Holl/ovl_En_Holl_reloc.o"
endseg
beginseg

View File

@ -457,6 +457,12 @@ f32 Actor_XZDistanceToPoint(Actor* actor, Vec3f* point) {
return Math_Vec3f_DistXZ(&actor->world.pos, point);
}
/** Performs the affine (linear) transformation from world coordinates to actor coordinates
*
* @param[in] actor The actor whose coordinate system to transform to.
* @param[out] offset The transformed coordinates.
* @param[in] point The point to transform to actor coordinates.
*/
void Actor_CalcOffsetOrientedToDrawRotation(Actor* actor, Vec3f* offset, Vec3f* point) {
f32 cos_rot_y;
f32 sin_rot_y;

View File

@ -38,10 +38,6 @@ TriNorm D_801EF5C8;
TriNorm D_801EF600;
TriNorm D_801EF638;
//! @TODO: These are fake bss symbols likely related to z_message_nes
UNK_TYPE1 D_801EF66C;
UNK_TYPE1 D_801EF66D;
/**
* Gets the damage and effect that should be applied for the collision between
* `at` and `ac`, referring to the ac actor's damage chart if applicable.

View File

@ -1,3 +1,4 @@
#include "prevent_bss_reordering.h"
#include "global.h"
QuakeRequest sQuakeRequest[4];

View File

@ -1,3 +1,42 @@
/** @file
* File: z_en_holl.c
* Overlay: ovl_En_Holl
* Description: Loading Halls/Holes
*
* This actor has several different types, which can be thought of as a bitfield of size 3:
* bit 0 = Orientation: Horizontal (Hall) or Vertical (Hole)
* bit 1 = Alpha: TRANSPARENT (alpha=0) or VISIBLE (alpha=[0,255])
* bit 2 = Space to Load: Room or Scene
* Note: The meaning of bit 1 is slightly different for Halls than Holes.
* For Halls, bit 1 being set indicates the actor shall not draw.
* For Holes, bit 1 being set indicates the bgCover shall be applied.
*
* There are only 5 types instead of the expected 8, because the only "Scene changer" is horizontal and visible.
*
* Halls take the shape of a rectangular box, and Holes take the shape of a circular cylinder.
*
* Each En_Holl has a number of distinct planes inside, which, when intersected with the En_Holl itself, take the shape
* of either a rectangle or a circle, respectively. Being within this rectangle or circle is necessary to achieve the
* effect of the plane.
*
* Every En_Holl has pairs of at least the first two planes below. Only Visible Room-Changing Halls get pairs of the
* last two planes. All planes are ordered from greatest to smallest distance from the central plane, which determines
* the side the player is on.
*
* @sa sActivationPlaneDistance, EN_HOLL_ACTIVATION_PLANE_DISTANCE, and EN_HOLL_ACTIVATION_PLANE_DISTANCE_VERTICAL
* @sa sLoadingPlaneDistance, EN_HOLL_LOADING_PLANE_DISTANCE, and EN_HOLL_LOADING_PLANE_DISTANCE_VERTICAL
* @sa sTranslucencyPlaneDistance
* @sa sTransparencyPlaneDistance
*
* Since, all these planes except the central plane are duplicated on either side of the actor, this means that there
* are a total of 5 (or 9 for Type 0) planes that crossing will produce an effect. The most noticeable effect is the
* room/scene loading, which has historically led to this actor being erroneously referred to as a "loading plane".
* However, the loading plane(s) are only one of many planes in the actor, which is why "loading hall/hole" is a more
* accurate name for En_Holl. A given instance can be called either a "loading hall" if it is horizontal, or a "loading
* hole" if it is vertical. It is worth noting that "Holl" is a portmanteau of "hall" and "hole", though whether that
* was the origin of the actor name or not is unknown.
*/
#include "z_en_holl.h"
#define FLAGS 0x00000010
@ -9,9 +48,15 @@ void EnHoll_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnHoll_Update(Actor* thisx, GlobalContext* globalCtx);
void EnHoll_Draw(Actor* thisx, GlobalContext* globalCtx);
void func_8089A330(EnHoll* this, GlobalContext* globalCtx);
void EnHoll_SetupAction(EnHoll* this);
void EnHoll_SetPlayerSide(GlobalContext* globalCtx, EnHoll* this, Vec3f* transformedPlayerPos);
void EnHoll_ChangeRooms(GlobalContext* globalCtx);
void EnHoll_VisibleIdle(EnHoll* this, GlobalContext* globalCtx);
void EnHoll_VerticalIdle(EnHoll* this, GlobalContext* globalCtx);
void EnHoll_TransparentIdle(EnHoll* this, GlobalContext* globalCtx);
void EnHoll_VerticalBgCoverIdle(EnHoll* this, GlobalContext* globalCtx);
void EnHoll_RoomTransitionIdle(EnHoll* this, GlobalContext* globalCtx);
#if 0
const ActorInit En_Holl_InitVars = {
ACTOR_EN_HOLL,
ACTORCAT_DOOR,
@ -24,37 +69,277 @@ const ActorInit En_Holl_InitVars = {
(ActorFunc)EnHoll_Draw,
};
// static InitChainEntry sInitChain[] = {
static InitChainEntry D_8089A5D0[] = {
#include "overlays/ovl_En_Holl/ovl_En_Holl.c"
static EnHoll* sInstancePlayingSound = NULL;
static EnHollActionFunc sActionFuncs[] = {
EnHoll_VisibleIdle, EnHoll_VerticalIdle, EnHoll_TransparentIdle, EnHoll_VerticalBgCoverIdle, EnHoll_VisibleIdle,
};
static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP),
};
#endif
//! Visible Halls: Being inside this plane enables the execution of more code within the actionFunc.
static f32 sActivationPlaneDistance = 200.0f;
extern InitChainEntry D_8089A5D0[];
//! Visible Halls: Crossing this plane will change rooms/scenes.
static f32 sLoadingPlaneDistance = 150.0f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/func_80899960.s")
//! Visible Room Halls: Being inside this plane indicates the draw function will render using POLY_XLU.
static f32 sTranslucencyPlaneDistance = 100.0f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/func_808999B0.s")
//! Visible Room Halls: Being inside this plane indicates the draw function won't render.
static f32 sTransparencyPlaneDistance = 50.0f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/EnHoll_Init.s")
void EnHoll_SetupAction(EnHoll* this) {
this->type = EN_HOLL_GET_TYPE(this);
this->actionFunc = sActionFuncs[this->type];
if (EN_HOLL_IS_VISIBLE(this)) {
this->alpha = 255;
} else {
this->actor.draw = NULL;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/EnHoll_Destroy.s")
void EnHoll_SetPlayerSide(GlobalContext* globalCtx, EnHoll* this, Vec3f* transformedPlayerPos) {
Player* player = PLAYER;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/func_80899ACC.s")
Actor_CalcOffsetOrientedToDrawRotation(&this->actor, transformedPlayerPos, &player->actor.world.pos);
this->playerSide = (transformedPlayerPos->z < 0.0f) ? EN_HOLL_BEHIND : EN_HOLL_BEFORE;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/func_80899B88.s")
void EnHoll_Init(Actor* thisx, GlobalContext* globalCtx) {
EnHoll* this = THIS;
s32 pad;
Vec3f transformedPlayerPos;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/func_80899F30.s")
Actor_ProcessInitChain(&this->actor, sInitChain);
EnHoll_SetupAction(this);
this->bgCoverAlphaActive = false;
this->alpha = 255;
EnHoll_SetPlayerSide(globalCtx, this, &transformedPlayerPos);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/func_8089A0C0.s")
void EnHoll_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnHoll* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/func_8089A238.s")
if (!EN_HOLL_IS_SCENE_CHANGER(this)) {
u32 enHollId = EN_HOLL_GET_ID_CAST(this);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/func_8089A330.s")
globalCtx->doorCtx.transitionActorList[enHollId].id = -globalCtx->doorCtx.transitionActorList[enHollId].id;
if (this == sInstancePlayingSound) {
sInstancePlayingSound = NULL;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/EnHoll_Update.s")
void EnHoll_ChangeRooms(GlobalContext* globalCtx) {
Room tempRoom = globalCtx->roomCtx.currRoom;
globalCtx->roomCtx.currRoom = globalCtx->roomCtx.prevRoom;
globalCtx->roomCtx.prevRoom = tempRoom;
globalCtx->roomCtx.activeMemPage ^= 1;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Holl/EnHoll_Draw.s")
void EnHoll_VisibleIdle(EnHoll* this, GlobalContext* globalCtx) {
s32 pad;
Vec3f transformedPlayerPos;
f32 playerDistFromCentralPlane;
if (this->type == EN_HOLL_TYPE_DEFAULT) {
u32 actorCtxBitmask = (globalCtx->actorCtx.unkC & 0x2AA) >> 1 | (globalCtx->actorCtx.unkC & 0x155);
u32 zActorBitmask = D_801AED48[EN_HOLL_GET_Z_ACTOR_BITMASK_INDEX(this)];
if (!(actorCtxBitmask & zActorBitmask)) {
Actor_MarkForDeath(&this->actor);
return;
}
if (this == sInstancePlayingSound) {
func_800B9010(&this->actor, NA_SE_EV_INVISIBLE_MONKEY - SFX_FLAG);
}
}
if ((globalCtx->sceneLoadFlag != 0) || (globalCtx->unk_18B4A != 0)) {
this->alpha = 255;
} else {
f32 enHollBottom = EN_HOLL_BOTTOM_DEFAULT;
f32 enHollHalfwidth = EN_HOLL_HALFWIDTH_DEFAULT;
EnHoll_SetPlayerSide(globalCtx, this, &transformedPlayerPos);
playerDistFromCentralPlane = fabsf(transformedPlayerPos.z);
if (globalCtx->sceneNum == SCENE_IKANA) {
enHollBottom = EN_HOLL_BOTTOM_IKANA;
enHollHalfwidth = EN_HOLL_HALFWIDTH_IKANA;
}
if ((enHollBottom < transformedPlayerPos.y) && (transformedPlayerPos.y < EN_HOLL_TOP_DEFAULT) &&
(fabsf(transformedPlayerPos.x) < enHollHalfwidth) &&
(playerDistFromCentralPlane < sActivationPlaneDistance)) {
u32 enHollId = EN_HOLL_GET_ID_AND(this);
if (sLoadingPlaneDistance < playerDistFromCentralPlane) {
if ((globalCtx->roomCtx.prevRoom.num >= 0) && (globalCtx->roomCtx.unk31 == 0)) {
this->actor.room = globalCtx->doorCtx.transitionActorList[enHollId].sides[this->playerSide].room;
if (globalCtx->roomCtx.prevRoom.num == this->actor.room) {
EnHoll_ChangeRooms(globalCtx);
}
func_8012EBF8(globalCtx, &globalCtx->roomCtx);
}
} else if (this->type == EN_HOLL_TYPE_SCENE_CHANGER) {
globalCtx->nextEntranceIndex = globalCtx->setupExitList[EN_HOLL_GET_EXIT_LIST_INDEX(this)];
gSaveContext.unk_3DBB = 1;
Scene_SetExitFade(globalCtx);
globalCtx->sceneLoadFlag = 0x14;
globalCtx->unk_1878C(globalCtx);
} else {
this->actor.room = globalCtx->doorCtx.transitionActorList[enHollId].sides[this->playerSide ^ 1].room;
if (globalCtx->roomCtx.prevRoom.num < 0) {
Room_StartRoomTransition(globalCtx, &globalCtx->roomCtx, this->actor.room);
if (this == sInstancePlayingSound) {
sInstancePlayingSound = NULL;
}
} else {
s32 unclampedAlpha = EN_HOLL_SCALE_ALPHA(playerDistFromCentralPlane);
this->alpha = CLAMP(unclampedAlpha, 0, 255);
if (globalCtx->roomCtx.currRoom.num != this->actor.room) {
EnHoll_ChangeRooms(globalCtx);
}
}
}
} else if ((this->type == EN_HOLL_TYPE_DEFAULT) && (globalCtx->sceneNum == SCENE_26SARUNOMORI) &&
(sInstancePlayingSound == NULL)) {
sInstancePlayingSound = this;
}
}
}
void EnHoll_TransparentIdle(EnHoll* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
s32 useViewEye = D_801D0D50 || globalCtx->csCtx.state != 0;
Vec3f transformedPlayerPos;
f32 enHollTop;
f32 playerDistFromCentralPlane;
Actor_CalcOffsetOrientedToDrawRotation(&this->actor, &transformedPlayerPos,
useViewEye ? &globalCtx->view.eye : &player->actor.world.pos);
enHollTop = (globalCtx->sceneNum == SCENE_PIRATE) ? EN_HOLL_TOP_PIRATE : EN_HOLL_TOP_DEFAULT;
if ((transformedPlayerPos.y > EN_HOLL_BOTTOM_DEFAULT) && (transformedPlayerPos.y < enHollTop) &&
(fabsf(transformedPlayerPos.x) < EN_HOLL_HALFWIDTH_TRANSPARENT)) {
if (playerDistFromCentralPlane = fabsf(transformedPlayerPos.z),
playerDistFromCentralPlane < EN_HOLL_ACTIVATION_PLANE_DISTANCE &&
playerDistFromCentralPlane > EN_HOLL_LOADING_PLANE_DISTANCE) {
s32 enHollId = EN_HOLL_GET_ID_CAST(this);
s32 playerSide = (transformedPlayerPos.z < 0.0f) ? EN_HOLL_BEHIND : EN_HOLL_BEFORE;
TransitionActorEntry* transitionActorEntry = &globalCtx->doorCtx.transitionActorList[enHollId];
s8 room = transitionActorEntry->sides[playerSide].room;
this->actor.room = room;
if ((this->actor.room != globalCtx->roomCtx.currRoom.num) &&
Room_StartRoomTransition(globalCtx, &globalCtx->roomCtx, this->actor.room)) {
this->actionFunc = EnHoll_RoomTransitionIdle;
}
}
}
}
void EnHoll_VerticalBgCoverIdle(EnHoll* this, GlobalContext* globalCtx) {
f32 playerDistFromCentralPlane;
if ((this->actor.xzDistToPlayer < EN_HOLL_RADIUS) &&
(playerDistFromCentralPlane = fabsf(this->actor.yDistToPlayer),
playerDistFromCentralPlane < EN_HOLL_ACTIVATION_PLANE_DISTANCE_VERTICAL)) {
if (playerDistFromCentralPlane < EN_HOLL_LOADING_PLANE_DISTANCE_VERTICAL) {
globalCtx->bgCoverAlpha = 255;
} else {
globalCtx->bgCoverAlpha = EN_HOLL_SCALE_BG_COVER_ALPHA(playerDistFromCentralPlane);
}
if (playerDistFromCentralPlane > EN_HOLL_LOADING_PLANE_DISTANCE_VERTICAL) {
s32 enHollId = EN_HOLL_GET_ID_CAST(this);
s32 playerSide = (this->actor.yDistToPlayer > 0.0f) ? EN_HOLL_ABOVE : EN_HOLL_BELOW;
this->actor.room = globalCtx->doorCtx.transitionActorList[enHollId].sides[playerSide].room;
if ((this->actor.room != globalCtx->roomCtx.currRoom.num) &&
Room_StartRoomTransition(globalCtx, &globalCtx->roomCtx, this->actor.room)) {
this->actionFunc = EnHoll_RoomTransitionIdle;
this->bgCoverAlphaActive = true;
}
}
} else if (this->bgCoverAlphaActive) {
this->bgCoverAlphaActive = false;
globalCtx->bgCoverAlpha = 0;
}
}
void EnHoll_VerticalIdle(EnHoll* this, GlobalContext* globalCtx) {
if (this->actor.xzDistToPlayer < EN_HOLL_RADIUS) {
f32 playerDistFromCentralPlane = fabsf(this->actor.yDistToPlayer);
if (playerDistFromCentralPlane < EN_HOLL_ACTIVATION_PLANE_DISTANCE_VERTICAL &&
playerDistFromCentralPlane > EN_HOLL_LOADING_PLANE_DISTANCE_VERTICAL) {
s32 enHollId = EN_HOLL_GET_ID_CAST(this);
s32 playerSide = (this->actor.yDistToPlayer > 0.0f) ? EN_HOLL_ABOVE : EN_HOLL_BELOW;
this->actor.room = globalCtx->doorCtx.transitionActorList[enHollId].sides[playerSide].room;
if ((this->actor.room != globalCtx->roomCtx.currRoom.num) &&
Room_StartRoomTransition(globalCtx, &globalCtx->roomCtx, this->actor.room)) {
this->actionFunc = EnHoll_RoomTransitionIdle;
}
}
}
}
void EnHoll_RoomTransitionIdle(EnHoll* this, GlobalContext* globalCtx) {
if (globalCtx->roomCtx.unk31 == 0) {
func_8012EBF8(globalCtx, &globalCtx->roomCtx);
if (globalCtx->bgCoverAlpha == 0) {
this->bgCoverAlphaActive = false;
}
EnHoll_SetupAction(this);
}
}
void EnHoll_Update(Actor* thisx, GlobalContext* globalCtx) {
EnHoll* this = THIS;
Player* player = PLAYER;
if ((globalCtx->sceneLoadFlag == 0) && (globalCtx->unk_18B4A == 0) && !(player->stateFlags1 & 0x200)) {
this->actionFunc(this, globalCtx);
}
}
void EnHoll_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnHoll* this = THIS;
Gfx* dl;
u32 dlIndex;
if (this->alpha != 0) {
OPEN_DISPS(globalCtx->state.gfxCtx);
if (this->alpha == 255) {
dl = POLY_OPA_DISP;
dlIndex = 37;
} else {
dl = POLY_XLU_DISP;
dlIndex = 0;
}
dl = Gfx_CallSetupDL(dl, dlIndex);
if (this->playerSide == EN_HOLL_BEHIND) {
SysMatrix_InsertYRotation_f(M_PI, MTXMODE_APPLY);
}
gSPMatrix(dl++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetPrimColor(dl++, 0, 0, 0, 0, 0, this->alpha);
gSPDisplayList(dl++, gEnHollCentralPlaneDL);
if (this->alpha == 255) {
POLY_OPA_DISP = dl;
} else {
POLY_XLU_DISP = dl;
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
}

View File

@ -7,12 +7,71 @@ struct EnHoll;
typedef void (*EnHollActionFunc)(struct EnHoll*, GlobalContext*);
typedef enum {
/* 0 */ EN_HOLL_TYPE_DEFAULT,
/* 1 */ EN_HOLL_TYPE_VERTICAL,
/* 2 */ EN_HOLL_TYPE_TRANSPARENT,
/* 3 */ EN_HOLL_TYPE_VERTICAL_BG_COVER,
/* 4 */ EN_HOLL_TYPE_SCENE_CHANGER
} EnHollTypes;
typedef enum {
/* 0 */ EN_HOLL_BEHIND,
/* 1 */ EN_HOLL_BEFORE
} EnHollSides;
typedef enum {
/* 0 */ EN_HOLL_ABOVE,
/* 1 */ EN_HOLL_BELOW
} EnHollSidesVertical;
typedef struct EnHoll {
/* 0x0000 */ Actor actor;
/* 0x0144 */ char unk_144[0x4];
/* 0x0148 */ EnHollActionFunc actionFunc;
/* 0x000 */ Actor actor;
/* 0x144 */ s8 type;
/* 0x145 */ u8 alpha;
/* 0x146 */ u8 playerSide;
/* 0x147 */ u8 bgCoverAlphaActive;
/* 0x148 */ EnHollActionFunc actionFunc;
} EnHoll; // size = 0x14C
// Horizontal
#define EN_HOLL_BOTTOM_DEFAULT -50.0f
#define EN_HOLL_BOTTOM_IKANA -90.0f
#define EN_HOLL_HALFWIDTH_DEFAULT 150.0f
#define EN_HOLL_HALFWIDTH_IKANA 280.0f
#define EN_HOLL_HALFWIDTH_TRANSPARENT 200.0f
#define EN_HOLL_TOP_DEFAULT 200.0f
#define EN_HOLL_TOP_PIRATE 280.0f
//! Transparent Halls: Being inside this plane enables the execution of more code within the actionFunc.
#define EN_HOLL_ACTIVATION_PLANE_DISTANCE 100.0f
//! Transparent Halls: Crossing this plane will change rooms/scenes.
#define EN_HOLL_LOADING_PLANE_DISTANCE 50.0f
// Vertical
#define EN_HOLL_RADIUS 120.0f
//! Holes: Being inside this plane enables the execution of more code within the actionFunc.
#define EN_HOLL_ACTIVATION_PLANE_DISTANCE_VERTICAL 200.0f
//! Holes: Crossing this plane will change rooms/scenes.
#define EN_HOLL_LOADING_PLANE_DISTANCE_VERTICAL 50.0f
#define EN_HOLL_GET_ID_AND(this) ((this->actor.params & 0xFFFF) >> 10)
#define EN_HOLL_GET_ID_CAST(this) ((u16) this->actor.params >> 10)
#define EN_HOLL_GET_TYPE(this) ((this->actor.params >> 7) & 0x7)
#define EN_HOLL_GET_EXIT_LIST_INDEX(this) (this->actor.params & 0x7F)
#define EN_HOLL_GET_Z_ACTOR_BITMASK_INDEX(this) (this->actor.params & 0x7)
#define EN_HOLL_IS_VISIBLE(this) ((this->type == EN_HOLL_TYPE_DEFAULT) || (this->type == EN_HOLL_TYPE_SCENE_CHANGER))
#define EN_HOLL_IS_SCENE_CHANGER(this) (this->type == EN_HOLL_TYPE_SCENE_CHANGER)
#define EN_HOLL_SCALE_ALPHA(playerDistFromCentralPlane) ((playerDistFromCentralPlane - sTransparencyPlaneDistance) * (255 / (sTranslucencyPlaneDistance - sTransparencyPlaneDistance)))
#define EN_HOLL_SCALE_BG_COVER_ALPHA(playerDistFromCentralPlane) ((EN_HOLL_ACTIVATION_PLANE_DISTANCE_VERTICAL - playerDistFromCentralPlane) * (255 / (EN_HOLL_ACTIVATION_PLANE_DISTANCE_VERTICAL - EN_HOLL_LOADING_PLANE_DISTANCE_VERTICAL)))
extern const ActorInit En_Holl_InitVars;
#endif // Z_EN_HOLL_H

View File

@ -91,6 +91,8 @@ def proper_name(symbol, in_data=False, is_symbol=True):
# hacks
if symbol == 0x809C46F0: # ovl_En_Encount4 fake symbol at the very end of the data section
return variables_ast[0x809C46DC][0] + " + 0x14"
elif symbol == 0x801EF66D: # z_message_nes constant-folding stray fairy array
return variables_ast[0x801EF670][0] + f" - 0x{0x801EF670 - 0x801EF66D:X}"
elif symbol == 0x80A09740: # boss_07 symbol with large addend folded into %lo
return variables_ast[0x80A09A60][0] + f" - 0x{0x80A09A60 - 0x80A09740:X}"
elif symbol == 0x80B80248: # bg_ikana_mirror symbol with large addend folded into %lo

View File

@ -5534,16 +5534,16 @@
0x80898E74:("func_80898E74",),
0x80899024:("func_80899024",),
0x80899218:("EnPeehat_Draw",),
0x80899960:("func_80899960",),
0x808999B0:("func_808999B0",),
0x80899960:("EnHoll_SetupAction",),
0x808999B0:("EnHoll_SetPlayerSide",),
0x80899A20:("EnHoll_Init",),
0x80899A78:("EnHoll_Destroy",),
0x80899ACC:("func_80899ACC",),
0x80899B88:("func_80899B88",),
0x80899F30:("func_80899F30",),
0x8089A0C0:("func_8089A0C0",),
0x8089A238:("func_8089A238",),
0x8089A330:("func_8089A330",),
0x80899ACC:("EnHoll_ChangeRooms",),
0x80899B88:("EnHoll_VisibleIdle",),
0x80899F30:("EnHoll_TransparentIdle",),
0x8089A0C0:("EnHoll_VerticalBgCoverIdle",),
0x8089A238:("EnHoll_VerticalIdle",),
0x8089A330:("EnHoll_RoomTransitionIdle",),
0x8089A3A0:("EnHoll_Update",),
0x8089A3FC:("EnHoll_Draw",),
0x8089A6E0:("EnDinofos_Init",),

View File

@ -6423,15 +6423,15 @@
0x80899650:("D_80899650","f32","",0x4),
0x80899654:("D_80899654","f32","",0x4),
0x8089A530:("En_Holl_InitVars","UNK_TYPE1","",0x1),
0x8089A550:("D_8089A550","UNK_TYPE1","",0x1),
0x8089A590:("D_8089A590","UNK_TYPE1","",0x1),
0x8089A5B8:("D_8089A5B8","UNK_TYPE4","",0x4),
0x8089A5BC:("D_8089A5BC","UNK_PTR","",0x4),
0x8089A5D0:("D_8089A5D0","UNK_TYPE1","",0x1),
0x8089A5DC:("D_8089A5DC","f32","",0x4),
0x8089A5E0:("D_8089A5E0","f32","",0x4),
0x8089A5E4:("D_8089A5E4","f32","",0x4),
0x8089A5E8:("D_8089A5E8","f32","",0x4),
0x8089A550:("gEnHollCentralPlaneVtx","UNK_TYPE1","",0x1),
0x8089A590:("gEnHollCentralPlaneDL","UNK_TYPE1","",0x1),
0x8089A5B8:("sInstancePlayingSound","UNK_TYPE4","",0x4),
0x8089A5BC:("sActionFuncs","UNK_PTR","",0x4),
0x8089A5D0:("sInitChain","UNK_TYPE1","",0x1),
0x8089A5DC:("sActivationPlaneDistance","f32","",0x4),
0x8089A5E0:("sLoadingPlaneDistance","f32","",0x4),
0x8089A5E4:("sTranslucencyPlaneDistance","f32","",0x4),
0x8089A5E8:("sTransparencyPlaneDistance","f32","",0x4),
0x8089A5F0:("D_8089A5F0","f32","",0x4),
0x8089A5F4:("D_8089A5F4","f32","",0x4),
0x8089E150:("En_Dinofos_InitVars","UNK_TYPE1","",0x1),