diff --git a/src/game/camera.c b/src/game/camera.c index 6733169c..3ce4641c 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -497,6 +497,9 @@ extern u8 sZoomOutAreaMasks[]; static void skip_camera_interpolation(void) { gLakituState.skipCameraInterpolationTimestamp = gGlobalTimer; + extern s32 gCamSkipInterp; + gCamSkipInterp = 1; + } /** diff --git a/src/game/level_update.c b/src/game/level_update.c index 3de10f8a..c9ef1459 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -637,6 +637,7 @@ void check_instant_warp(void) { //vec3f_mul(gMarioStates[0].vel, -0.8f); return; } + mario_drop_held_object(&gMarioStates[0]); u8 changeOfArea = (gCurrAreaIndex != warp->area); gMarioStates[0].pos[0] += warp->displacement[0]; diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 861dd70c..9a4295fa 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -55,6 +55,9 @@ Mat4 gMatStackPrev[MATRIX_STACK_SIZE] = {}; Mtx *gMatStackFixed[MATRIX_STACK_SIZE] = { 0 }; Mtx *gMatStackPrevFixed[MATRIX_STACK_SIZE] = { 0 }; +s32 gCamSkipInterp = 0; +Vec3f gCamSkipInterpDisplacement = { 0 }; + u8 sUsingCamSpace = FALSE; Mtx sPrevCamTranf, sCurrCamTranf = { .m = { @@ -227,6 +230,9 @@ void patch_mtx_interpolated(f32 delta) { Mtx camTranfInv, prevCamTranfInv; if (sPerspectiveNode != NULL) { + if (gCamSkipInterp) { + sPerspectiveNode->prevFov = sPerspectiveNode->fov; + } u16 perspNorm; f32 fovInterpolated = delta_interpolate_f32(sPerspectiveNode->prevFov, sPerspectiveNode->fov, delta); f32 near = MIN(sPerspectiveNode->near, gProjectionMaxNearValue); @@ -320,6 +326,7 @@ void patch_mtx_interpolated(f32 delta) { G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH); } + gCamSkipInterp = 0; } /** @@ -556,6 +563,18 @@ static void geo_process_camera(struct GraphNodeCamera *node) { mtxf_lookat(cameraTransform, node->pos, node->focus, node->roll); mtxf_mul(gMatStack[gMatStackIndex + 1], cameraTransform, gMatStack[gMatStackIndex]); + if (gCamSkipInterp) { + // apply prevpos camera offset + vec3f_copy(node->prevPos, node->pos); + vec3f_add(node->prevPos, gCamSkipInterpDisplacement); + vec3f_copy(node->prevFocus, node->focus); + vec3f_add(node->prevFocus, gCamSkipInterpDisplacement); + } + + // save prevpos camera offset + vec3f_copy(gCamSkipInterpDisplacement, node->prevPos); + vec3f_sub(gCamSkipInterpDisplacement, node->pos); + if (gGlobalTimer == node->prevTimestamp + 1 && gGlobalTimer != gLakituState.skipCameraInterpolationTimestamp) { mtxf_lookat(cameraTransform, node->prevPos, node->prevFocus, node->roll); mtxf_mul(gMatStackPrev[gMatStackIndex + 1], cameraTransform, gMatStackPrev[gMatStackIndex]);