summaryrefslogtreecommitdiff
path: root/soh/src/code
diff options
context:
space:
mode:
authorArchez <Archez@users.noreply.github.com>2024-08-13 20:18:41 -0400
committerGitHub <noreply@github.com>2024-08-13 20:18:41 -0400
commit86580fc79fd174a2dba29c18caf88a46d6bf8c05 (patch)
treef54e376533a8926010561fd1fe47384b8431ad41 /soh/src/code
parent73be4e55591f547df1a27884fdddbae36f603e07 (diff)
parent651348d2a94f6bfa5f7e7f89800908e9e8a4a3e5 (diff)
Merge pull request #4290 from Archez/macready-golf-merge
merge Macready Golf -> develop
Diffstat (limited to 'soh/src/code')
-rw-r--r--soh/src/code/z_actor.c122
-rw-r--r--soh/src/code/z_fcurve_data_skelanime.c4
-rw-r--r--soh/src/code/z_message_PAL.c2
-rw-r--r--soh/src/code/z_player_lib.c2
-rw-r--r--soh/src/code/z_skelanime.c20
5 files changed, 118 insertions, 32 deletions
diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c
index 9eac79559..289982318 100644
--- a/soh/src/code/z_actor.c
+++ b/soh/src/code/z_actor.c
@@ -1228,14 +1228,6 @@ void Actor_Init(Actor* actor, PlayState* play) {
actor->uncullZoneForward = 1000.0f;
actor->uncullZoneScale = 350.0f;
actor->uncullZoneDownward = 700.0f;
- if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 0) != 0 && actor->id != ACTOR_EN_TORCH2 && actor->id != ACTOR_EN_BLKOBJ // Extra check for Dark Link and his room
- && actor->id != ACTOR_EN_HORSE // Check for Epona, else if we call her she will spawn at the other side of the map + we can hear her during the title screen sequence
- && actor->id != ACTOR_EN_HORSE_GANON && actor->id != ACTOR_EN_HORSE_ZELDA // check for Zelda's and Ganondorf's horses that will always be scene during cinematic whith camera paning
- && (play->sceneNum != SCENE_DODONGOS_CAVERN && actor->id != ACTOR_EN_ZF)) { // Check for DC and Lizalfos for the case where the miniboss music would still play under certains conditions and changing room
- actor->uncullZoneForward = 32767.0f;
- actor->uncullZoneScale = 32767.0f;
- actor->uncullZoneDownward = 32767.0f;
- }
CollisionCheck_InitInfo(&actor->colChkInfo);
actor->floorBgId = BGCHECK_SCENE;
ActorShape_Init(&actor->shape, 0.0f, NULL, 0.0f);
@@ -2898,33 +2890,92 @@ s32 func_800314B0(PlayState* play, Actor* actor) {
s32 func_800314D4(PlayState* play, Actor* actor, Vec3f* arg2, f32 arg3) {
f32 var;
- if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 0) != 0 && actor->id != ACTOR_EN_TORCH2 && actor->id != ACTOR_EN_BLKOBJ // Extra check for Dark Link and his room
- && actor->id != ACTOR_EN_HORSE // Check for Epona, else if we call her she will spawn at the other side of the map + we can hear her during the title screen sequence
- && actor->id != ACTOR_EN_HORSE_GANON && actor->id != ACTOR_EN_HORSE_ZELDA // check for Zelda's and Ganondorf's horses that will always be scene during cinematic whith camera paning
- && (play->sceneNum != SCENE_DODONGOS_CAVERN && actor->id != ACTOR_EN_ZF)) { // Check for DC and Lizalfos for the case where the miniboss music would still play under certains conditions and changing room
+ if ((arg2->z > -actor->uncullZoneScale) && (arg2->z < (actor->uncullZoneForward + actor->uncullZoneScale))) {
+ var = (arg3 < 1.0f) ? 1.0f : 1.0f / arg3;
+
+ if ((((fabsf(arg2->x) - actor->uncullZoneScale) * var) < 1.0f) &&
+ (((arg2->y + actor->uncullZoneDownward) * var) > -1.0f) &&
+ (((arg2->y - actor->uncullZoneScale) * var) < 1.0f)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// #region SOH [Enhancements] Allows us to increase the draw and update distance independently,
+// mostly a modified version of the function above and additional tweaks for some specfic actors
+s32 Ship_CalcShouldDrawAndUpdate(PlayState* play, Actor* actor, Vec3f* projectedPos, f32 projectedW, bool* shouldDraw,
+ bool* shouldUpdate) {
+ f32 clampedProjectedW;
+
+ // Check if the actor passes its original/vanilla culling requirements
+ if (func_800314D4(play, actor, projectedPos, projectedW)) {
+ *shouldUpdate = true;
+ *shouldDraw = true;
return true;
}
- if ((arg2->z > -actor->uncullZoneScale) && (arg2->z < (actor->uncullZoneForward + actor->uncullZoneScale))) {
- var = (arg3 < 1.0f) ? 1.0f : 1.0f / arg3;
+ // Skip cutscne actors that depend on culling to hide from camera pans
+ if (actor->id == ACTOR_EN_VIEWER) {
+ return false;
+ }
- // #region SoH [Widescreen support]
- // Doors will cull quite noticeably on wider screens. For these actors the zone is increased
- f32 limit = 1.0f;
- if (((actor->id == ACTOR_EN_DOOR) || (actor->id == ACTOR_DOOR_SHUTTER)) && CVarGetInteger(CVAR_GENERAL("IncreaseDoorUncullZones"), 1)) {
- limit = 2.0f;
+ s32 multiplier = CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1);
+ multiplier = MAX(multiplier, 1);
+
+ // Some actors have a really short forward value, so we need to add to it before the multiplier to increase the
+ // final strength of the forward culling
+ f32 adder = (actor->uncullZoneForward < 500) ? 1000.0f : 0.0f;
+
+ if ((projectedPos->z > -actor->uncullZoneScale) &&
+ (projectedPos->z < (((actor->uncullZoneForward + adder) * multiplier) + actor->uncullZoneScale))) {
+ clampedProjectedW = (projectedW < 1.0f) ? 1.0f : 1.0f / projectedW;
+
+ f32 ratioAdjusted = 1.0f;
+
+ if (CVarGetInteger(CVAR_ENHANCEMENT("WidescreenActorCulling"), 0)) {
+ f32 originalAspectRatio = 4.0f / 3.0f;
+ f32 currentAspectRatio = OTRGetAspectRatio();
+ ratioAdjusted = MAX(currentAspectRatio / originalAspectRatio, 1.0f);
}
- if ((((fabsf(arg2->x) - actor->uncullZoneScale) * var) < limit) &&
- (((arg2->y + actor->uncullZoneDownward) * var) > -limit) &&
- (((arg2->y - actor->uncullZoneScale) * var) < limit)) {
+ if ((((fabsf(projectedPos->x) - actor->uncullZoneScale) * (clampedProjectedW / ratioAdjusted)) < 1.0f) &&
+ (((projectedPos->y + actor->uncullZoneDownward) * clampedProjectedW) > -1.0f) &&
+ (((projectedPos->y - actor->uncullZoneScale) * clampedProjectedW) < 1.0f)) {
+
+ if (CVarGetInteger(CVAR_ENHANCEMENT("ExtendedCullingExcludeGlitchActors"), 0)) {
+ // These actors are safe to draw without impacting glitches
+ if ((actor->id == ACTOR_OBJ_BOMBIWA || actor->id == ACTOR_OBJ_HAMISHI ||
+ actor->id == ACTOR_EN_ISHI) || // Boulders (hookshot through collision)
+ actor->id == ACTOR_EN_GS || // Gossip stones (text delay)
+ actor->id == ACTOR_EN_GE1 || // White gerudos (gate clip/archery room transition)
+ actor->id == ACTOR_EN_KZ || // King Zora (unfreeze glitch)
+ actor->id == ACTOR_EN_DU || // Darunia (Fire temple BK skip)
+ actor->id == ACTOR_DOOR_WARP1 // Blue warps (wrong warps)
+ ) {
+ *shouldDraw = true;
+ return true;
+ }
+
+ // Skip these actors entirely as their draw funcs impacts glitches
+ if ((actor->id == ACTOR_EN_SW &&
+ (((actor->params & 0xE000) >> 0xD) == 1 ||
+ ((actor->params & 0xE000) >> 0xD) == 2)) // Gold Skulltulas (hitbox at 0,0)
+ ) {
+ return false;
+ }
+ }
+
+ *shouldDraw = true;
+ *shouldUpdate = true;
return true;
}
- // #endregion
}
return false;
}
+// #endregion
void func_800315AC(PlayState* play, ActorContext* actorCtx) {
s32 invisibleActorCounter;
@@ -2961,18 +3012,35 @@ void func_800315AC(PlayState* play, ActorContext* actorCtx) {
}
}
+ // #region SOH [Enhancement] Extended culling updates
+ bool shipShouldDraw = false;
+ bool shipShouldUpdate = false;
if ((HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(70) == 0)) {
- if (func_800314B0(play, actor)) {
- actor->flags |= ACTOR_FLAG_ACTIVE;
+ if (CVarGetInteger(CVAR_ENHANCEMENT("DisableDrawDistance"), 1) > 1 ||
+ CVarGetInteger(CVAR_ENHANCEMENT("WidescreenActorCulling"), 0)) {
+ Ship_CalcShouldDrawAndUpdate(play, actor, &actor->projectedPos, actor->projectedW, &shipShouldDraw,
+ &shipShouldUpdate);
+
+ if (shipShouldUpdate) {
+ actor->flags |= ACTOR_FLAG_ACTIVE;
+ } else {
+ actor->flags &= ~ACTOR_FLAG_ACTIVE;
+ }
} else {
- actor->flags &= ~ACTOR_FLAG_ACTIVE;
+ if (func_800314B0(play, actor)) {
+ actor->flags |= ACTOR_FLAG_ACTIVE;
+ } else {
+ actor->flags &= ~ACTOR_FLAG_ACTIVE;
+ }
}
}
actor->isDrawn = false;
if ((HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(71) == 0)) {
- if ((actor->init == NULL) && (actor->draw != NULL) && (actor->flags & (ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_ACTIVE))) {
+ if ((actor->init == NULL) && (actor->draw != NULL) &&
+ ((actor->flags & (ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_ACTIVE)) || shipShouldDraw)) {
+ // #endregion
if ((actor->flags & ACTOR_FLAG_LENS) &&
((play->roomCtx.curRoom.lensMode == LENS_MODE_HIDE_ACTORS) ||
play->actorCtx.lensActive || (actor->room != play->roomCtx.curRoom.num))) {
diff --git a/soh/src/code/z_fcurve_data_skelanime.c b/soh/src/code/z_fcurve_data_skelanime.c
index 91b6dc90c..c75450be2 100644
--- a/soh/src/code/z_fcurve_data_skelanime.c
+++ b/soh/src/code/z_fcurve_data_skelanime.c
@@ -131,10 +131,6 @@ void SkelCurve_DrawLimb(PlayState* play, s32 limbIndex, SkelAnimeCurve* skelCurv
Matrix_TranslateRotateZYX(&pos, &rot);
Matrix_Scale(scale.x, scale.y, scale.z, MTXMODE_APPLY);
- if (CVarGetInteger(CVAR_ENHANCEMENT("DisableLOD"), 0)) {
- lod = 0;
- }
-
if (lod == 0) {
s32 pad1;
diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c
index c6b1415f6..0495df1dd 100644
--- a/soh/src/code/z_message_PAL.c
+++ b/soh/src/code/z_message_PAL.c
@@ -1116,7 +1116,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
}
}
if (msgCtx->textDelayTimer == 0) {
- msgCtx->textDrawPos = i + CVarGetInteger(CVAR_ENHANCEMENT("TextSpeed"), 2);
+ msgCtx->textDrawPos = i + CVarGetInteger(CVAR_ENHANCEMENT("TextSpeed"), 1);
msgCtx->textDelayTimer = msgCtx->textDelay;
} else {
msgCtx->textDelayTimer--;
diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c
index 4b790122f..b5128740c 100644
--- a/soh/src/code/z_player_lib.c
+++ b/soh/src/code/z_player_lib.c
@@ -2415,10 +2415,12 @@ void Player_DrawPause(PlayState* play, u8* segment, SkelAnime* skelAnime, Vec3f*
}
srcTable = ResourceMgr_LoadArrayByNameAsVec3s(srcTable);
+ Vec3s* ogSrcTable = srcTable;
destTable = skelAnime->jointTable;
for (i = 0; i < skelAnime->limbCount; i++) {
*destTable++ = *srcTable++;
}
+ free(ogSrcTable);
}
Player_DrawPauseImpl(play, segment + 0x3800, segment + 0x8800, skelAnime, pos, rot, scale, sword, tunic, shield,
diff --git a/soh/src/code/z_skelanime.c b/soh/src/code/z_skelanime.c
index 3df8a26a5..0bcf39236 100644
--- a/soh/src/code/z_skelanime.c
+++ b/soh/src/code/z_skelanime.c
@@ -148,6 +148,8 @@ void SkelAnime_DrawFlexLimbLod(PlayState* play, s32 limbIndex, void** skeleton,
newDList = limbDList = limb->dLists[lod];
+ play->flexLimbOverrideMTX = mtx;
+
if ((overrideLimbDraw == NULL) || !overrideLimbDraw(play, limbIndex, &newDList, &pos, &rot, arg)) {
Matrix_TranslateRotateZYX(&pos, &rot);
if (newDList != NULL) {
@@ -220,6 +222,8 @@ void SkelAnime_DrawFlexLod(PlayState* play, void** skeleton, Vec3s* jointTable,
newDList = limbDList = rootLimb->dLists[lod];
+ play->flexLimbOverrideMTX = &mtx;
+
if ((overrideLimbDraw == 0) || !overrideLimbDraw(play, 1, &newDList, &pos, &rot, arg)) {
Matrix_TranslateRotateZYX(&pos, &rot);
if (newDList != NULL) {
@@ -306,6 +310,20 @@ void SkelAnime_DrawSkeletonOpa(PlayState* play, SkelAnime* skelAnime, OverrideLi
}
}
+Gfx* SkelAnime_DrawSkeleton2(PlayState* play, SkelAnime* skelAnime, OverrideLimbDrawOpa overrideLimbDraw,
+ PostLimbDrawOpa postLimbDraw, void* arg, Gfx* gfx)
+{
+ if (skelAnime->skeletonHeader->skeletonType == SKELANIME_TYPE_NORMAL) {
+ return SkelAnime_Draw(play, skelAnime->skeleton, skelAnime->jointTable, overrideLimbDraw, postLimbDraw, arg, gfx);
+ } else if (skelAnime->skeletonHeader->skeletonType == SKELANIME_TYPE_FLEX) {
+ FlexSkeletonHeader* flexHeader = (FlexSkeletonHeader*)skelAnime->skeletonHeader;
+ return SkelAnime_DrawFlex(play, skelAnime->skeleton, skelAnime->jointTable, flexHeader->dListCount,
+ overrideLimbDraw, postLimbDraw, arg, gfx);
+ }
+
+ return gfx;
+}
+
/**
* Draw all limbs of type `StandardLimb` in a given skeleton to the polyOpa buffer
*/
@@ -383,6 +401,8 @@ void SkelAnime_DrawFlexLimbOpa(PlayState* play, s32 limbIndex, void** skeleton,
newDList = limbDList = limb->dList;
+ play->flexLimbOverrideMTX = limbMatricies;
+
if ((overrideLimbDraw == NULL) || !overrideLimbDraw(play, limbIndex, &newDList, &pos, &rot, arg)) {
Matrix_TranslateRotateZYX(&pos, &rot);
if (newDList != NULL) {