Skip to content

Commit

Permalink
Add draw distance enhancements for actors and scene geometry (Harbour…
Browse files Browse the repository at this point in the history
  • Loading branch information
garrettjoecox authored Jun 3, 2024
1 parent 2d8bc17 commit f8f00e6
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 4 deletions.
31 changes: 31 additions & 0 deletions mm/2s2h/BenGui/BenMenuBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,37 @@ void DrawEnhancementsMenu() {
"minor visual glitches that were covered up by the black bars\nPlease disable this "
"setting before reporting a bug" });

ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 255, 0, 255));
ImGui::SeparatorText("Unstable");
ImGui::PopStyleColor();
UIWidgets::CVarCheckbox(
"Disable Scene Geometry Distance Check", "gEnhancements.Graphics.DisableSceneGeometryDistanceCheck",
{ .tooltip =
"Disables the distance check for scene geometry, allowing it to be drawn no matter how far "
"away it is from the player. This may have unintended side effects." });
// BENTODO: Not implemented yet
// UIWidgets::CVarCheckbox("Widescreen Actor Culling",
// "gEnhancements.Graphics.ActorCullingAccountsForWidescreen",
// { .tooltip = "Adjusts the culling planes to account for widescreen resolutions. "
// "This may have unintended side effects." });
if (UIWidgets::CVarSliderInt(
"Increase Actor Draw Distance: %dx", "gEnhancements.Graphics.IncreaseActorDrawDistance", 1, 5, 1,
{ .tooltip =
"Increase the range in which Actors are drawn. This may have unintended side effects." })) {
CVarSetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance",
MIN(CVarGetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", 1),
CVarGetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", 1)));
}
if (UIWidgets::CVarSliderInt(
"Increase Actor Update Distance: %dx", "gEnhancements.Graphics.IncreaseActorUpdateDistance", 1, 5,
1,
{ .tooltip =
"Increase the range in which Actors are updated. This may have unintended side effects." })) {
CVarSetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance",
MAX(CVarGetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", 1),
CVarGetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", 1)));
}

ImGui::EndMenu();
}

Expand Down
1 change: 1 addition & 0 deletions mm/include/PR/gbi.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@
* G_EXTRAGEOMETRY flags: set extra custom geometry modes
*/
#define G_EX_INVERT_CULLING 0x00000001
#define G_EX_ALWAYS_EXECUTE_BRANCH 0x00000002

/* Need these defined for Sprite Microcode */
#ifdef _LANGUAGE_ASSEMBLY
Expand Down
63 changes: 59 additions & 4 deletions mm/src/code/z_actor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) ||
Expand Down
10 changes: 10 additions & 0 deletions mm/src/code/z_play.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit f8f00e6

Please sign in to comment.