diff --git a/src/config.h b/src/config.h index 20af8650..7b2334a5 100644 --- a/src/config.h +++ b/src/config.h @@ -62,7 +62,7 @@ #define COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI 0 /* If enabled, bitbuffs will insert/verify magic numbers & length for each read & write */ -#define BITBUFF_DEBUG 0 +#define BITBUFF_DEBUG RTC #define BITBUFF_TEST RTC /* ========================== * diff --git a/src/sim.c b/src/sim.c index bfae2920..85a43768 100644 --- a/src/sim.c +++ b/src/sim.c @@ -125,7 +125,7 @@ void sim_client_store_release(struct sim_client_store *store) * Client alloc * ========================== */ -struct sim_client *sim_client_alloc(struct sim_client_store *store, enum sim_client_kind kind) +struct sim_client *sim_client_alloc(struct sim_client_store *store) { struct sim_client_handle handle = ZI; struct sim_client *client = sim_client_from_handle(store, store->first_free_client); @@ -144,7 +144,6 @@ struct sim_client *sim_client_alloc(struct sim_client_store *store, enum sim_cli *client = *sim_client_nil(); client->store = store; client->valid = true; - client->kind = kind; client->handle = handle; client->snapshots_arena = arena_alloc(GIGABYTE(8)); @@ -302,12 +301,8 @@ struct sim_snapshot *sim_snapshot_alloc(struct sim_client *client, struct sim_sn ++client->num_ticks; /* Copy src info */ - ss->is_master = src->is_master; - ss->real_dt_ns = src->real_dt_ns; - ss->real_time_ns = src->real_time_ns; - ss->world_timescale = src->world_timescale; - ss->world_dt_ns = src->world_dt_ns; - ss->world_time_ns = src->world_time_ns; + ss->sim_dt_ns = src->sim_dt_ns; + ss->sim_time_ns = src->sim_time_ns; ss->continuity_gen = src->continuity_gen; ss->local_client = src->local_client; ss->phys_iteration = src->phys_iteration; @@ -528,11 +523,8 @@ struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_client *client, str if (should_blend) { /* Blend time */ - ss->real_dt_ns = math_lerp_i64(ss0->real_dt_ns, ss1->real_dt_ns, blend); - ss->real_time_ns = math_lerp_i64(ss0->real_time_ns, ss1->real_time_ns, blend); - ss->world_timescale = math_lerp_f64(ss0->world_timescale, ss1->world_timescale, blend); - ss->world_dt_ns = math_lerp_i64(ss0->world_dt_ns, ss1->world_dt_ns, blend); - ss->world_time_ns = math_lerp_i64(ss0->world_time_ns, ss1->world_time_ns, blend); + ss->sim_dt_ns = math_lerp_i64(ss0->sim_dt_ns, ss1->sim_dt_ns, blend); + ss->sim_time_ns = math_lerp_i64(ss0->sim_time_ns, ss1->sim_time_ns, blend); /* Blend entities */ { @@ -559,15 +551,8 @@ void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_client *receiver, { __prof; - /* TODO: Don't encode this */ - bw_write_bit(bw, ss1->is_master); - - bw_write_iv(bw, ss1->real_dt_ns); - bw_write_iv(bw, ss1->real_time_ns); - - bw_write_f64(bw, ss1->world_timescale); - bw_write_iv(bw, ss1->world_dt_ns); - bw_write_iv(bw, ss1->world_time_ns); + bw_write_iv(bw, ss1->sim_dt_ns); + bw_write_iv(bw, ss1->sim_time_ns); bw_write_uv(bw, ss1->continuity_gen); bw_write_uv(bw, ss1->phys_iteration); @@ -575,12 +560,6 @@ void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_client *receiver, bw_write_uv(bw, receiver->handle.gen); bw_write_uv(bw, receiver->handle.idx); - bw_write_f32(bw, ss1->control.move.x); - bw_write_f32(bw, ss1->control.move.y); - bw_write_f32(bw, ss1->control.focus.x); - bw_write_f32(bw, ss1->control.focus.y); - bw_write_ubits(bw, ss1->control.flags, 32); - /* Ents */ if (ss1->num_ents_allocated == ss0->num_ents_allocated) { bw_write_bit(bw, 0); @@ -612,15 +591,8 @@ void sim_snapshot_decode(struct bitbuff_reader *br, struct sim_snapshot *ss) { __prof; - /* TODO: Don't encode this */ - ss->is_master = br_read_bit(br); - - ss->real_dt_ns = br_read_iv(br); - ss->real_time_ns = br_read_iv(br); - - ss->world_timescale = br_read_f64(br); - ss->world_dt_ns = br_read_iv(br); - ss->world_time_ns = br_read_iv(br); + ss->sim_dt_ns = br_read_iv(br); + ss->sim_time_ns = br_read_iv(br); ss->continuity_gen = br_read_uv(br); ss->phys_iteration = br_read_uv(br); @@ -628,12 +600,6 @@ void sim_snapshot_decode(struct bitbuff_reader *br, struct sim_snapshot *ss) ss->local_client.gen = br_read_uv(br); ss->local_client.idx = br_read_uv(br); - ss->control.move.x = br_read_f32(br); - ss->control.move.y = br_read_f32(br); - ss->control.focus.x = br_read_f32(br); - ss->control.focus.y = br_read_f32(br); - ss->control.flags = br_read_ubits(br, 32); - /* Ents */ if (br_read_bit(br)) { ss->num_ents_allocated = br_read_uv(br); diff --git a/src/sim.h b/src/sim.h index b413c16c..8e08537f 100644 --- a/src/sim.h +++ b/src/sim.h @@ -60,14 +60,6 @@ void sim_client_store_release(struct sim_client_store *store); struct sim_snapshot; -enum sim_client_kind { - SIM_CLIENT_KIND_INVALID, - SIM_CLIENT_KIND_USER, - SIM_CLIENT_KIND_LOCAL_SIM, - SIM_CLIENT_KIND_SLAVE_SIM, - SIM_CLIENT_KIND_MASTER_SIM, -}; - struct sim_snapshot_lookup_bucket { struct sim_snapshot *first; struct sim_snapshot *last; @@ -75,7 +67,6 @@ struct sim_snapshot_lookup_bucket { struct sim_client { b32 valid; - enum sim_client_kind kind; struct sim_client_handle handle; struct sim_client_store *store; @@ -91,8 +82,10 @@ struct sim_client { /* This is the last confirmed tick of ours that we know this client has received */ u64 ack; - /* This is the last confirmed client tick that the client knows we have received */ - u64 reverse_ack; + /* This is the last confirmed ack of ours that we know this client has received (this + * can be used to determine which client ticks will no longer be delta encoded from and + * can therefore be released) */ + u64 double_ack; /* Snapshots sorted by tick (low to high) */ u64 first_tick; @@ -111,7 +104,12 @@ INLINE struct sim_client *sim_client_nil(void) return *_g_sim_client_nil; } -struct sim_client *sim_client_alloc(struct sim_client_store *store, enum sim_client_kind kind); +INLINE b32 sim_client_handle_eq(struct sim_client_handle a, struct sim_client_handle b) +{ + return a.gen == b.gen && a.idx == b.idx; +} + +struct sim_client *sim_client_alloc(struct sim_client_store *store); void sim_client_release(struct sim_client *client); struct sim_client *sim_client_from_channel_id(struct sim_client_store *store, struct host_channel_id channel_id); @@ -123,16 +121,14 @@ struct sim_client *sim_client_from_handle(struct sim_client_store *store, struct * ========================== */ enum sim_control_flag { - SIM_CONTROL_FLAG_NONE = 0, - SIM_CONTROL_FLAG_FIRING = 1 << 0, + SIM_CONTROL_FLAG_FIRE = 1 << 0, /* Testing */ - SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 1, - SIM_CONTROL_FLAG_SPAWN_TEST = 1 << 2, - SIM_CONTROL_FLAG_PAUSE = 1 << 3, - SIM_CONTROL_FLAG_STEP = 1 << 4, - - SIM_CONTROL_FLAG_DRAGGING = 1 << 5, + SIM_CONTROL_FLAG_DRAG = 1 << 1, + SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 2, + SIM_CONTROL_FLAG_SPAWN_TEST = 1 << 3, + SIM_CONTROL_FLAG_PAUSE = 1 << 4, + SIM_CONTROL_FLAG_STEP = 1 << 5 }; struct sim_control { @@ -153,32 +149,13 @@ struct sim_snapshot { struct arena arena; - struct sim_client_handle producer_client; - b32 producer_client_is_local; - - /* ====================================================================== */ - /* SIM_SNAPSHOT_FLAG_CONTROL */ - - struct sim_control control; - - /* ====================================================================== */ - /* SIM_SNAPSHOT_FLAG_STATE */ - - /* Was this snapshot created by the master sim */ - b32 is_master; - - /* Time of local snapshot publish to user thread */ + /* Program time of local snapshot publish to user thread (if relevant) */ i64 publish_dt_ns; i64 publish_time_ns; - /* Real time (guaranteed to increase by real_dt_ns each sim step) */ - i64 real_dt_ns; - i64 real_time_ns; - - /* World time (affected by timescale) */ - f64 world_timescale; - i64 world_dt_ns; - i64 world_time_ns; + /* Sim time (guaranteed to increase by sim_dt_ns each step) */ + i64 sim_dt_ns; + i64 sim_time_ns; /* If != previous tick's continuity then don't lerp */ u64 continuity_gen; @@ -186,8 +163,8 @@ struct sim_snapshot { /* The last physics iteration (used for tracking contact lifetime) */ u64 phys_iteration; - /* The receiver's client handle on the sender's machine (use this to find local client ent in snapshot) */ - struct sim_client_handle local_client; + /* TODO: Replace with networked id that resolves to local client ent? */ + struct sim_client_handle local_client; /* The receiver's client handle on the master sim (used for finding local client ent in snapshot) */ /* Entities */ struct arena ents_arena; @@ -197,16 +174,6 @@ struct sim_snapshot { u64 num_ents_reserved; }; -struct sim_snapshot_list_node { - struct sim_snapshot *ss; - struct sim_snapshot_list_node *next; -}; - -struct sim_snapshot_list { - struct sim_snapshot_list_node *first; - struct sim_snapshot_list_node *last; -}; - INLINE struct sim_snapshot *sim_snapshot_nil(void) { extern READONLY struct sim_snapshot **_g_sim_snapshot_nil; diff --git a/src/sim_ent.c b/src/sim_ent.c index af6d769e..8d1ef916 100644 --- a/src/sim_ent.c +++ b/src/sim_ent.c @@ -373,6 +373,10 @@ void sim_ent_encode(struct bitbuff_writer *bw, struct sim_ent *e0, struct sim_en { struct sim_snapshot *ss = e1->ss; + + /* FIXME: Things like xforms need to be retreived manually rather than memcopied. + * This will also be true for things like ent handles once netids are implemented. */ + /* TODO: Granular delta encoding */ u64 pos = 0; diff --git a/src/sim_ent.h b/src/sim_ent.h index 4feeddbe..e3180a96 100644 --- a/src/sim_ent.h +++ b/src/sim_ent.h @@ -20,9 +20,12 @@ enum sim_ent_prop { SIM_ENT_PROP_RELEASE_THIS_TICK, SIM_ENT_PROP_RELEASE_NEXT_TICK, + SIM_ENT_PROP_REMOTE, SIM_ENT_PROP_CLIENT, SIM_ENT_PROP_LOCAL_CLIENT, + SIM_ENT_PROP_CMD_CONTROL, + SIM_ENT_PROP_PHYSICAL_DYNAMIC, SIM_ENT_PROP_PHYSICAL_KINEMATIC, @@ -85,10 +88,19 @@ struct sim_ent { struct sim_ent_handle last; struct sim_ent_handle next_free; + /* ====================================================================== */ + /* Remote */ + + /* SIM_ENT_PROP_REMOTE */ + + struct sim_client_handle remote_client; + struct sim_ent_handle remote_ent; + /* ====================================================================== */ /* Position */ /* Access with xform getters/setters */ + /* TODO: Prefix with '_' to signal against direct access */ struct xform local_xform; /* Transform in relation to parent ent (or the world if ent has no parent) */ struct xform cached_global_xform; /* Calculated from ent tree */ b32 cached_global_xform_dirty; @@ -105,6 +117,35 @@ struct sim_ent { i32 layer; i32 final_layer; /* Calculated each tick from ent tree */ + /* ====================================================================== */ + /* Cmd */ + + /* SIM_ENT_PROP_CMD_CONTROL */ + + /* FIXME: Lerp */ + + struct sim_ent_handle cmd_client; + struct sim_control cmd_control; + + /* ====================================================================== */ + /* Client */ + + /* SIM_ENT_PROP_CLIENT */ + + /* FIXME: Lerp */ + + struct sim_client_handle client_handle; /* The client handle on the master sim's machine */ + + struct sim_control client_control; + struct v2 client_cursor_pos; + + struct sim_ent_handle client_control_ent; + struct sim_ent_handle client_camera_ent; + + struct sim_ent_handle client_dbg_drag_joint_ent; + b32 client_dbg_drag_start; + b32 client_dbg_drag_stop; + /* ====================================================================== */ /* Collider */ @@ -134,25 +175,6 @@ struct sim_ent { /* SIM_ENT_PROP_MOUSE_JOINT */ struct phys_mouse_joint mouse_joint_data; - /* ====================================================================== */ - /* Client */ - - /* SIM_ENT_PROP_CLIENT */ - - /* FIXME: Lerp */ - - struct sim_client_handle client_handle; - - struct sim_control client_control; - struct v2 client_cursor_pos; - - struct sim_ent_handle client_control_ent; - struct sim_ent_handle client_camera_ent; - - struct sim_ent_handle client_dbg_drag_joint_ent; - b32 client_dbg_drag_start; - b32 client_dbg_drag_stop; - /* ====================================================================== */ /* Control */ @@ -231,7 +253,7 @@ struct sim_ent { /* SIM_ENT_PROP_TRIGGERED_THIS_TICK */ f32 trigger_delay; /* Minimum time between triggers */ - f32 last_triggered; + i64 last_triggered_ns; /* ====================================================================== */ /* Bullet */ diff --git a/src/sim_step.c b/src/sim_step.c index fb37ae12..14a3b2af 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -124,6 +124,16 @@ void sim_lookup_remove(struct sim_lookup *l, struct sim_lookup_entry *entry) l->first_free_entry = entry; } +struct sim_lookup_key sim_lookup_key_from_client_and_ent_handles(struct sim_client_handle client_handle, struct sim_ent_handle ent_handle) +{ + struct sim_lookup_key key = ZI; + struct string b0 = STRING_FROM_STRUCT(&client_handle); + struct string b1 = STRING_FROM_STRUCT(&ent_handle); + key.hash = hash_fnv64(HASH_FNV64_BASIS, b0); + key.hash = hash_fnv64(key.hash, b1); + return key; +} + struct sim_lookup_key sim_lookup_key_from_two_handles(struct sim_ent_handle h0, struct sim_ent_handle h1) { struct sim_lookup_key key = ZI; @@ -149,6 +159,7 @@ struct sim_accel sim_accel_alloc(void) { struct sim_accel accel = ZI; accel.space = space_alloc(1, 256); + accel.remote_lookup = sim_lookup_alloc(4096); accel.client_lookup = sim_lookup_alloc(4096); accel.contact_lookup = sim_lookup_alloc(4096); #if COLLIDER_DEBUG @@ -164,6 +175,7 @@ void sim_accel_release(struct sim_accel *accel) #endif sim_lookup_release(&accel->contact_lookup); sim_lookup_release(&accel->client_lookup); + sim_lookup_release(&accel->remote_lookup); space_release(accel->space); } @@ -172,6 +184,7 @@ void sim_accel_rebuild(struct sim_snapshot *ss, struct sim_accel *accel) /* FIXME: Rebuild collision debug lookup */ space_reset(accel->space); + sim_lookup_reset(&accel->remote_lookup); sim_lookup_reset(&accel->client_lookup); sim_lookup_reset(&accel->contact_lookup); @@ -188,6 +201,10 @@ void sim_accel_rebuild(struct sim_snapshot *ss, struct sim_accel *accel) for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { struct sim_ent *ent = &ss->ents[sim_ent_index]; if (!sim_ent_is_valid_and_active(ent)) continue; + if (sim_ent_has_prop(ent, SIM_ENT_PROP_REMOTE)) { + struct sim_lookup_key key = sim_lookup_key_from_client_and_ent_handles(ent->remote_client, ent->remote_ent); + sim_lookup_set(&accel->remote_lookup, key, ent->handle); + } if (sim_ent_has_prop(ent, SIM_ENT_PROP_CLIENT)) { struct sim_lookup_key key = sim_lookup_key_from_client_handle(ent->client_handle); sim_lookup_set(&accel->client_lookup, key, ent->handle); @@ -561,40 +578,24 @@ void sim_step(struct sim_step_ctx *step_ctx) struct temp_arena scratch = scratch_begin_no_conflict(); struct sim_snapshot *world = step_ctx->world; - struct sim_accel *accel = step_ctx->accel; - struct sim_snapshot_list *cmd_snapshots = step_ctx->cmd_snapshots; - i64 real_dt_ns = step_ctx->real_dt_ns; + i64 sim_dt_ns = step_ctx->sim_dt_ns; /* ========================== * * Begin frame * ========================== */ - sim_accel_rebuild(world, step_ctx->accel); - //sys_sleep_precise(rng_rand_f32(0, 0.050)); //sys_sleep_precise(0.050); - world->real_dt_ns = max_i64(0, real_dt_ns); - world->real_time_ns += world->real_dt_ns; - - world->world_timescale = SIM_TIMESCALE; - world->world_dt_ns = max_i64(0, real_dt_ns * world->world_timescale); - world->world_time_ns += world->world_dt_ns; - - f64 real_dt = SECONDS_FROM_NS(world->real_dt_ns); - f64 real_time = SECONDS_FROM_NS(world->real_time_ns); - f64 world_dt = SECONDS_FROM_NS(world->world_dt_ns); - f64 world_time = SECONDS_FROM_NS(world->world_time_ns); - (UNUSED)real_dt; - (UNUSED)real_time; - (UNUSED)world_dt; - (UNUSED)world_time; + world->sim_dt_ns = max_i64(0, sim_dt_ns); + world->sim_time_ns += world->sim_dt_ns; + f32 sim_dt = SECONDS_FROM_NS(world->sim_dt_ns); struct sprite_scope *sprite_frame_scope = sprite_scope_begin(); struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE); - if (world->is_master) { + if (step_ctx->is_master) { /* ========================== * * Spawn test entities * ========================== */ @@ -651,6 +652,67 @@ void sim_step(struct sim_step_ctx *step_ctx) * Process client cmds * ========================== */ + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + struct sim_ent *cmd_ent = &world->ents[ent_index]; + if (!sim_ent_is_valid_and_active(cmd_ent)) continue; + + if (sim_ent_has_prop(cmd_ent, SIM_ENT_PROP_CMD_CONTROL)) { + struct sim_ent *client_ent = sim_ent_from_handle(world, cmd_ent->cmd_client); + if (sim_ent_is_valid_and_active(client_ent)) { + /* Process control cmd for client */ + struct sim_control old_control = client_ent->client_control; + struct sim_control *control = &client_ent->client_control; + *control = cmd_ent->cmd_control; + { + client_ent->client_dbg_drag_start = false; + client_ent->client_dbg_drag_stop = false; + + if (v2_len_sq(control->move) > 1) { + /* Cap movement vector magnitude at 1 */ + control->move = v2_norm(control->move); + } + + /* Determine cursor pos from focus */ + { + struct sim_ent_handle client_control_ent_handle = client_ent->client_control_ent; + struct sim_ent *client_control_ent = sim_ent_from_handle(world, client_control_ent_handle); + if (client_control_ent->valid || sim_ent_handle_eq(client_control_ent_handle, SIM_ENT_NIL_HANDLE)) { + /* Only update cursor pos if focus ent is valid (or nil) */ + client_ent->client_cursor_pos = v2_add(sim_ent_get_xform(client_control_ent).og, client_ent->client_control.focus); + } + } + + u32 flags = control->flags; + if (flags & SIM_CONTROL_FLAG_DRAG) { + if (!(old_control.flags & SIM_CONTROL_FLAG_DRAG)) { + client_ent->client_dbg_drag_start = true; + } + } else { + if (old_control.flags & SIM_CONTROL_FLAG_DRAG) { + client_ent->client_dbg_drag_stop = true; + } + } + if (flags & SIM_CONTROL_FLAG_CLEAR_ALL) { + if (!(old_control.flags & SIM_CONTROL_FLAG_CLEAR_ALL)) { + test_clear_level(world); + } + } + if (flags & SIM_CONTROL_FLAG_SPAWN_TEST) { + if (!(old_control.flags & SIM_CONTROL_FLAG_SPAWN_TEST)) { + logf_info("Spawning (test)"); + u32 count = 1; + f32 spread = 1; + for (u32 j = 0; j < count; ++j) { + spawn_test_entities(world, V2(0, (((f32)j / (f32)count) - 0.5) * spread)); + } + } + } + } + } + } + } + +#if 0 for (struct sim_snapshot_list_node *n = cmd_snapshots->first; n; n = n->next) { struct sim_snapshot *cmd_snapshot = n->ss; struct sim_client_handle client_handle = cmd_snapshot->producer_client; @@ -698,12 +760,12 @@ void sim_step(struct sim_step_ctx *step_ctx) } u32 flags = control->flags; - if (flags & SIM_CONTROL_FLAG_DRAGGING) { - if (!(old_control.flags & SIM_CONTROL_FLAG_DRAGGING)) { + if (flags & SIM_CONTROL_FLAG_DRAG) { + if (!(old_control.flags & SIM_CONTROL_FLAG_DRAG)) { client_ent->client_dbg_drag_start = true; } } else { - if (old_control.flags & SIM_CONTROL_FLAG_DRAGGING) { + if (old_control.flags & SIM_CONTROL_FLAG_DRAG) { client_ent->client_dbg_drag_stop = true; } } @@ -724,6 +786,10 @@ void sim_step(struct sim_step_ctx *step_ctx) } } } +#endif + + + /* ========================== * * Create client player ents @@ -762,7 +828,7 @@ void sim_step(struct sim_step_ctx *step_ctx) if (client_ent->valid) { ent->control = client_ent->client_control; /* TODO: Move this */ - if (ent->control.flags & SIM_CONTROL_FLAG_FIRING) { + if (ent->control.flags & SIM_CONTROL_FLAG_FIRE) { sim_ent_enable_prop(ent, SIM_ENT_PROP_TRIGGERING_EQUIPPED); } else { sim_ent_disable_prop(ent, SIM_ENT_PROP_TRIGGERING_EQUIPPED); @@ -786,10 +852,10 @@ void sim_step(struct sim_step_ctx *step_ctx) { struct sprite_sheet_span span = sprite_sheet_get_span(sheet, ent->sprite_span_name); if (ent->animation_last_frame_change_time_ns == 0) { - ent->animation_last_frame_change_time_ns = world_time; + ent->animation_last_frame_change_time_ns = SECONDS_FROM_NS(world->sim_time_ns); } - f64 time_in_frame = SECONDS_FROM_NS(world->world_time_ns - ent->animation_last_frame_change_time_ns); + f64 time_in_frame = SECONDS_FROM_NS(world->sim_time_ns - ent->animation_last_frame_change_time_ns); u64 frame_index = ent->animation_frame; if (frame_index < span.start || frame_index > span.end) { frame_index = span.start; @@ -805,7 +871,7 @@ void sim_step(struct sim_step_ctx *step_ctx) frame_index = span.start; } frame = sprite_sheet_get_frame(sheet, frame_index); - ent->animation_last_frame_change_time_ns = world->world_time_ns; + ent->animation_last_frame_change_time_ns = world->sim_time_ns; } } @@ -971,9 +1037,9 @@ void sim_step(struct sim_step_ctx *step_ctx) struct sim_ent *ent = &world->ents[ent_index]; if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_TRIGGERED_THIS_TICK)) continue; - if ((world_time - ent->last_triggered < ent->trigger_delay) && ent->last_triggered != 0) continue; + if ((world->sim_time_ns - ent->last_triggered_ns < NS_FROM_SECONDS(ent->trigger_delay)) && ent->last_triggered_ns != 0) continue; - ent->last_triggered = world_time; + ent->last_triggered_ns = world->sim_time_ns; /* Fire weapon */ if (sim_ent_has_prop(ent, SIM_ENT_PROP_WEAPON)) { @@ -1092,7 +1158,7 @@ void sim_step(struct sim_step_ctx *step_ctx) } /* Set correction rate dynamically since motor velocity is only set for one frame */ - joint_ent->motor_joint_data.correction_rate = 10 * world_dt; + joint_ent->motor_joint_data.correction_rate = 10 * sim_dt; /* Solve for final angle using law of sines */ @@ -1145,7 +1211,7 @@ void sim_step(struct sim_step_ctx *step_ctx) f32 diff = math_unwind_angle(new_angle - xform_get_rotation(joint_xf)); if (math_fabs(diff) > angle_error_allowed) { /* Instantly snap joint ent to new angle */ - new_vel = diff / real_dt; + new_vel = diff / sim_dt; } } sim_ent_set_angular_velocity(joint_ent, new_vel); @@ -1260,7 +1326,7 @@ void sim_step(struct sim_step_ctx *step_ctx) struct phys_step_ctx phys = ZI; phys.sim_step_ctx = step_ctx; phys.pre_solve_callback = on_collision; - phys_step(&phys, world_dt); + phys_step(&phys, sim_dt); } /* ========================== * @@ -1274,7 +1340,7 @@ void sim_step(struct sim_step_ctx *step_ctx) struct v2 end = sim_ent_get_xform(ent).og; - struct v2 tick_velocity = v2_mul(ent->tracer_start_velocity, world_dt); + struct v2 tick_velocity = v2_mul(ent->tracer_start_velocity, sim_dt); struct v2 gradient_start = v2_add(ent->tracer_gradient_start, tick_velocity); struct v2 gradient_end = v2_add(ent->tracer_gradient_end, tick_velocity); @@ -1374,7 +1440,7 @@ void sim_step(struct sim_step_ctx *step_ctx) /* Lerp camera */ if (ent->camera_applied_lerp_continuity_gen_plus_one == ent->camera_lerp_continuity_gen + 1) { - f32 t = 1 - math_pow(2.f, -20.f * (f32)world_dt); + f32 t = 1 - math_pow(2.f, -20.f * (f32)sim_dt); xf = xform_lerp(xf, ent->camera_xform_target, t); } else { /* Skip lerp */ @@ -1407,7 +1473,7 @@ void sim_step(struct sim_step_ctx *step_ctx) if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_QUAKE)) continue; - ent->quake_intensity = max_f32(0, ent->quake_intensity - (ent->quake_fade * world_dt)); + ent->quake_intensity = max_f32(0, ent->quake_intensity - (ent->quake_fade * sim_dt)); if (ent->quake_intensity <= 0) { sim_ent_enable_prop(ent, SIM_ENT_PROP_RELEASE_NEXT_TICK); } diff --git a/src/sim_step.h b/src/sim_step.h index a10ff44b..8e6e25be 100644 --- a/src/sim_step.h +++ b/src/sim_step.h @@ -44,6 +44,8 @@ struct sim_lookup_entry *sim_lookup_get(struct sim_lookup *l, struct sim_lookup_ void sim_lookup_set(struct sim_lookup *l, struct sim_lookup_key key, struct sim_ent_handle handle); void sim_lookup_remove(struct sim_lookup *l, struct sim_lookup_entry *entry); + +struct sim_lookup_key sim_lookup_key_from_client_and_ent_handles(struct sim_client_handle client_handle, struct sim_ent_handle ent_handle); struct sim_lookup_key sim_lookup_key_from_two_handles(struct sim_ent_handle h0, struct sim_ent_handle h1); struct sim_lookup_key sim_lookup_key_from_client_handle(struct sim_client_handle handle); @@ -56,6 +58,7 @@ struct sim_lookup_key sim_lookup_key_from_client_handle(struct sim_client_handle struct sim_accel { struct space *space; + struct sim_lookup remote_lookup; struct sim_lookup client_lookup; struct sim_lookup contact_lookup; #if COLLIDER_DEBUG @@ -72,10 +75,10 @@ void sim_accel_rebuild(struct sim_snapshot *ss, struct sim_accel *accel); * ========================== */ struct sim_step_ctx { + b32 is_master; struct sim_accel *accel; struct sim_snapshot *world; - struct sim_snapshot_list *cmd_snapshots; - i64 real_dt_ns; + i64 sim_dt_ns; }; void sim_step(struct sim_step_ctx *step_ctx); diff --git a/src/sock_win32.c b/src/sock_win32.c index 4336d2f9..22ae8c45 100644 --- a/src/sock_win32.c +++ b/src/sock_win32.c @@ -414,7 +414,7 @@ struct sock_read_result sock_read(struct sock *sock, struct string read_buff) res.address = sock_address_from_win32_address(ws_addr); if (size >= 0) { - atomic_u64_eval_add_u64(&app_statistics()->sock_bytes_sent, size); + atomic_u64_eval_add_u64(&app_statistics()->sock_bytes_received, size); res.data.text = read_buff.text; res.data.len = size; res.valid = true; diff --git a/src/user.c b/src/user.c index 717a530f..8d32afe5 100644 --- a/src/user.c +++ b/src/user.c @@ -49,14 +49,14 @@ GLOBAL struct { struct string connect_address_str; struct sim_client_store *user_client_store; - struct sim_client *user_unblended_snapshots_client; /* Contains buffered snapshots received from sim */ - struct sim_client *user_blended_snapshots_client; /* Contains single world snapshot from result of blending sim snapshots */ - struct sim_snapshot *ss_blended; /* Points to blended snapshot in blended snapshots client */ + struct sim_client *user_unblended_client; /* Contains snapshots received from local sim */ + struct sim_client *user_blended_client; /* Contains single snapshot from result of blending local sim snapshots */ + struct sim_snapshot *ss_blended; /* Points to blended snapshot contained in blended client */ /* Usage stats */ i64 last_second_reset_ns; - struct second_stat client_bytes_read; - struct second_stat client_bytes_sent; + struct second_stat net_bytes_read; + struct second_stat net_bytes_sent; /* Render targets */ struct renderer_texture final_texture; @@ -88,23 +88,21 @@ GLOBAL struct { struct sim_control user_sim_cmd_control; u64 last_user_sim_cmd_gen; u64 user_sim_cmd_gen; - u64 user_sim_cmd_ack; /* Local sim -> user */ - struct sys_mutex local_sim_to_user_mutex; - struct sim_client_store *local_sim_to_user_client_store; - struct sim_client *local_sim_to_user_client; + struct sys_mutex local_to_user_client_mutex; + struct sim_client_store *local_to_user_client_store; + struct sim_client *local_to_user_client; - /* Rolling window of local sim publish times */ - i64 last_snapshot_published_at_ns; - i64 snapshot_publish_dts_ns[50]; - i64 snapshot_publish_dts_index; - i64 average_snapshot_publish_dt_ns; + /* Rolling window of local sim -> user publish time deltas */ + i64 last_local_to_user_snapshot_published_at_ns; + i64 local_to_user_snapshot_publish_dts_ns[50]; + i64 local_to_user_snapshot_publish_dts_index; + i64 average_local_to_user_snapshot_publish_dt_ns; - /* Calculated from */ - i64 local_sim_predicted_time_ns; - i64 render_time_target_ns; - i64 render_time_ns; + i64 local_sim_predicted_time_ns; /* Calculated from +