From cb05b707f0f0ada8688a33ca9588ff5cb1024291 Mon Sep 17 00:00:00 2001 From: jacob Date: Wed, 19 Feb 2025 13:49:07 -0600 Subject: [PATCH] store publish dt in snapshot --- src/config.h | 6 ++-- src/sim_snapshot.h | 6 ++-- src/user.c | 79 +++++++++++++++++++++------------------------- 3 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/config.h b/src/config.h index 3e3021cc..20af8650 100644 --- a/src/config.h +++ b/src/config.h @@ -33,7 +33,7 @@ #define SPACE_CELL_BUCKETS_SQRT (256) #define SPACE_CELL_SIZE 1.0f -#define SIM_TICKS_PER_SECOND 50 +#define SIM_TICKS_PER_SECOND 100 #define SIM_TIMESCALE 1 #define SIM_PHYSICS_SUBSTEPS 4 @@ -52,7 +52,7 @@ /* How many ticks back in time should the user blend between? * = * - * E.g: At 1.5, the user thread will render 75ms back in time (if sim thread runs at 50 TPS) + * E.g: At 1.5, the user thread will render 75ms back in time if the sim runs at 50tps */ #define USER_INTERP_RATIO 1.5 #define USER_INTERP_ENABLED 1 @@ -73,4 +73,4 @@ #define AUDIO_ENABLED 0 #define VSYNC_ENABLED 0 -#define USER_FRAME_LIMIT 300 +#define USER_FPS_LIMIT 300 diff --git a/src/sim_snapshot.h b/src/sim_snapshot.h index 742cd50d..0c91ed5d 100644 --- a/src/sim_snapshot.h +++ b/src/sim_snapshot.h @@ -42,9 +42,11 @@ struct sim_snapshot { struct arena arena; - i64 published_at_ns; + /* Time of local snapshot publish to user */ + i64 publish_dt_ns; + i64 publish_time_ns; - /* Real time (increases with clock assuming no lag) */ + /* Real time (guaranteed to increase by real_dt_ns each sim step) */ i64 real_dt_ns; i64 real_time_ns; diff --git a/src/user.c b/src/user.c index d4f63f29..bf856d53 100644 --- a/src/user.c +++ b/src/user.c @@ -98,9 +98,9 @@ GLOBAL struct { struct sim_snapshot_store *local_sim_ss_store; /* Rolling window of local sim publish times */ - i64 snapshot_publish_times_ns[50]; - i64 snapshot_publish_times_index; i64 last_snapshot_published_at_ns; + i64 snapshot_publish_dts_ns[50]; + i64 snapshot_publish_dts_index; i64 average_snapshot_publish_dt_ns; /* Calculated from */ @@ -419,10 +419,10 @@ INTERNAL void user_update(void) #if 0 G.last_snapshot_received_at_ns = G.real_time_ns; #else - G.last_snapshot_published_at_ns = src->published_at_ns; - G.snapshot_publish_times_ns[G.snapshot_publish_times_index++] = src->published_at_ns; - if (G.snapshot_publish_times_index >= (i64)ARRAY_COUNT(G.snapshot_publish_times_ns)) { - G.snapshot_publish_times_index = 0; + G.last_snapshot_published_at_ns = src->publish_time_ns; + G.snapshot_publish_dts_ns[G.snapshot_publish_dts_index++] = src->publish_dt_ns; + if (G.snapshot_publish_dts_index >= (i64)ARRAY_COUNT(G.snapshot_publish_dts_ns)) { + G.snapshot_publish_dts_index = 0; } #endif } @@ -437,28 +437,13 @@ INTERNAL void user_update(void) i64 average_publish_dt_ns = 0; { i64 num_dts = 0; - for (i64 offset = 0; offset < (i64)ARRAY_COUNT(G.snapshot_publish_times_ns); ++offset) { - i64 t0_index = G.snapshot_publish_times_index + offset - 1; - if (t0_index < 0) { - t0_index += ARRAY_COUNT(G.snapshot_publish_times_ns); - } else if (t0_index >= (i64)ARRAY_COUNT(G.snapshot_publish_times_ns)) { - t0_index -= ARRAY_COUNT(G.snapshot_publish_times_ns); - } - - i64 t1_index = G.snapshot_publish_times_index + offset; - if (t1_index < 0) { - t1_index += ARRAY_COUNT(G.snapshot_publish_times_ns); - } else if (t1_index >= (i64)ARRAY_COUNT(G.snapshot_publish_times_ns)) { - t1_index -= ARRAY_COUNT(G.snapshot_publish_times_ns); - } - - i64 t0 = G.snapshot_publish_times_ns[t0_index]; - i64 t1 = G.snapshot_publish_times_ns[t1_index]; - - if (t0 != 0 && t1 != 0 && t1 > t0) { - i64 dt = t1 - t0; - average_publish_dt_ns += dt; + for (u64 i = 0; i < ARRAY_COUNT(G.snapshot_publish_dts_ns); ++i) { + i64 dt_ns = G.snapshot_publish_dts_ns[i]; + if (dt_ns != 0) { + average_publish_dt_ns += dt_ns; ++num_dts; + } else { + break; } } if (num_dts > 0) { @@ -534,7 +519,7 @@ INTERNAL void user_update(void) } #else /* Interp disabled, just copy latest snapshot */ - G.render_time_target_ns = G.local_sim_predicted_time_ns; + G.render_time_target_ns = newest_snapshot->real_time_ns; G.render_time_ns = newest_snapshot->real_time_ns; if (G.ss_blended->tick != newest_snapshot->tick) { if (G.ss_blended->valid) { @@ -606,10 +591,10 @@ INTERNAL void user_update(void) b32 pressed = event->kind == SYS_EVENT_KIND_BUTTON_DOWN; #if 0 b32 out_of_bounds = button >= SYS_BTN_M1 && button <= SYS_BTN_M5 && - (G.ui_cursor.x < 0 || - G.ui_cursor.y < 0 || - G.ui_cursor.x > G.ui_size.x || - G.ui_cursor.y > G.ui_size.y); + (G.ui_cursor.x < 0 || + G.ui_cursor.y < 0 || + G.ui_cursor.x > G.ui_size.x || + G.ui_cursor.y > G.ui_size.y); #else b32 out_of_bounds = false; #endif @@ -1206,10 +1191,10 @@ INTERNAL void user_update(void) "e1 rot: %F\n" ); struct string text = string_format(temp.arena, fmt, - FMT_FLOAT_P(e0_xf.og.x, 24), FMT_FLOAT_P(e0_xf.og.y, 24), - FMT_FLOAT_P(xform_get_rotation(e0_xf), 24), - FMT_FLOAT_P(e1_xf.og.x, 24), FMT_FLOAT_P(e1_xf.og.y, 24), - FMT_FLOAT_P(xform_get_rotation(e1_xf), 24)); + FMT_FLOAT_P(e0_xf.og.x, 24), FMT_FLOAT_P(e0_xf.og.y, 24), + FMT_FLOAT_P(xform_get_rotation(e0_xf), 24), + FMT_FLOAT_P(e1_xf.og.x, 24), FMT_FLOAT_P(e1_xf.og.y, 24), + FMT_FLOAT_P(xform_get_rotation(e1_xf), 24)); draw_text(G.ui_cmd_buffer, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_ui_xf, V2(0, 0))), V2(0, offset_px)), text); @@ -1383,19 +1368,23 @@ INTERNAL void user_update(void) switch (bind) { /* Movement */ - case USER_BIND_KIND_MOVE_UP: { + case USER_BIND_KIND_MOVE_UP: + { input_move_dir.y -= 1; } break; - case USER_BIND_KIND_MOVE_DOWN: { + case USER_BIND_KIND_MOVE_DOWN: + { input_move_dir.y += 1; } break; - case USER_BIND_KIND_MOVE_LEFT: { + case USER_BIND_KIND_MOVE_LEFT: + { input_move_dir.x -= 1; } break; - case USER_BIND_KIND_MOVE_RIGHT: { + case USER_BIND_KIND_MOVE_RIGHT: + { input_move_dir.x += 1; } break; @@ -1716,7 +1705,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg) (UNUSED)arg; i64 last_frame_ns = 0; - i64 target_dt_ns = NS_FROM_SECONDS(USER_FRAME_LIMIT > (0) ? (1.0 / USER_FRAME_LIMIT) : 0); + i64 target_dt_ns = NS_FROM_SECONDS(USER_FPS_LIMIT > (0) ? (1.0 / USER_FPS_LIMIT) : 0); while (!atomic_i32_eval(&G.user_thread_shutdown)) { __profscope(user_update_w_sleep); @@ -1749,8 +1738,9 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) struct sim_snapshot *prev_ss = sim_snapshot_nil(); + i64 last_publish_ns = 0; i64 last_tick_ns = 0; - i64 target_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND;; + i64 target_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND; while (!atomic_i32_eval(&G.local_sim_thread_shutdown)) { struct temp_arena scratch = scratch_begin_no_conflict(); { @@ -1812,8 +1802,11 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) { struct sys_lock lock = sys_mutex_lock_e(&G.local_sim_ss_mutex); struct sim_snapshot *pub_ss = sim_snapshot_alloc(G.local_sim_ss_store, ss, ss->tick); - pub_ss->published_at_ns = sys_time_ns(); sim_snapshot_store_release_ticks_in_range(G.local_sim_ss_store, 0, pub_ss->tick - 1); + i64 publish_ns = sys_time_ns(); + pub_ss->publish_dt_ns = publish_ns - last_publish_ns; + pub_ss->publish_time_ns = publish_ns; + last_publish_ns = publish_ns; sys_mutex_unlock(&lock); }