diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index 4316e04..c13a5fc 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -11,6 +11,7 @@ #include "game/obj_behaviors_2.h" #include "game/object_helpers.h" #include "game/object_list_processor.h" +#include "game/level_update.h" // Frameskip #include "graph_node.h" #include "surface_collision.h" @@ -919,6 +920,14 @@ void cur_obj_update(void) { f32 distanceFromMario; BhvCommandProc bhvCmdProc; s32 bhvProcResult; +#ifdef TARGET_N64 + s32 hasAnimation = (gCurrentObject->header.gfx.node.flags & GRAPH_RENDER_HAS_ANIMATION) != 0; + // frameskip + if ((doneSkipped >= 0) && hasAnimation && gCurrentObject->header.gfx.animInfo.curAnim != NULL) { + gCurrentObject->header.gfx.animInfo.animFrame = geo_update_animation_frame( + &gCurrentObject->header.gfx.animInfo, &gCurrentObject->header.gfx.animInfo.animFrameAccelAssist); + } +#endif // Calculate the distance from the object to Mario. if (objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) { @@ -1014,4 +1023,12 @@ void cur_obj_update(void) { } } } + +#ifdef TARGET_N64 + // frameskip + if (gCurrentObject->header.gfx.animInfo.animFrame < 0) { + gCurrentObject->header.gfx.animInfo.animFrame = 0; + } +#endif + } diff --git a/src/game/level_update.c b/src/game/level_update.c index 8f28b73..fe837a2 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -213,6 +213,14 @@ s8 sWarpCheckpointActive = FALSE; u8 unused2[4]; u8 unused3[2]; +#ifdef TARGET_N64 +// Frameskip +u64 deltaTime = 0; +u64 newTime = 0; +u64 oldTime = 0; +s8 doneSkipped; +#endif + u16 level_control_timer(s32 timerOp) { switch (timerOp) { case TIMER_CONTROL_SHOW: @@ -1008,6 +1016,31 @@ void basic_update(UNUSED s16 *arg) { } } +#ifdef TARGET_N64 +void delta_time_handle(void) { + OSTime newTime = osGetTime(); + + doneSkipped = -1; + deltaTime += newTime - oldTime; + oldTime = newTime; + while (deltaTime > 1562744) { + deltaTime -= 1562744; + if (sTimerRunning && gHudDisplay.timer < 17999) { + gHudDisplay.timer += 1; + } + area_update_objects(); + doneSkipped++; + } +} +#endif + +static void delta_time_reset(void) { +#ifdef TARGET_N64 + deltaTime = 0; + oldTime = osGetTime(); +#endif +} + s32 play_mode_normal(void) { if (gCurrDemoInput != NULL) { print_intro_text(); @@ -1023,11 +1056,19 @@ s32 play_mode_normal(void) { warp_area(); check_instant_warp(); +// Only N64 - shouldn't be necessary in pc-port +#ifdef TARGET_N64 + delta_time_handle(); +#else if (sTimerRunning && gHudDisplay.timer < 17999) { gHudDisplay.timer++; } area_update_objects(); + // put fast64's scroll_textures() function here for pc-port + // scroll_textures(); +#endif + update_hud_values(); if (gCurrentArea != NULL) { @@ -1207,15 +1248,19 @@ s32 update_level(void) { break; case PLAY_MODE_PAUSED: changeLevel = play_mode_paused(); + delta_time_reset(); break; case PLAY_MODE_CHANGE_AREA: changeLevel = play_mode_change_area(); + delta_time_reset(); break; case PLAY_MODE_CHANGE_LEVEL: changeLevel = play_mode_change_level(); + delta_time_reset(); break; case PLAY_MODE_FRAME_ADVANCE: changeLevel = play_mode_frame_advance(); + delta_time_reset(); break; #if QOL_FIX_UNUSED_PLAY_MODE default: @@ -1320,6 +1365,7 @@ s32 lvl_init_or_update(s16 initOrUpdate, UNUSED s32 unused) { switch (initOrUpdate) { case 0: result = init_level(); + delta_time_reset(); break; case 1: result = update_level(); diff --git a/src/game/level_update.h b/src/game/level_update.h index 2ca79e1..05c54c3 100644 --- a/src/game/level_update.h +++ b/src/game/level_update.h @@ -71,6 +71,11 @@ extern s16 sTransitionTimer; extern void (*sTransitionUpdate)(s16 *); extern u8 unused2[4]; +#ifdef TARGET_N64 +// Frameskip +extern s8 doneSkipped; +#endif + struct WarpDest { u8 type; u8 levelNum; diff --git a/src/game/mario.c b/src/game/mario.c index fd3a4b5..7daa056 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1405,6 +1405,12 @@ void update_mario_inputs(struct MarioState *m) { m->collidedObjInteractTypes = m->marioObj->collidedObjInteractTypes; m->flags &= 0xFFFFFF; +#ifdef TARGET_N64 + if (doneSkipped >= 0) { + m->controller->buttonPressed = 0; + } +#endif + update_mario_button_inputs(m); update_mario_joystick_inputs(m); update_mario_geometry_inputs(m);