From f6aa25760ec9990777bc3c3bd7d1c544fd4f8b2f Mon Sep 17 00:00:00 2001 From: jacob Date: Fri, 14 Feb 2025 17:01:44 -0600 Subject: [PATCH] sim ctx decoupling progress --- src/phys.c | 36 +++--- src/phys.h | 15 +-- src/sim.c | 292 ++++++++++++++++++++++----------------------- src/sim.h | 7 +- src/sim_snapshot.h | 53 ++++++++ src/space.h | 2 +- src/user.c | 64 +++++++++- 7 files changed, 285 insertions(+), 184 deletions(-) diff --git a/src/phys.c b/src/phys.c index 6e0b3157..3b5488fa 100644 --- a/src/phys.c +++ b/src/phys.c @@ -45,9 +45,11 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a struct phys_collision_data_array res = ZI; res.a = arena_dry_push(arena, struct phys_collision_data); struct sim_snapshot *ss = ctx->ss; - struct sim_ent_lookup *contact_lookup = ctx->contact_lookup; - struct sim_ent_lookup *debug_lookup = ctx->debug_lookup; - struct space *space = ctx->space; + struct sim_ent_lookup *contact_lookup = &ss->contact_lookup; + struct space *space = ss->space; +#if COLLIDER_DEBUG + struct sim_ent_lookup *debug_lookup = &ss->collision_debug_lookup; +#endif struct sim_ent *root = sim_ent_from_handle(ss, SIM_ENT_ROOT_HANDLE); u64 tick = ss->tick; @@ -271,8 +273,6 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a dbg->closest1 = closest_points_res.p1; } } -#else - (UNUSED)debug_lookup; #endif } space_iter_end(&iter); @@ -283,8 +283,8 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration) { __prof; - struct sim_ent_lookup *contact_lookup = ctx->contact_lookup; struct sim_snapshot *ss = ctx->ss; + struct sim_ent_lookup *contact_lookup = &ss->contact_lookup; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { struct sim_ent *constraint_ent = &ss->ents[sim_ent_index]; @@ -985,6 +985,7 @@ void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt) { __prof; struct sim_snapshot *ss = ctx->ss; + struct space *space = ss->space; 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; @@ -993,7 +994,7 @@ void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt) struct xform xf = get_derived_xform(ent, dt); sim_ent_set_xform(ent, xf); - struct space_entry *space_entry = space_entry_from_handle(ctx->space, ent->space_handle); + struct space_entry *space_entry = space_entry_from_handle(space, ent->space_handle); if (space_entry->valid) { space_entry_update_aabb(space_entry, collider_aabb_from_collider(&ent->local_collider, xf)); } @@ -1008,7 +1009,7 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f { __prof; struct sim_snapshot *ss = ctx->ss; - struct space *space = ctx->space; + struct space *space = ss->space; f32 smallest_t = 1; for (u64 e0_index = 0; e0_index < ss->num_ents_reserved; ++e0_index) { @@ -1058,15 +1059,16 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f void phys_update_aabbs(struct phys_ctx *ctx) { struct sim_snapshot *ss = ctx->ss; + struct space *space = ss->space; 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 (ent->local_collider.count <= 0) continue; struct xform xf = sim_ent_get_xform(ent); - struct space_entry *space_entry = space_entry_from_handle(ctx->space, ent->space_handle); + struct space_entry *space_entry = space_entry_from_handle(space, ent->space_handle); if (!space_entry->valid) { - space_entry = space_entry_alloc(ctx->space, ent->handle); + space_entry = space_entry_alloc(space, ent->handle); ent->space_handle = space_entry->handle; } space_entry_update_aabb(space_entry, collider_aabb_from_collider(&ent->local_collider, xf)); @@ -1078,11 +1080,13 @@ void phys_update_aabbs(struct phys_ctx *ctx) * ========================== */ /* Returns phys iteration to be fed into next step. Supplied iteration must be > 0. */ -u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_iteration) +void phys_step(struct phys_ctx *ctx, f32 timestep) { __prof; phys_integrate_forces(ctx, timestep); - u64 phys_iteration = last_iteration; + u64 phys_iteration = ctx->ss->phys_iteration; + + phys_update_aabbs(ctx); f32 remaining_dt = timestep; while (remaining_dt > 0) { @@ -1090,8 +1094,6 @@ u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_iteration) ++phys_iteration; struct temp_arena scratch = scratch_begin_no_conflict(); - phys_update_aabbs(ctx); - /* TOI */ f32 step_dt = remaining_dt; { @@ -1115,7 +1117,7 @@ u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_iteration) if (ctx->pre_solve_callback) { __profscope(pre_solve_callback); - ctx->pre_solve_callback(collision_data, ctx->pre_solve_callback_udata); + ctx->pre_solve_callback(collision_data, ctx->ss); } f32 substep_dt = step_dt / SIM_PHYSICS_SUBSTEPS; @@ -1147,11 +1149,11 @@ u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_iteration) if (ctx->post_solve_callback) { __profscope(post_solve_callback); - ctx->post_solve_callback(collision_data, ctx->post_solve_callback_udata); + ctx->post_solve_callback(collision_data, ctx->ss); } scratch_end(scratch); } - return phys_iteration; + ctx->ss->phys_iteration = phys_iteration; } diff --git a/src/phys.h b/src/phys.h index 9820c4f2..2b6d8014 100644 --- a/src/phys.h +++ b/src/phys.h @@ -6,6 +6,7 @@ struct space; struct sim_ent_lookup; +struct sim_snapshot; struct phys_contact_constraint; struct phys_collision_data { @@ -24,22 +25,14 @@ struct phys_collision_data_array { }; struct phys_collision_data; -#define PHYS_COLLISION_CALLBACK_FUNC_DEF(name, arg_collision_data, arg_udata) void name(struct phys_collision_data_array arg_collision_data, void *arg_udata) -typedef PHYS_COLLISION_CALLBACK_FUNC_DEF(phys_collision_callback_func, collision_data, udata); +#define PHYS_COLLISION_CALLBACK_FUNC_DEF(name, arg_collision_data, arg_ss) void name(struct phys_collision_data_array arg_collision_data, struct sim_snapshot *arg_ss) +typedef PHYS_COLLISION_CALLBACK_FUNC_DEF(phys_collision_callback_func, collision_data, ss); /* Structure containing data used for a single physics step */ struct phys_ctx { struct sim_snapshot *ss; - struct space *space; - struct sim_ent_lookup *contact_lookup; - phys_collision_callback_func *pre_solve_callback; phys_collision_callback_func *post_solve_callback; - void *pre_solve_callback_udata; - void *post_solve_callback_udata; - - struct sim_ent_lookup *debug_lookup; - }; /* ========================== * @@ -208,6 +201,6 @@ void phys_update_aabbs(struct phys_ctx *ctx); * Step * ========================== */ -u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 phys_iteration); +void phys_step(struct phys_ctx *ctx, f32 timestep); #endif diff --git a/src/sim.c b/src/sim.c index 95833f0a..8d89c9f7 100644 --- a/src/sim.c +++ b/src/sim.c @@ -21,6 +21,7 @@ * Ctx * ========================== */ +#if 0 struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr, struct phys_startup_receipt *phys_sr, struct host_startup_receipt *host_sr, @@ -37,10 +38,10 @@ struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr, (UNUSED)sim_snapshot_sr; /* Intialize host */ - ctx->host = host_alloc(host_port); + host = host_alloc(host_port); /* Allocate encoder bitbuff */ - ctx->encoder_bitbuff = bitbuff_alloc(GIGABYTE(64)); + encoder_bitbuff = bitbuff_alloc(GIGABYTE(64)); /* Create bookkeeping */ ctx->contact_lookup = sim_ent_lookup_alloc(4096); @@ -50,8 +51,8 @@ struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr, ctx->space = space_alloc(SPACE_CELL_SIZE, SPACE_CELL_BUCKETS_SQRT); /* Create snapshot store */ - ctx->snapshot_store = sim_snapshot_store_alloc(); - ctx->world = sim_snapshot_nil(); + snapshot_store = sim_snapshot_store_alloc(); + world = sim_snapshot_nil(); return ctx; } @@ -61,7 +62,7 @@ void sim_ctx_release(struct sim_ctx *ctx) __prof; /* Release snapshot store */ - sim_snapshot_store_release(ctx->snapshot_store); + sim_snapshot_store_release(snapshot_store); /* Release bookkeeping */ space_release(ctx->space); @@ -71,13 +72,14 @@ void sim_ctx_release(struct sim_ctx *ctx) sim_ent_lookup_release(&ctx->contact_lookup); /* Release encoder bitbuff */ - bitbuff_release(&ctx->encoder_bitbuff); + bitbuff_release(&encoder_bitbuff); /* Release host */ - host_release(ctx->host); + host_release(host); arena_release(&ctx->arena); } +#endif /* ========================== * * Test @@ -85,9 +87,9 @@ void sim_ctx_release(struct sim_ctx *ctx) /* TODO: Remove this */ -INTERNAL void spawn_test_entities(struct sim_ctx *ctx, struct v2 offset) +INTERNAL void spawn_test_entities(struct sim_snapshot *world, struct v2 offset) { - struct sim_ent *root = sim_ent_from_handle(ctx->world, SIM_ENT_ROOT_HANDLE); + struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE); root->mass_unscaled = F32_INFINITY; root->inertia_unscaled = F32_INFINITY; @@ -161,9 +163,9 @@ INTERNAL void spawn_test_entities(struct sim_ctx *ctx, struct v2 offset) #endif } -INTERNAL struct sim_ent *spawn_test_player(struct sim_ctx *ctx) +INTERNAL struct sim_ent *spawn_test_player(struct sim_snapshot *world) { - struct sim_ent *root = sim_ent_from_handle(ctx->world, SIM_ENT_ROOT_HANDLE); + struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE); /* Player */ struct sim_ent *player_ent = sim_ent_nil(); @@ -236,9 +238,9 @@ INTERNAL struct sim_ent *spawn_test_player(struct sim_ctx *ctx) return player_ent; } -INTERNAL struct sim_ent *spawn_test_player_camera(struct sim_ctx *ctx, struct sim_ent *player_ent) +INTERNAL struct sim_ent *spawn_test_player_camera(struct sim_snapshot *world, struct sim_ent *player_ent) { - struct sim_ent *root = sim_ent_from_handle(ctx->world, SIM_ENT_ROOT_HANDLE); + struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE); struct sim_ent *camera_ent = sim_ent_nil(); if (player_ent->valid) { @@ -257,10 +259,10 @@ INTERNAL struct sim_ent *spawn_test_player_camera(struct sim_ctx *ctx, struct si return camera_ent; } -INTERNAL void test_clear_level(struct sim_ctx *ctx) +INTERNAL void test_clear_level(struct sim_snapshot *world) { - for (u64 j = 0; j < ctx->world->num_ents_reserved; ++j) { - struct sim_ent *ent = &ctx->world->ents[j]; + for (u64 j = 0; j < world->num_ents_reserved; ++j) { + struct sim_ent *ent = &world->ents[j]; if (ent->valid) { sim_ent_enable_prop(ent, SIM_ENT_PROP_RELEASE_NEXT_TICK); } @@ -271,15 +273,15 @@ INTERNAL void test_clear_level(struct sim_ctx *ctx) * Release entities * ========================== */ -INTERNAL void release_entities_with_prop(struct sim_ctx *ctx, enum sim_ent_prop prop) +INTERNAL void release_entities_with_prop(struct sim_snapshot *world, enum sim_ent_prop prop) { struct temp_arena scratch = scratch_begin_no_conflict(); - struct space *space = ctx->space; + struct space *space = world->space; struct sim_ent **ents_to_release = arena_dry_push(scratch.arena, struct sim_ent *); u64 ents_to_release_count = 0; - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + struct sim_ent *ent = &world->ents[ent_index]; if (ent->valid && sim_ent_has_prop(ent, prop)) { *arena_push(scratch.arena, struct sim_ent *) = ent; ++ents_to_release_count; @@ -315,17 +317,16 @@ INTERNAL void release_entities_with_prop(struct sim_ctx *ctx, enum sim_ent_prop * Respond to physics collisions * ========================== */ -INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, udata) +INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, world) { - struct sim_ctx *ctx = (struct sim_ctx *)udata; - struct sim_ent *root = sim_ent_from_handle(ctx->world, SIM_ENT_ROOT_HANDLE); + struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE); for (u64 i = 0; i < collision_data_array.count; ++i) { struct phys_collision_data *data = &collision_data_array.a[i]; struct phys_contact_constraint *constraint = data->constraint; - struct sim_ent *e0 = sim_ent_from_handle(ctx->world, data->e0); - struct sim_ent *e1 = sim_ent_from_handle(ctx->world, data->e1); + struct sim_ent *e0 = sim_ent_from_handle(world, data->e0); + struct sim_ent *e1 = sim_ent_from_handle(world, data->e1); if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) { /* Bullet hit entity */ @@ -341,7 +342,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, ud normal = v2_neg(normal); vrel = v2_neg(vrel); } - struct sim_ent *src = sim_ent_from_handle(ctx->world, bullet->bullet_src); + struct sim_ent *src = sim_ent_from_handle(world, bullet->bullet_src); if (bullet->bullet_has_hit || sim_ent_handle_eq(src->top, target->top)) { /* Ignore collision if bullet already spent or if weapon and @@ -356,7 +357,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, ud sim_ent_enable_prop(bullet, SIM_ENT_PROP_RELEASE_THIS_TICK); /* Update tracer */ - struct sim_ent *tracer = sim_ent_from_handle(ctx->world, bullet->bullet_tracer); + struct sim_ent *tracer = sim_ent_from_handle(world, bullet->bullet_tracer); if (sim_ent_is_valid_and_active(tracer)) { struct xform xf = sim_ent_get_xform(tracer); xf.og = point; @@ -402,61 +403,50 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, ud * Update * ========================== */ -void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) +void sim_step(struct host *host, struct bitbuff *encoder_bitbuff, struct sim_snapshot_store *snapshot_store, struct sim_snapshot *prev_snapshot, i64 real_dt_ns, struct sim_cmd_list user_sim_cmds) { __prof; - - { - __profscope(sim_update_sleep); - sleep_frame(ctx->last_tick_ns, target_dt_ns); - ctx->last_tick_ns = sys_time_ns(); - } - struct temp_arena scratch = scratch_begin_no_conflict(); /* ========================== * * Begin frame * ========================== */ - struct sim_snapshot *prev_snapshot = ctx->world; - ctx->world = sim_snapshot_alloc(ctx->snapshot_store, prev_snapshot, prev_snapshot->tick + 1); + struct sim_snapshot *world = sim_snapshot_alloc(snapshot_store, prev_snapshot, prev_snapshot->tick + 1); +#if 0 /* Release old snapshots */ { /* TODO: Something better */ - i64 release_tick = (i64)ctx->world->tick - 25; /* Arbitrary tick offset */ + i64 release_tick = (i64)world->tick - 25; /* Arbitrary tick offset */ if (release_tick > 0) { - struct sim_snapshot *old = sim_snapshot_from_tick(ctx->snapshot_store, release_tick); + struct sim_snapshot *old = sim_snapshot_from_tick(snapshot_store, release_tick); if (old->valid) { sim_snapshot_release(old); } } } +#endif + world->real_dt_ns = max_i64(0, real_dt_ns); + world->real_time_ns += world->real_dt_ns; - ctx->world->real_dt_ns = max_i64(0, target_dt_ns); - ctx->world->real_time_ns += ctx->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; - ctx->world->world_timescale = SIM_TIMESCALE; - ctx->world->world_dt_ns = max_i64(0, target_dt_ns * ctx->world->world_timescale); - ctx->world->world_time_ns += ctx->world->world_dt_ns; - - f64 sim_time = SECONDS_FROM_NS(ctx->world->world_time_ns); - ctx->sprite_frame_scope = sprite_scope_begin(); - - f64 real_dt = SECONDS_FROM_NS(ctx->world->real_dt_ns); - f64 real_time = SECONDS_FROM_NS(ctx->world->real_time_ns); - f64 world_dt = SECONDS_FROM_NS(ctx->world->world_dt_ns); - f64 world_time = SECONDS_FROM_NS(ctx->world->world_time_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; - struct space *space = ctx->space; - struct sprite_scope *sprite_frame_scope = ctx->sprite_frame_scope; + struct sprite_scope *sprite_frame_scope = sprite_scope_begin(); - struct sim_ent *root = sim_ent_from_handle(ctx->world, SIM_ENT_ROOT_HANDLE); + struct sim_ent *root = sim_ent_from_handle(world, SIM_ENT_ROOT_HANDLE); /* ========================== * * Spawn test entities @@ -468,7 +458,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) static b32 run = 0; if (!run) { run = 1; - spawn_test_entities(ctx, V2(0, 0)); + spawn_test_entities(world, V2(0, 0)); } } @@ -476,20 +466,20 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Release entities * ========================== */ - release_entities_with_prop(ctx, SIM_ENT_PROP_RELEASE_NEXT_TICK); + release_entities_with_prop(world, SIM_ENT_PROP_RELEASE_NEXT_TICK); /* ========================== * * Activate entities * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + struct sim_ent *ent = &world->ents[ent_index]; if (!ent->valid) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ACTIVE)) { u64 atick = ent->activation_tick; - if (atick != 0 || ctx->world->tick >= atick) { - sim_ent_activate(ent, ctx->world->tick); + if (atick != 0 || world->tick >= atick) { + sim_ent_activate(ent, world->tick); } } } @@ -498,8 +488,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Reset triggered entities * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_TRIGGER_NEXT_TICK)) { @@ -510,14 +500,21 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) } } + /* ========================== * + * Create user client if it doesn't exist + * ========================== */ + + (UNUSED)user_sim_cmds; + + /* ========================== * * Process host events into sim cmds * ========================== */ struct sim_cmd_list *client_cmds; { - host_update(ctx->host); - struct host_event_array host_events = host_pop_events(scratch.arena, ctx->host); + host_update(host); + struct host_event_array host_events = host_pop_events(scratch.arena, host); struct sim_cmd_list sim_cmds = ZI; sim_cmds_decode(scratch.arena, host_events, &sim_cmds); @@ -526,20 +523,20 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) for (struct sim_cmd *cmd = sim_cmds.first; cmd; cmd = cmd->next) { enum sim_cmd_kind kind = cmd->kind; struct host_channel_id channel_id = cmd->channel_id; - struct sim_client *client = sim_client_from_channel_id(ctx->world, channel_id); + struct sim_client *client = sim_client_from_channel_id(world, channel_id); if (!client->valid && kind == SIM_CMD_KIND_SIM_CLIENT_CONNECT && !host_channel_id_is_nil(channel_id)) { - client = sim_client_alloc(ctx->world, channel_id); + client = sim_client_alloc(world, channel_id); } } /* Split cmds by client */ - client_cmds = arena_push_array_zero(scratch.arena, struct sim_cmd_list, ctx->world->num_clients_reserved); + client_cmds = arena_push_array_zero(scratch.arena, struct sim_cmd_list, world->num_clients_reserved); { struct sim_cmd *cmd = sim_cmds.first; while (cmd) { struct sim_cmd *next = cmd->next; struct host_channel_id channel_id = cmd->channel_id; - struct sim_client *client = sim_client_from_channel_id(ctx->world, channel_id); + struct sim_client *client = sim_client_from_channel_id(world, channel_id); if (client->valid) { struct sim_cmd_list *cmd_list = &client_cmds[client->handle.idx]; if (cmd_list->last) { @@ -560,9 +557,9 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * ========================== */ /* Process client cmds */ - ctx->oldest_client_ack_tick = ctx->world->tick; - for (u64 i = 0; i < ctx->world->num_clients_reserved; ++i) { - struct sim_client *client = &ctx->world->clients[i]; + u64 oldest_client_ack_tick = world->tick; + for (u64 i = 0; i < world->num_clients_reserved; ++i) { + struct sim_client *client = &world->clients[i]; if (client->valid) { struct host_channel_id channel_id = client->channel_id; struct sim_cmd_list cmds = client_cmds[client->handle.idx]; @@ -626,7 +623,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) /* Clear level */ case SIM_CMD_KIND_CLEAR_ALL: { - test_clear_level(ctx); + test_clear_level(world); } break; /* Spawn test */ @@ -636,14 +633,14 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) u32 count = 1; f32 spread = 1; for (u32 j = 0; j < count; ++j) { - spawn_test_entities(ctx, V2(0, (((f32)j / (f32)count) - 0.5) * spread)); + spawn_test_entities(world, V2(0, (((f32)j / (f32)count) - 0.5) * spread)); } } break; /* Disconnect client */ case SIM_CMD_KIND_SIM_CLIENT_DISCONNECT: { - host_queue_disconnect(ctx->host, channel_id); + host_queue_disconnect(host, channel_id); sim_client_release(client); } break; @@ -651,8 +648,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) }; } - if (client->ack_tick < ctx->oldest_client_ack_tick || ctx->oldest_client_ack_tick == 0) { - ctx->oldest_client_ack_tick = client->ack_tick; + if (client->ack_tick < oldest_client_ack_tick || oldest_client_ack_tick == 0) { + oldest_client_ack_tick = client->ack_tick; } } } @@ -661,21 +658,20 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Create client ents * ========================== */ - ctx->oldest_client_ack_tick = ctx->world->tick; - for (u64 i = 0; i < ctx->world->num_clients_reserved; ++i) { - struct sim_client *client = &ctx->world->clients[i]; + for (u64 i = 0; i < world->num_clients_reserved; ++i) { + struct sim_client *client = &world->clients[i]; if (client->valid) { /* FIXME: Ents never released when client disconnects */ - struct sim_ent *player_ent = sim_ent_from_handle(ctx->world, client->control_ent); + struct sim_ent *player_ent = sim_ent_from_handle(world, client->control_ent); if (!player_ent->valid) { - player_ent = spawn_test_player(ctx); + player_ent = spawn_test_player(world); sim_ent_enable_prop(player_ent, SIM_ENT_PROP_CONTROLLED); client->control_ent = player_ent->handle; player_ent->controlling_client = client->handle; } - struct sim_ent *camera_ent = sim_ent_from_handle(ctx->world, client->camera_ent); + struct sim_ent *camera_ent = sim_ent_from_handle(world, client->camera_ent); if (!camera_ent->valid) { - camera_ent = spawn_test_player_camera(ctx, player_ent); + camera_ent = spawn_test_player_camera(world, player_ent); client->camera_ent = camera_ent->handle; } } @@ -685,12 +681,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Update entity control from client control * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_CONTROLLED)) { - struct sim_client *client = sim_client_from_handle(ctx->world, ent->controlling_client); + struct sim_client *client = sim_client_from_handle(world, ent->controlling_client); if (client->valid) { ent->control = client->control; /* TODO: Move this */ @@ -707,8 +703,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Update entities from sprite * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + struct sim_ent *ent = &world->ents[ent_index]; if (!sim_ent_is_valid_and_active(ent)) continue; if (sprite_tag_is_nil(ent->sprite)) continue; @@ -802,12 +798,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Update attachments * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_ATTACHED)) continue; - struct sim_ent *parent = sim_ent_from_handle(ctx->world, ent->parent); + struct sim_ent *parent = sim_ent_from_handle(world, ent->parent); struct sprite_tag parent_sprite = parent->sprite; struct sprite_sheet *parent_sheet = sprite_sheet_from_tag_await(sprite_frame_scope, parent_sprite); @@ -828,8 +824,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * ========================== */ #if 0 - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_TEST)) continue; @@ -878,12 +874,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Trigger equipped * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_TRIGGERING_EQUIPPED)) { - struct sim_ent *eq = sim_ent_from_handle(ctx->world, ent->equipped); + struct sim_ent *eq = sim_ent_from_handle(world, ent->equipped); if (sim_ent_is_valid_and_active(eq)) { sim_ent_enable_prop(eq, SIM_ENT_PROP_TRIGGERED_THIS_TICK); } @@ -894,13 +890,13 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Process triggered entities * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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 ((sim_time - ent->last_triggered < ent->trigger_delay) && ent->last_triggered != 0) continue; + if ((world_time - ent->last_triggered < ent->trigger_delay) && ent->last_triggered != 0) continue; - ent->last_triggered = sim_time; + ent->last_triggered = world_time; /* Fire weapon */ if (sim_ent_has_prop(ent, SIM_ENT_PROP_WEAPON)) { @@ -958,12 +954,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Create motor joints from control move * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_CONTROLLED)) { - struct sim_ent *joint_ent = sim_ent_from_handle(ctx->world, ent->move_joint); + struct sim_ent *joint_ent = sim_ent_from_handle(world, ent->move_joint); if (!sim_ent_is_valid_and_active(joint_ent)) { joint_ent = sim_ent_alloc(root); joint_ent->mass_unscaled = F32_INFINITY; @@ -991,8 +987,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * ========================== */ #if SIM_PLAYER_AIM - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_CONTROLLED)) { @@ -1000,7 +996,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) struct xform sprite_xf = xform_mul(xf, ent->sprite_local_xform); /* Retrieve / create aim joint */ - struct sim_ent *joint_ent = sim_ent_from_handle(ctx->world, ent->aim_joint); + struct sim_ent *joint_ent = sim_ent_from_handle(world, ent->aim_joint); if (!sim_ent_is_valid_and_active(joint_ent)) { joint_ent = sim_ent_alloc(root); joint_ent->mass_unscaled = F32_INFINITY; @@ -1083,12 +1079,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Create motor joints from ground friction (gravity) * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_PHYSICAL_DYNAMIC)) continue; - struct sim_ent *joint_ent = sim_ent_from_handle(ctx->world, ent->ground_friction_joint); + struct sim_ent *joint_ent = sim_ent_from_handle(world, ent->ground_friction_joint); struct phys_motor_joint_def def = ZI; def.e0 = root->handle; @@ -1111,15 +1107,15 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Create mouse joints from client debug drag * ========================== */ - for (u64 i = 0; i < ctx->world->num_clients_reserved; ++i) { - struct sim_client *client = &ctx->world->clients[i]; + for (u64 i = 0; i < world->num_clients_reserved; ++i) { + struct sim_client *client = &world->clients[i]; if (client->valid) { struct v2 cursor = client->cursor_pos; b32 start_dragging = client->dbg_drag_start; b32 stop_dragging = client->dbg_drag_stop; - struct sim_ent *joint_ent = sim_ent_from_handle(ctx->world, client->dbg_drag_joint_ent); - struct sim_ent *target_ent = sim_ent_from_handle(ctx->world, joint_ent->mouse_joint_data.target); + struct sim_ent *joint_ent = sim_ent_from_handle(world, client->dbg_drag_joint_ent); + struct sim_ent *target_ent = sim_ent_from_handle(world, joint_ent->mouse_joint_data.target); if (start_dragging) { struct xform mouse_xf = xform_from_pos(cursor); @@ -1127,8 +1123,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) mouse_shape.points[0] = V2(0, 0); mouse_shape.count = 1; - for (u64 sim_ent_index = 0; sim_ent_index < ctx->world->num_ents_reserved; ++sim_ent_index) { - struct sim_ent *ent = &ctx->world->ents[sim_ent_index]; + for (u64 sim_ent_index = 0; sim_ent_index < world->num_ents_reserved; ++sim_ent_index) { + struct sim_ent *ent = &world->ents[sim_ent_index]; if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC)) continue; @@ -1183,25 +1179,19 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) { struct phys_ctx phys = ZI; - phys.ss = ctx->world; - phys.space = space; - phys.contact_lookup = &ctx->contact_lookup; + phys.ss = world; phys.pre_solve_callback = on_collision; - phys.pre_solve_callback_udata = ctx; -#if COLLIDER_DEBUG - phys.debug_lookup = &ctx->collision_debug_lookup; -#endif /* Step */ - ctx->last_phys_iteration = phys_step(&phys, world_dt, ctx->last_phys_iteration); + phys_step(&phys, world_dt); } /* ========================== * * Update tracers * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_TRACER)) continue; @@ -1224,13 +1214,13 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Initialize bullet kinematics from sources * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_BULLET)) continue; - if (ent->activation_tick == ctx->world->tick) { - struct sim_ent *src = sim_ent_from_handle(ctx->world, ent->bullet_src); + if (ent->activation_tick == world->tick) { + struct sim_ent *src = sim_ent_from_handle(world, ent->bullet_src); struct xform src_xf = sim_ent_get_xform(src); struct v2 pos = xform_mul_v2(src_xf, ent->bullet_src_pos); @@ -1241,7 +1231,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) /* Add shooter velocity to bullet */ { /* TODO: Add angular velocity as well? */ - struct sim_ent *top = sim_ent_from_handle(ctx->world, src->top); + struct sim_ent *top = sim_ent_from_handle(world, src->top); impulse = v2_add(impulse, v2_mul(top->linear_velocity, dt)); } #endif @@ -1253,7 +1243,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) sim_ent_apply_linear_impulse_to_center(ent, impulse); /* Initialize tracer */ - struct sim_ent *tracer = sim_ent_from_handle(ctx->world, ent->bullet_tracer); + struct sim_ent *tracer = sim_ent_from_handle(world, ent->bullet_tracer); if (sim_ent_is_valid_and_active(tracer)) { sim_ent_set_xform(tracer, xf); sim_ent_enable_prop(tracer, SIM_ENT_PROP_PHYSICAL_KINEMATIC); @@ -1279,8 +1269,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Update cameras * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_CAMERA)) continue; @@ -1288,7 +1278,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) /* Camera follow */ { - struct sim_ent *follow = sim_ent_from_handle(ctx->world, ent->camera_follow); + struct sim_ent *follow = sim_ent_from_handle(world, ent->camera_follow); f32 aspect_ratio = 1.0; { @@ -1320,8 +1310,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) { /* TODO: Update based on distance to quake */ ent->shake = 0; - for (u64 quake_ent_index = 0; quake_ent_index < ctx->world->num_ents_reserved; ++quake_ent_index) { - struct sim_ent *quake = &ctx->world->ents[quake_ent_index]; + for (u64 quake_ent_index = 0; quake_ent_index < world->num_ents_reserved; ++quake_ent_index) { + struct sim_ent *quake = &world->ents[quake_ent_index]; if (!sim_ent_is_valid_and_active(quake)) continue; if (!sim_ent_has_prop(quake, SIM_ENT_PROP_QUAKE)) continue; ent->shake += quake->quake_intensity; @@ -1335,8 +1325,8 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Update quakes * ========================== */ - for (u64 ent_index = 0; ent_index < ctx->world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ctx->world->ents[ent_index]; + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + 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_QUAKE)) continue; @@ -1363,7 +1353,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) --stack_count; i32 parent_layer = parent->final_layer; - for (struct sim_ent *child = sim_ent_from_handle(ctx->world, parent->first); child->valid; child = sim_ent_from_handle(ctx->world, child->next)) { + for (struct sim_ent *child = sim_ent_from_handle(world, parent->first); child->valid; child = sim_ent_from_handle(world, child->next)) { if (sim_ent_is_valid_and_active(child)) { child->final_layer = parent_layer + child->layer; *arena_push(temp.arena, struct sim_ent *) = child; @@ -1379,21 +1369,21 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) * Release entities * ========================== */ - release_entities_with_prop(ctx, SIM_ENT_PROP_RELEASE_THIS_TICK); + release_entities_with_prop(world, SIM_ENT_PROP_RELEASE_THIS_TICK); /* ========================== * * Publish tick * ========================== */ - for (u64 i = 0; i < ctx->world->num_clients_reserved; ++i) { - struct sim_client *client = &ctx->world->clients[i]; + for (u64 i = 0; i < world->num_clients_reserved; ++i) { + struct sim_client *client = &world->clients[i]; if (client->valid) { struct temp_arena temp = arena_temp_begin(scratch.arena); u64 ss0_tick = client->ack_tick; - u64 ss1_tick = ctx->world->tick; - struct sim_snapshot *ss0 = sim_snapshot_from_tick(ctx->snapshot_store, ss0_tick); - struct sim_snapshot *ss1 = ctx->world; + u64 ss1_tick = world->tick; + struct sim_snapshot *ss0 = sim_snapshot_from_tick(snapshot_store, ss0_tick); + struct sim_snapshot *ss1 = world; ss0_tick = ss0->tick; /* In case ack tick is no longer in store we need to do a full resend */ struct sim_event_list l = ZI; @@ -1402,12 +1392,12 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) /* Create & encode snapshot event */ { snapshot_event.kind = SIM_EVENT_KIND_SNAPSHOT; - snapshot_event.tick = ctx->world->tick; + snapshot_event.tick = world->tick; snapshot_event.snapshot_tick_start = ss0_tick; snapshot_event.snapshot_tick_end = ss1_tick; { - struct bitbuff_writer bw = bw_from_bitbuff(&ctx->encoder_bitbuff); + struct bitbuff_writer bw = bw_from_bitbuff(encoder_bitbuff); sim_snapshot_encode(&bw, ss0, ss1, client); snapshot_event.snapshot_encoded = bw_get_written(temp.arena, &bw); } @@ -1423,18 +1413,18 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns) /* Encode events */ struct string events_msg = ZI; { - struct bitbuff_writer bw = bw_from_bitbuff(&ctx->encoder_bitbuff); + struct bitbuff_writer bw = bw_from_bitbuff(encoder_bitbuff); sim_events_encode(&bw, l); events_msg = bw_get_written(temp.arena, &bw); } - host_queue_write(ctx->host, client->channel_id, events_msg, 0); + host_queue_write(host, client->channel_id, events_msg, 0); arena_temp_end(temp); } } - host_update(ctx->host); + host_update(host); __profframe("Sim"); /* ========================== * diff --git a/src/sim.h b/src/sim.h index 782160fc..cadbac14 100644 --- a/src/sim.h +++ b/src/sim.h @@ -122,6 +122,7 @@ struct sim_event_list { * Ctx * ========================== */ +#if 0 struct sim_ctx { struct arena arena; @@ -162,8 +163,12 @@ struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr, u16 host_port); void sim_ctx_release(struct sim_ctx *ctx); +#endif -void sim_update(struct sim_ctx *ctx, i64 target_dt_ns); +struct host; +struct bitbuff; +struct sim_snapshot; +void sim_step(struct host *host, struct bitbuff *encoder_bitbuff, struct sim_snapshot_store *snapshot_store, struct sim_snapshot *prev_snapshot, i64 real_dt_ns, struct sim_cmd_list user_sim_cmds); /* ========================== * * Event & cmd encode/decode diff --git a/src/sim_snapshot.h b/src/sim_snapshot.h index a8be8077..9ef752df 100644 --- a/src/sim_snapshot.h +++ b/src/sim_snapshot.h @@ -4,6 +4,16 @@ #include "sim_ent.h" #include "sim_client.h" + + +/* TODO: Remove this */ +struct space; + + + + + + struct sim_snapshot_store { b32 valid; struct arena arena; @@ -32,6 +42,49 @@ struct sim_snapshot { struct arena arena; + + + + + + /* FIXME: Remove this */ + struct space *space; + + + + + + + + /* FIXME: Encode / decode*/ + + u64 phys_iteration; + + /* This is the oldest tick stored in ctx that we need to hold a reference to for delta encoding */ + u64 oldest_client_ack_tick; + + /* Bookkeeping structures */ + /* TODO: Store in snapshot for determinism */ + struct sim_ent_lookup contact_lookup; +#if COLLIDER_DEBUG + struct sim_ent_lookup collision_debug_lookup; +#endif + + + + + + + + + + + + + + + + /* Real time (increases with clock assuming no lag) */ i64 real_dt_ns; i64 real_time_ns; diff --git a/src/space.h b/src/space.h index 103fc96c..6e6cd421 100644 --- a/src/space.h +++ b/src/space.h @@ -17,7 +17,7 @@ struct space_entry { }; /* Links a cell to a entry. - * Acts as both a list of entries contained by cell & a list of cells containing entry. */ + * Acts as both a node in the list of entries contained by the cell, and a node in the list of cells containing the entry. */ struct space_cell_node { struct space_entry *entry; struct space_cell *cell; diff --git a/src/user.c b/src/user.c index b44e29f7..80d202c6 100644 --- a/src/user.c +++ b/src/user.c @@ -205,6 +205,7 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, sys_window_register_event_callback(G.window, &window_event_callback); /* TODO: Remove this */ +#if 0 connect_address_str = STRING(0, 0); if (connect_address_str.len == 0) { G.local_sim_ctx = sim_ctx_alloc(sprite_sr, phys_sr, host_sr, sim_snapshot_sr, 12345); @@ -213,6 +214,9 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, } else { G.connect_address_str = string_copy(&G.arena, connect_address_str); } +#else + (UNUSED)connect_address_str; +#endif G.debug_draw = true; @@ -228,11 +232,18 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(user_shutdown) atomic_i32_eval_exchange(&G.user_thread_shutdown, true); sys_thread_wait_release(&G.user_thread); +#if 0 if (G.local_sim_ctx) { atomic_i32_eval_exchange(&G.local_sim_thread_shutdown, true); sys_thread_wait_release(&G.local_sim_thread); sim_ctx_release(G.local_sim_ctx); } +#else + if (G.local_sim_ctx) { + atomic_i32_eval_exchange(&G.local_sim_thread_shutdown, true); + sys_thread_wait_release(&G.local_sim_thread); + } +#endif } /* ========================== * @@ -1743,7 +1754,7 @@ INTERNAL void user_update(void) } /* ========================== * - * User thread entry point + * User thread * ========================== */ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg) @@ -1762,14 +1773,61 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg) } /* ========================== * - * Local sim thread entry point + * Local sim thread * ========================== */ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) { + + struct host *host = host_alloc(12345); + struct bitbuff encoder_bitbuff = bitbuff_alloc(GIGABYTE(64)); + struct sim_snapshot_store *ss_store = sim_snapshot_store_alloc(); + + + + + struct sim_ctx *ctx = (struct sim_ctx *)arg; + i64 last_tick_ns = 0; i64 target_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND;; while (!atomic_i32_eval(&G.local_sim_thread_shutdown)) { - sim_update(ctx, target_dt_ns); + { + __profscope(local_sim_sleep); + sleep_frame(last_tick_ns, target_dt_ns); + last_tick_ns = sys_time_ns(); + } + + struct temp_arena scratch = scratch_begin_no_conflict(); + /* Copy user sim cmds */ + struct sim_cmd_list user_sim_cmds = ZI; + { + struct sys_lock lock = sys_mutex_lock_s(&G.user_sim_cmds_arena); + for (struct sim_cmd *cmd = G.user_sim_cmds.first; cmd; cmd = cmd->next) { + struct sim_cmd *dst = arena_push(scratch.arena, struct sim_cmd); + *dst = *cmd; + dst->next = NULL; + if (user_sim_cmds.last) { + user_sim_cmds.last->next = dst; + } else { + user_sim_cmds.first = dst; + } + user_sim_cmds.last = dst; + } + sys_mutex_unlock(&lock); + } + sim_step(host, &encoder_bitbuff, snapshot_store, snapshot, target_dt_ns, user_sim_cmds); + scratch_end(scratch); } + + + + sim_snapshot_store_release(ss_store); + bitbuff_release(&encoder_bitbuff); + host_release(host); + + + + + + }