diff --git a/src/game/behaviors/bowser_puzzle_piece.inc.c b/src/game/behaviors/bowser_puzzle_piece.inc.c index a8573e4b9..cbdccf75f 100644 --- a/src/game/behaviors/bowser_puzzle_piece.inc.c +++ b/src/game/behaviors/bowser_puzzle_piece.inc.c @@ -259,13 +259,11 @@ void (*sBowserPuzzlePieceActions[])(void) = { }; void bhv_lll_bowser_puzzle_piece_loop(void) { - // make sure we're loaded and synchronized - if (!gNetworkAreaLoaded) { - o->oTimer = 0; - return; - } else if (o->oBowserPuzzlePieceTimer == 0 && (gNetworkAreaTimer - o->oBowserPuzzlePieceTimer) >= 650) { - o->oBowserPuzzlePieceTimer = ((gNetworkAreaTimer - o->oBowserPuzzlePieceTimer) / 650) * 650; - o->oTimer = 0; + u32 loopLength = 650; + if ((gNetworkAreaTimer - o->oBowserPuzzlePieceTimer) >= loopLength) { + u32 catchup = (gNetworkAreaTimer - o->oBowserPuzzlePieceTimer) / loopLength; + catchup *= loopLength; + o->oBowserPuzzlePieceTimer += catchup; } while (o->oBowserPuzzlePieceTimer < gNetworkAreaTimer) { diff --git a/src/game/behaviors/checkerboard_platform.inc.c b/src/game/behaviors/checkerboard_platform.inc.c index 342229d4f..832d1ba06 100644 --- a/src/game/behaviors/checkerboard_platform.inc.c +++ b/src/game/behaviors/checkerboard_platform.inc.c @@ -54,17 +54,11 @@ void bhv_checkerboard_platform_init(void) { } void bhv_checkerboard_platform_loop(void) { - // make sure we're loaded and synchronized - if (!gNetworkAreaLoaded) { - o->oTimer = 0; - o->oCheckerBoardPlatformTimer = 0; - return; - } else { - u32 loopLength = 132 + o->oCheckerBoardPlatformUnkFC * 2; - if (o->oCheckerBoardPlatformTimer == 0 && (gNetworkAreaTimer - o->oCheckerBoardPlatformTimer) >= loopLength) { - o->oTimer = 0; - o->oCheckerBoardPlatformTimer = ((gNetworkAreaTimer - o->oCheckerBoardPlatformTimer) / loopLength) * loopLength; - } + u32 loopLength = 132 + o->oCheckerBoardPlatformUnkFC * 2; + if ((gNetworkAreaTimer - o->oCheckerBoardPlatformTimer) >= loopLength) { + u32 catchup = (gNetworkAreaTimer - o->oCheckerBoardPlatformTimer) / loopLength; + catchup *= loopLength; + o->oCheckerBoardPlatformTimer += catchup; } if (o->oDistanceToMario < 1000.0f) diff --git a/src/game/behaviors/ddd_pole.inc.c b/src/game/behaviors/ddd_pole.inc.c index d8cf32fe7..0c8693d7d 100644 --- a/src/game/behaviors/ddd_pole.inc.c +++ b/src/game/behaviors/ddd_pole.inc.c @@ -10,18 +10,11 @@ void bhv_ddd_pole_init(void) { void bhv_ddd_pole_update(void) { - // make sure we're loaded and synchronized - if (!gNetworkAreaLoaded) { - o->oTimer = 0; - o->oDDDPoleTimer = 0; - return; - } else { - // catch up, jumping full loop cycles at a time - u16 loopTime = (((u16)o->oDDDPoleMaxOffset / 10) + 20) * 2; - if (o->oDDDPoleTimer == 0 && (gNetworkAreaTimer - o->oDDDPoleTimer) >= loopTime) { - o->oDDDPoleTimer = ((gNetworkAreaTimer - o->oDDDPoleTimer) / loopTime) * loopTime; - o->oTimer = 0; - } + u32 loopLength = (((u16)o->oDDDPoleMaxOffset / 10) + 20) * 2; + if ((gNetworkAreaTimer - o->oDDDPoleTimer) >= loopLength) { + u32 catchup = (gNetworkAreaTimer - o->oDDDPoleTimer) / loopLength; + catchup *= loopLength; + o->oDDDPoleTimer += catchup; } while (o->oDDDPoleTimer < gNetworkAreaTimer) { diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 37490593d..e4c15c3c1 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -31,7 +31,8 @@ struct NetworkSystem* gNetworkSystem = &gNetworkSystemSocket; u16 networkLoadingLevel = 0; bool gNetworkAreaLoaded = false; bool gNetworkAreaSyncing = true; -u32 gNetworkAreaTimer = 0; +u32 gNetworkAreaTimerClock = 0; +u32 gNetworkAreaTimer = 0; struct StringLinkedList gRegisteredMods = { 0 }; @@ -100,6 +101,7 @@ void network_on_init_area(void) { gNetworkAreaLoaded = false; gNetworkAreaSyncing = true; gNetworkAreaTimer = 0; + gNetworkAreaTimerClock = clock_elapsed_ticks(); } void network_on_loaded_area(void) { @@ -261,12 +263,10 @@ void network_update(void) { networkLoadingLevel++; if (!gNetworkAreaLoaded && networkLoadingLevel >= LOADING_LEVEL_THRESHOLD) { gNetworkAreaLoaded = true; - gNetworkAreaTimer = 0; network_on_loaded_area(); } - } else if (gNetworkAreaLoaded) { - gNetworkAreaTimer++; } + gNetworkAreaTimer = (clock_elapsed_ticks() - gNetworkAreaTimerClock); // send out update packets if (gNetworkType != NT_NONE && network_player_any_connected()) { diff --git a/src/pc/network/network.h b/src/pc/network/network.h index 258d91c5d..4f9bdd30c 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -85,6 +85,7 @@ extern enum NetworkType gNetworkType; extern bool gNetworkAreaLoaded; extern bool gNetworkAreaSyncing; extern u32 gNetworkAreaTimer; +extern u32 gNetworkAreaTimerClock; extern struct SyncObject gSyncObjects[]; extern struct ServerSettings gServerSettings; extern struct StringLinkedList gRegisteredMods; diff --git a/src/pc/network/packets/packet_area.c b/src/pc/network/packets/packet_area.c index 864373d2b..8647e6324 100644 --- a/src/pc/network/packets/packet_area.c +++ b/src/pc/network/packets/packet_area.c @@ -9,6 +9,7 @@ #include "object_constants.h" #include "object_fields.h" #include "model_ids.h" +#include "pc/utils/misc.h" //#define DISABLE_MODULE_LOG 1 #include "pc/debuglog.h" @@ -140,6 +141,7 @@ void network_receive_area(struct Packet* p) { // read area variables packet_read(p, &gNetworkAreaTimer, sizeof(u32)); + gNetworkAreaTimerClock = clock_elapsed_ticks() - gNetworkAreaTimer; // read removed sync ids area_remove_sync_ids_clear(); diff --git a/src/pc/utils/misc.c b/src/pc/utils/misc.c index 3d3cfca8d..fdfab5c78 100644 --- a/src/pc/utils/misc.c +++ b/src/pc/utils/misc.c @@ -23,16 +23,27 @@ void update_all_mario_stars(void) { } } -f32 clock_elapsed(void) { +static u64 clock_elapsed_ns(void) { static bool sClockInitialized = false; - static struct timespec clock_start; + static u64 clock_start_ns; if (!sClockInitialized) { + struct timespec clock_start; clock_gettime(CLOCK_MONOTONIC, &clock_start); + clock_start_ns = ((u64)clock_start.tv_sec) * 1000000000 + clock_start.tv_nsec; sClockInitialized = true; } struct timespec clock_current; clock_gettime(CLOCK_MONOTONIC, &clock_current); - return (clock_current.tv_sec - clock_start.tv_sec) - + ((clock_current.tv_nsec - clock_start.tv_nsec) / 1000000000.0f); + + u64 clock_current_ns = ((u64)clock_current.tv_sec) * 1000000000 + clock_current.tv_nsec; + return (clock_current_ns - clock_start_ns); +} + +f32 clock_elapsed(void) { + return (clock_elapsed_ns() / 1000000000.0f); +} + +u32 clock_elapsed_ticks(void) { + return (clock_elapsed_ns() * 3 / 100000000); } \ No newline at end of file diff --git a/src/pc/utils/misc.h b/src/pc/utils/misc.h index 04bfd82a1..765e03052 100644 --- a/src/pc/utils/misc.h +++ b/src/pc/utils/misc.h @@ -4,5 +4,6 @@ float smoothstep(float edge0, float edge1, float x); void update_all_mario_stars(void); f32 clock_elapsed(void); +u32 clock_elapsed_ticks(void); #endif \ No newline at end of file