diff --git a/src/game/hud.c b/src/game/hud.c index 747cafc1c..40b604f52 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -67,20 +67,21 @@ static struct CameraHUD sCameraHUD = { CAM_STATUS_NONE }; static u32 sPowerMeterPrevTimestamp; static f32 sPowerMeterPrevY; -static Gfx *sPowerMeterDisplayListPos; +static Gfx *sPowerMeterDisplayListPos = NULL; +static Mtx *sPowerMeterMtx = NULL; void patch_hud_before(void) { if (sPowerMeterDisplayListPos != NULL) { sPowerMeterPrevY = sPowerMeterHUD.y; sPowerMeterPrevTimestamp = gGlobalTimer; sPowerMeterDisplayListPos = NULL; + sPowerMeterMtx = NULL; } } void patch_hud_interpolated(f32 delta) { - if (sPowerMeterDisplayListPos != NULL) { - Mtx *mtx = alloc_display_list(sizeof(Mtx)); - if (mtx == NULL) { return; } + if (sPowerMeterDisplayListPos && sPowerMeterMtx) { + Mtx* mtx = sPowerMeterMtx; f32 interpY = delta_interpolate_f32(sPowerMeterPrevY, (f32)sPowerMeterHUD.y, delta); guTranslate(mtx, (f32) sPowerMeterHUD.x, interpY, 0); gSPMatrix(sPowerMeterDisplayListPos, VIRTUAL_TO_PHYSICAL(mtx), @@ -148,6 +149,7 @@ void render_dl_power_meter(s16 numHealthWedges) { } guTranslate(mtx, (f32) sPowerMeterHUD.x, sPowerMeterPrevY, 0); + sPowerMeterMtx = mtx; sPowerMeterDisplayListPos = gDisplayListHead; gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(mtx++), diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 188dcc022..5ce8d55c4 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -266,14 +266,16 @@ void patch_mtx_interpolated(f32 delta) { struct GraphNodeObject* savedObj = gCurGraphNodeObject; for (s32 i = 0; i < sShadowInterpCount; i++) { struct ShadowInterp* interp = &sShadowInterp[i]; + if (!interp->gfx) { continue; } gShadowInterpCurrent = interp; Vec3f posInterp; delta_interpolate_vec3f(posInterp, interp->shadowPosPrev, interp->shadowPos, delta); gCurGraphNodeObject = interp->obj; extern u8 gInterpolatingSurfaces; gInterpolatingSurfaces = true; - create_shadow_below_xyz(posInterp[0], posInterp[1], posInterp[2], interp->shadowScale, interp->node->shadowSolidity, interp->node->shadowType); + gShadowInterpCurrent->gfx = create_shadow_below_xyz(posInterp[0], posInterp[1], posInterp[2], interp->shadowScale, interp->node->shadowSolidity, interp->node->shadowType); gInterpolatingSurfaces = false; + gShadowInterpCurrent = NULL; } gCurGraphNodeObject = savedObj; diff --git a/src/game/shadow.c b/src/game/shadow.c index 1099bd538..9ca153b73 100644 --- a/src/game/shadow.c +++ b/src/game/shadow.c @@ -914,7 +914,14 @@ Gfx *create_shadow_below_xyz(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 s s8 shadowType) { Gfx *displayList = NULL; struct Surface *pfloor; - find_floor(xPos, yPos, zPos, &pfloor); + f32 height = find_floor(xPos, yPos, zPos, &pfloor); + + // if we're interpolating and the shadow isn't valid, just give up + if (gRenderingInterpolated) { + if (height <= FLOOR_LOWER_LIMIT || pfloor == NULL) { + return gShadowInterpCurrent->gfx; + } + } gShadowAboveWaterOrLava = FALSE; gMarioOnIceOrCarpet = 0; diff --git a/src/pc/djui/djui.c b/src/pc/djui/djui.c index d73f01ca7..6a66a7c7f 100644 --- a/src/pc/djui/djui.c +++ b/src/pc/djui/djui.c @@ -80,6 +80,7 @@ void djui_lua_error(char* text) { void djui_render(void) { if (gDjuiDisabled) { return; } + sSavedDisplayListHead = gDisplayListHead; gDjuiHudUtilsZ = 0;