diff options
| author | Philip Dubé <159546+serprex@users.noreply.github.com> | 2026-08-09 22:01:31 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-09 22:01:31 +0000 |
| commit | f27ddede59d8134eccf8a106f62eaebeecc4ace5 (patch) | |
| tree | ba9a8d77ce0158d8ce2df17d360c2d3274ab08c6 | |
| parent | 4e39d06accfa65fbed9e034c3cd7face91a6d80c (diff) | |
Fix mirror decal not rendering on some walls (#7052)
| -rw-r--r-- | soh/soh/Enhancements/AlwaysOnFixes.cpp | 15 | ||||
| -rw-r--r-- | soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h | 8 | ||||
| -rw-r--r-- | soh/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c | 4 |
3 files changed, 26 insertions, 1 deletions
diff --git a/soh/soh/Enhancements/AlwaysOnFixes.cpp b/soh/soh/Enhancements/AlwaysOnFixes.cpp index 639330f68..66c270c22 100644 --- a/soh/soh/Enhancements/AlwaysOnFixes.cpp +++ b/soh/soh/Enhancements/AlwaysOnFixes.cpp @@ -8,6 +8,7 @@ extern "C" { #include "include/z64camera.h" #include "src/overlays/actors/ovl_En_Test/z_en_test.h" #include "src/overlays/actors/ovl_En_Horse/z_en_horse.h" +#include "src/overlays/actors/ovl_Mir_Ray/z_mir_ray.h" void UnregisterActorSkeletons(struct Actor* actor); extern void Player_UseItem(PlayState*, Player*, s32); extern PlayState* gPlayState; @@ -110,6 +111,20 @@ void RegisterAlwaysOnFixes() { } }); + // Mir_Ray draws the reflection image straight on the collision poly's plane, but CollisionPoly + // stores that plane quantized (s16 normal, integer dist), so for about half of all walls it + // lands a fraction of a unit inside the drawn surface. N64 RDP's decal mode handled that, + // but our graphics pipeline does not. Lift the image off the plane along the poly normal. + COND_VB_SHOULD(VB_MIRRAY_DRAW_REFLECTION, true, { + if (*should) { + MirRayShieldReflection* reflection = va_arg(args, MirRayShieldReflection*); + CollisionPoly* poly = reflection->reflectionPoly; + reflection->pos.x += COLPOLY_GET_NORMAL(poly->normal.x); + reflection->pos.y += COLPOLY_GET_NORMAL(poly->normal.y); + reflection->pos.z += COLPOLY_GET_NORMAL(poly->normal.z); + } + }); + // Handle first person aiming camera settings COND_VB_SHOULD(VB_CHANGE_AIMING_CAMERA, true, { s8* heldItemAction = va_arg(args, s8*); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index f0b91582c..e41669089 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -1642,6 +1642,14 @@ typedef enum { // #### `result` // ```c + // reflection[i].reflectionPoly != NULL + // ``` + // #### `args` + // - `*MirRayShieldReflection` + VB_MIRRAY_DRAW_REFLECTION, + + // #### `result` + // ```c // false // ``` // #### `args` diff --git a/soh/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c b/soh/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c index 334c1fdf6..ae1b130bd 100644 --- a/soh/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c +++ b/soh/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c @@ -7,6 +7,7 @@ #include "z_mir_ray.h" #include "objects/object_mir_ray/object_mir_ray.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED) @@ -510,7 +511,8 @@ void MirRay_Draw(Actor* thisx, PlayState* play) { } } for (i = 0; i < 6; i++) { - if (reflection[i].reflectionPoly != NULL) { + if (GameInteractor_Should(VB_MIRRAY_DRAW_REFLECTION, reflection[i].reflectionPoly != NULL, + &reflection[i])) { FrameInterpolation_RecordOpenChild(&reflection[i], i); Matrix_Translate(reflection[i].pos.x, reflection[i].pos.y, reflection[i].pos.z, MTXMODE_NEW); Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); |
