summaryrefslogtreecommitdiff
path: root/mm/src/code
diff options
context:
space:
mode:
authorGarrett Cox <garrettjcox@gmail.com>2024-06-02 23:15:33 -0500
committerGitHub <noreply@github.com>2024-06-02 23:15:33 -0500
commitf8f00e6d9baf08dda5ac2e0ab5ae8ff33fc3e97f (patch)
treee66941b54ceda81c359555d965532fd01658272c /mm/src/code
parent2d8bc175fef010cff5faba1c21e2dffa3643e624 (diff)
Add draw distance enhancements for actors and scene geometry (#539)
Diffstat (limited to 'mm/src/code')
-rw-r--r--mm/src/code/z_actor.c63
-rw-r--r--mm/src/code/z_play.c10
2 files changed, 69 insertions, 4 deletions
diff --git a/mm/src/code/z_actor.c b/mm/src/code/z_actor.c
index 532bb599f..2a967694b 100644
--- a/mm/src/code/z_actor.c
+++ b/mm/src/code/z_actor.c
@@ -3070,6 +3070,45 @@ s32 func_800BA2FC(PlayState* play, Actor* actor, Vec3f* projectedPos, f32 projec
return false;
}
+// #region 2S2H [Enhancements] Allows us to increase the draw and update distance independently, mostly a modified
+// version of the function above
+void Ship_CalcShouldDrawAndUpdate(PlayState* play, Actor* actor, Vec3f* projectedPos, f32 projectedW, bool* shouldDraw,
+ bool* shouldUpdate) {
+ s32 updateMulti = CVarGetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", 1);
+ s32 drawMulti = CVarGetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", 1);
+ bool updateCheck =
+ (-(actor->uncullZoneScale * updateMulti) < projectedPos->z) &&
+ (projectedPos->z < ((actor->uncullZoneForward * updateMulti) + (actor->uncullZoneScale * updateMulti)));
+ bool drawCheck =
+ (-(actor->uncullZoneScale * drawMulti) < projectedPos->z) &&
+ (projectedPos->z < ((actor->uncullZoneForward * drawMulti) + (actor->uncullZoneScale * drawMulti)));
+
+ if (updateCheck || drawCheck) {
+ f32 phi_f12;
+ f32 phi_f2 = CLAMP_MIN(projectedW, 1.0f);
+ f32 phi_f14;
+ f32 phi_f16;
+
+ if (play->view.fovy != 60.0f) {
+ phi_f12 = actor->uncullZoneScale * play->projectionMtxFDiagonal.x * 0.76980036f; // sqrt(16/27)
+
+ phi_f14 = play->projectionMtxFDiagonal.y * 0.57735026f; // 1 / sqrt(3)
+ phi_f16 = actor->uncullZoneScale * phi_f14;
+ phi_f14 *= actor->uncullZoneDownward;
+ } else {
+ phi_f16 = phi_f12 = actor->uncullZoneScale;
+ phi_f14 = actor->uncullZoneDownward;
+ }
+
+ if (((fabsf(projectedPos->x) - phi_f12) < phi_f2) && ((-phi_f2 < (projectedPos->y + phi_f14))) &&
+ ((projectedPos->y - phi_f16) < phi_f2)) {
+ *shouldDraw = drawCheck;
+ *shouldUpdate = updateCheck;
+ }
+ }
+}
+// #endregion
+
void Actor_DrawAll(PlayState* play, ActorContext* actorCtx) {
s32 pad[2];
Gfx* ref2;
@@ -3105,14 +3144,30 @@ void Actor_DrawAll(PlayState* play, ActorContext* actorCtx) {
Actor_UpdateFlaggedAudio(actor);
}
- if (func_800BA2D8(play, actor)) {
- actor->flags |= ACTOR_FLAG_40;
+ // #region 2S2H
+ bool shipShouldDraw = false;
+ bool shipShouldUpdate = false;
+ if (CVarGetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", 1) > 1 ||
+ CVarGetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", 1) > 1) {
+ Ship_CalcShouldDrawAndUpdate(play, actor, &actor->projectedPos, actor->projectedW, &shipShouldDraw,
+ &shipShouldUpdate);
+
+ if (shipShouldUpdate) {
+ actor->flags |= ACTOR_FLAG_40;
+ } else {
+ actor->flags &= ~ACTOR_FLAG_40;
+ }
} else {
- actor->flags &= ~ACTOR_FLAG_40;
+ if (func_800BA2D8(play, actor)) {
+ actor->flags |= ACTOR_FLAG_40;
+ } else {
+ actor->flags &= ~ACTOR_FLAG_40;
+ }
}
actor->isDrawn = false;
- if ((actor->init == NULL) && (actor->draw != NULL) && (actor->flags & actorFlags)) {
+ if ((actor->init == NULL) && (actor->draw != NULL) && ((actor->flags & actorFlags) || shipShouldDraw)) {
+ // #endregion
if ((actor->flags & ACTOR_FLAG_REACT_TO_LENS) &&
((play->roomCtx.curRoom.lensMode == LENS_MODE_HIDE_ACTORS) ||
(play->actorCtx.lensMaskSize == LENS_MASK_ACTIVE_SIZE) ||
diff --git a/mm/src/code/z_play.c b/mm/src/code/z_play.c
index a939ed217..a4fd7e5b5 100644
--- a/mm/src/code/z_play.c
+++ b/mm/src/code/z_play.c
@@ -1373,11 +1373,21 @@ void Play_DrawMain(PlayState* this) {
if (1) {
u32 roomDrawFlags = ((1) ? 1 : 0) | (((void)0, 1) ? 2 : 0); // FAKE:
+ if (CVarGetInteger("gEnhancements.Graphics.DisableSceneGeometryDistanceCheck", 0)) {
+ gSPSetExtraGeometryMode(POLY_OPA_DISP++, G_EX_ALWAYS_EXECUTE_BRANCH);
+ gSPSetExtraGeometryMode(POLY_XLU_DISP++, G_EX_ALWAYS_EXECUTE_BRANCH);
+ }
+
Scene_Draw(this);
if (this->roomCtx.unk78) {
Room_Draw(this, &this->roomCtx.curRoom, roomDrawFlags & 3);
Room_Draw(this, &this->roomCtx.prevRoom, roomDrawFlags & 3);
}
+
+ if (CVarGetInteger("gEnhancements.Graphics.DisableSceneGeometryDistanceCheck", 0)) {
+ gSPClearExtraGeometryMode(POLY_OPA_DISP++, G_EX_ALWAYS_EXECUTE_BRANCH);
+ gSPClearExtraGeometryMode(POLY_XLU_DISP++, G_EX_ALWAYS_EXECUTE_BRANCH);
+ }
}
if (this->skyboxCtx.skyboxShouldDraw) {