diff --git a/src/app.c b/src/app.c index 26026454..f9ef1d36 100644 --- a/src/app.c +++ b/src/app.c @@ -223,8 +223,7 @@ void app_entry_point(void) struct sound_startup_receipt sound_sr = sound_startup(&work_sr, &asset_cache_sr, &resource_sr); struct draw_startup_receipt draw_sr = draw_startup(&renderer_sr, &font_sr); struct phys_startup_receipt phys_sr = phys_startup(); - struct sim_startup_receipt sim_sr = sim_startup(&mixer_sr, &sprite_sr, &sound_sr, &phys_sr, &host_sr); - struct user_startup_receipt user_sr = user_startup(&work_sr, &renderer_sr, &font_sr, &sprite_sr, &draw_sr, &sim_sr, &asset_cache_sr, &mixer_sr, &host_sr, &window); + struct user_startup_receipt user_sr = user_startup(&work_sr, &renderer_sr, &font_sr, &sprite_sr, &draw_sr, &asset_cache_sr, &sound_sr, &mixer_sr, &phys_sr, &host_sr, &window); struct playback_startup_receipt playback_sr = playback_startup(&mixer_sr); (UNUSED)user_sr; diff --git a/src/config.h b/src/config.h index 24f3ed08..3c43da26 100644 --- a/src/config.h +++ b/src/config.h @@ -33,7 +33,6 @@ #define SPACE_CELL_BUCKETS_SQRT (256) #define SPACE_CELL_SIZE 1.0f - #define SIM_FPS 50.0 #define SIM_TIMESCALE 1 diff --git a/src/phys.c b/src/phys.c index 1132fdc8..4790194e 100644 --- a/src/phys.c +++ b/src/phys.c @@ -1172,7 +1172,7 @@ u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_phys_iteration) if (ctx->pre_solve_callback) { __profscope(pre_solve_callback); - ctx->pre_solve_callback(collision_data); + ctx->pre_solve_callback(collision_data, ctx->pre_solve_callback_udata); } f32 substep_dt = step_dt / SIM_PHYSICS_SUBSTEPS; @@ -1204,7 +1204,7 @@ u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_phys_iteration) if (ctx->post_solve_callback) { __profscope(post_solve_callback); - ctx->post_solve_callback(collision_data); + ctx->post_solve_callback(collision_data, ctx->post_solve_callback_udata); } scratch_end(scratch); diff --git a/src/phys.h b/src/phys.h index 9a46d489..4d04bdc3 100644 --- a/src/phys.h +++ b/src/phys.h @@ -25,8 +25,8 @@ struct phys_collision_data_array { }; struct phys_collision_data; -#define PHYS_COLLISION_CALLBACK_FUNC_DEF(name, arg) void name(struct phys_collision_data_array arg) -typedef PHYS_COLLISION_CALLBACK_FUNC_DEF(phys_collision_callback_func, 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); /* Structure containing data used for a single physics step */ struct phys_ctx { @@ -37,6 +37,8 @@ struct phys_ctx { 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; struct v2 dbg_cursor_pos; diff --git a/src/sim.c b/src/sim.c index 81ae7e03..9b4bee28 100644 --- a/src/sim.c +++ b/src/sim.c @@ -1,12 +1,11 @@ #include "sim.h" #include "sim_ent.h" #include "sim_client.h" +#include "sim_msg.h" #include "sys.h" #include "util.h" #include "world.h" #include "sprite.h" -#include "sound.h" -#include "mixer.h" #include "math.h" #include "scratch.h" #include "atomic.h" @@ -19,7 +18,8 @@ #include "byteio.h" #include "host.h" -GLOBAL struct { +struct sim_ctx { + struct arena arena; struct atomic_i32 sim_thread_shutdown; struct sys_thread sim_thread; @@ -48,76 +48,75 @@ GLOBAL struct { /* Tick */ struct world tick; -} G = ZI, DEBUG_ALIAS(G, G_sim); +}; /* ========================== * - * Startup + * Ctx * ========================== */ -INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(sim_shutdown); INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sim_thread_entry_point, arg); -INTERNAL void reset_world(void); +INTERNAL void reset_world(struct sim_ctx *ctx); -struct sim_startup_receipt sim_startup(struct mixer_startup_receipt *mixer_sr, - struct sprite_startup_receipt *sheet_sr, - struct sound_startup_receipt *sound_sr, - struct phys_startup_receipt *phys_sr, - struct host_startup_receipt *host_sr) +struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr, + struct phys_startup_receipt *phys_sr, + struct host_startup_receipt *host_sr, + u16 host_port) { - (UNUSED)mixer_sr; - (UNUSED)sheet_sr; - (UNUSED)sound_sr; + struct arena arena = arena_alloc(GIGABYTE(64)); + struct sim_ctx *ctx = arena_push_zero(&arena, struct sim_ctx); + ctx->arena = arena; + + (UNUSED)sprite_sr; (UNUSED)phys_sr; (UNUSED)host_sr; - G.client_store = client_store_alloc(); + ctx->client_store = sim_client_store_alloc(); /* Intialize host */ - G.host = host_alloc(12345); + ctx->host = host_alloc(host_port); /* Initialize empty world */ - reset_world(); + reset_world(ctx); - G.sim_thread = sys_thread_alloc(&sim_thread_entry_point, NULL, LIT("[P2] Sim thread")); - app_register_exit_callback(&sim_shutdown); + ctx->sim_thread = sys_thread_alloc(&sim_thread_entry_point, ctx, LIT("[P2] Sim thread")); - return (struct sim_startup_receipt) { 0 }; + return ctx; } -INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(sim_shutdown) +void sim_ctx_release(struct sim_ctx *ctx) { __prof; - atomic_i32_eval_exchange(&G.sim_thread_shutdown, true); - sys_thread_wait_release(&G.sim_thread); + atomic_i32_eval_exchange(&ctx->sim_thread_shutdown, true); + sys_thread_wait_release(&ctx->sim_thread); } /* ========================== * * Reset * ========================== */ -INTERNAL void reset_world(void) +INTERNAL void reset_world(struct sim_ctx *ctx) { - if (G.tick.ent_store) { + if (ctx->tick.ent_store) { /* Release world */ - world_release(&G.tick); + world_release(&ctx->tick); /* Release bookkeeping */ - space_release(G.space); + space_release(ctx->space); #if COLLIDER_DEBUG - sim_ent_lookup_release(&G.collision_debug_lookup); + sim_ent_lookup_release(&ctx->collision_debug_lookup); #endif - sim_ent_lookup_release(&G.contact_lookup); + sim_ent_lookup_release(&ctx->contact_lookup); } /* Create bookkeeping */ - G.contact_lookup = sim_ent_lookup_alloc(4096); + ctx->contact_lookup = sim_ent_lookup_alloc(4096); #if COLLIDER_DEBUG - G.collision_debug_lookup = sim_ent_lookup_alloc(4096); + ctx->collision_debug_lookup = sim_ent_lookup_alloc(4096); #endif - G.space = space_alloc(SPACE_CELL_SIZE, SPACE_CELL_BUCKETS_SQRT); + ctx->space = space_alloc(SPACE_CELL_SIZE, SPACE_CELL_BUCKETS_SQRT); /* Re-create world */ - world_alloc(&G.tick); - G.tick.timescale = SIM_TIMESCALE; + world_alloc(&ctx->tick); + ctx->tick.timescale = SIM_TIMESCALE; } /* ========================== * @@ -126,15 +125,15 @@ INTERNAL void reset_world(void) /* TODO: Remove this */ -INTERNAL void spawn_test_entities(void) +INTERNAL void spawn_test_entities(struct sim_ctx *ctx) { - struct sim_ent *root = sim_ent_from_handle(G.tick.ent_store, G.tick.ent_store->root); + struct sim_ent *root = sim_ent_from_handle(ctx->tick.ent_store, ctx->tick.ent_store->root); root->mass_unscaled = F32_INFINITY; root->inertia_unscaled = F32_INFINITY; /* Player */ struct sim_ent *player_ent = sim_ent_nil(); - //if (!G.extra_spawn) { + //if (!ctx->extra_spawn) { { struct sim_ent *e = sim_ent_alloc(root); @@ -148,7 +147,7 @@ INTERNAL void spawn_test_entities(void) //f32 r = PI / 4; f32 r = 0; - if (!G.extra_spawn) { + if (!ctx->extra_spawn) { sim_ent_enable_prop(e, SIM_ENT_PROP_PLAYER_CONTROLLED); sim_ent_enable_prop(e, SIM_ENT_PROP_TEST); e->sprite = sprite_tag_from_path(LIT("res/graphics/tim.ase")); @@ -280,7 +279,7 @@ INTERNAL void spawn_test_entities(void) } /* Camera */ - if (!G.extra_spawn && player_ent->valid) { + if (!ctx->extra_spawn && player_ent->valid) { struct sim_ent *e = sim_ent_alloc(root); sim_ent_set_xform(e, XFORM_IDENT); @@ -293,18 +292,18 @@ INTERNAL void spawn_test_entities(void) e->camera_quad_xform = XFORM_TRS(.s = V2(width, height)); } - G.extra_spawn = true; + ctx->extra_spawn = true; } /* ========================== * * Release entities * ========================== */ -INTERNAL void release_entities_with_prop(enum sim_ent_prop prop) +INTERNAL void release_entities_with_prop(struct sim_ctx *ctx, enum sim_ent_prop prop) { struct temp_arena scratch = scratch_begin_no_conflict(); - struct sim_ent_store *store = G.tick.ent_store; - struct space *space = G.space; + struct sim_ent_store *store = ctx->tick.ent_store; + struct space *space = ctx->space; struct sim_ent **ents_to_release = arena_dry_push(scratch.arena, struct sim_ent *); u64 ents_to_release_count = 0; @@ -347,13 +346,14 @@ INTERNAL void release_entities_with_prop(enum sim_ent_prop prop) * Respond to physics collisions * ========================== */ -INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array) +INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, udata) { - struct sim_ent_store *store = G.tick.ent_store; + struct sim_ctx *ctx = (struct sim_ctx *)udata; + struct sim_ent_store *store = ctx->tick.ent_store; struct sim_ent *root = sim_ent_from_handle(store, store->root); - for (u64 i = 0; i < array.count; ++i) { - struct phys_collision_data *data = &array.a[i]; + 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(store, data->e0); @@ -434,7 +434,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array) * Update * ========================== */ -INTERNAL void sim_update(void) +INTERNAL void sim_update(struct sim_ctx *ctx) { __prof; @@ -444,31 +444,31 @@ INTERNAL void sim_update(void) * Reset level if necessary * ========================== */ - if (G.should_reset_level) { + if (ctx->should_reset_level) { logf_info("Clearing level"); - G.should_reset_level = false; - G.extra_spawn = false; - reset_world(); + ctx->should_reset_level = false; + ctx->extra_spawn = false; + reset_world(ctx); } /* ========================== * * Begin frame * ========================== */ - ++G.tick.tick_id; + ++ctx->tick.tick_id; - G.tick.dt_ns = NS_FROM_SECONDS(max_f64(0.0, (1.0 / SIM_FPS) * G.tick.timescale)); - G.tick.time_ns += G.tick.dt_ns; + ctx->tick.dt_ns = NS_FROM_SECONDS(max_f64(0.0, (1.0 / SIM_FPS) * ctx->tick.timescale)); + ctx->tick.time_ns += ctx->tick.dt_ns; - f64 dt = SECONDS_FROM_NS(G.tick.dt_ns); - f64 time = SECONDS_FROM_NS(G.tick.time_ns); - G.sprite_frame_scope = sprite_scope_begin(); - G.root = sim_ent_from_handle(G.tick.ent_store, G.tick.ent_store->root); + f64 dt = SECONDS_FROM_NS(ctx->tick.dt_ns); + f64 time = SECONDS_FROM_NS(ctx->tick.time_ns); + ctx->sprite_frame_scope = sprite_scope_begin(); + ctx->root = sim_ent_from_handle(ctx->tick.ent_store, ctx->tick.ent_store->root); - struct sim_ent *root = G.root; - struct sim_ent_store *ent_store = G.tick.ent_store; - struct space *space = G.space; - struct sprite_scope *sprite_frame_scope = G.sprite_frame_scope; + struct sim_ent *root = ctx->root; + struct sim_ent_store *ent_store = ctx->tick.ent_store; + struct space *space = ctx->space; + struct sprite_scope *sprite_frame_scope = ctx->sprite_frame_scope; (UNUSED)dt; (UNUSED)time; @@ -483,7 +483,7 @@ INTERNAL void sim_update(void) static b32 run = 0; if (!run) { run = 1; - spawn_test_entities(); + spawn_test_entities(ctx); } } @@ -491,7 +491,7 @@ INTERNAL void sim_update(void) * Release entities * ========================== */ - release_entities_with_prop(SIM_ENT_PROP_RELEASE_NEXT_TICK); + release_entities_with_prop(ctx, SIM_ENT_PROP_RELEASE_NEXT_TICK); /* ========================== * * Activate entities @@ -503,8 +503,8 @@ INTERNAL void sim_update(void) if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ACTIVE)) { u64 atick = ent->activation_tick; - if (atick != 0 || G.tick.tick_id >= atick) { - sim_ent_activate(ent, G.tick.tick_id); + if (atick != 0 || ctx->tick.tick_id >= atick) { + sim_ent_activate(ent, ctx->tick.tick_id); } } } @@ -532,7 +532,7 @@ INTERNAL void sim_update(void) struct sim_cmd_list sim_cmds = ZI; { - struct host_event_array host_events = host_pop_events(scratch.arena, G.host); + struct host_event_array host_events = host_pop_events(scratch.arena, ctx->host); sim_cmds_from_host_events(scratch.arena, host_events, &sim_cmds); } @@ -544,26 +544,26 @@ INTERNAL void sim_update(void) enum sim_cmd_kind kind = cmd->kind; struct host_channel_id channel_id = cmd->channel_id; - struct sim_client *client = client_from_channel_id(G.client_store, channel_id); + struct sim_client *client = sim_client_from_channel_id(ctx->client_store, channel_id); if (client->valid || host_channel_id_is_nil(channel_id)) { switch (kind) { /* Cursor */ case SIM_CMD_KIND_CURSOR_MOVE: { - G.user_cursor = cmd->cursor_pos; + ctx->user_cursor = cmd->cursor_pos; } break; /* Clear level */ case SIM_CMD_KIND_CLEAR_ALL: { - G.should_reset_level = true; + ctx->should_reset_level = true; } break; /* Spawn test */ case SIM_CMD_KIND_SPAWN_TEST: { logf_info("Spawning (test)"); - spawn_test_entities(); + spawn_test_entities(ctx); } break; /* Disconnect client */ @@ -574,9 +574,9 @@ INTERNAL void sim_update(void) if (client_ent->valid) { sim_ent_disable_prop(client_ent, SIM_ENT_PROP_PLAYER_CONTROLLED); sim_ent_enable_prop(client_ent, SIM_ENT_PROP_RELEASE_NEXT_TICK); - host_queue_disconnect(G.host, channel_id); + host_queue_disconnect(ctx->host, channel_id); } - client_release(client); + sim_client_release(client); } } break; @@ -584,7 +584,7 @@ INTERNAL void sim_update(void) }; } else if (kind == SIM_CMD_KIND_SIM_CLIENT_CONNECT && !host_channel_id_is_nil(channel_id) && !client->valid) { /* Connect client */ - client = client_alloc(G.client_store, channel_id); + client = sim_client_alloc(ctx->client_store, channel_id); struct sim_ent *client_ent = sim_ent_alloc(root); sim_ent_enable_prop(client_ent, SIM_ENT_PROP_PLAYER_CONTROLLED); client_ent->controlling_client = client->handle; @@ -676,7 +676,7 @@ INTERNAL void sim_update(void) #endif ent->local_collider.count = 3; ent->local_collider.radius = 0.25; - //ent->local_collider.radius = math_fabs(math_sin(G.tick.time) / 3); + //ent->local_collider.radius = math_fabs(math_sin(ctx->tick.time) / 3); #else //ent->local_collider.radius = 0.5; ent->local_collider.radius = 0.25; @@ -729,7 +729,7 @@ INTERNAL void sim_update(void) b32 start = cmd->state == SIM_CMD_STATE_START; b32 stop = cmd->state == SIM_CMD_STATE_STOP; - /* TODO: Combine movement from multiple inputs? E.G. a sudden + /* TODO: Combine movement from multiple inputs? E.ctx-> a sudden * start and immediate stop cmd should still move the player a * tad. */ switch (cmd->kind) { @@ -1071,30 +1071,31 @@ INTERNAL void sim_update(void) * ========================== */ { - struct phys_ctx ctx = ZI; - ctx.tick_id = G.tick.tick_id; - ctx.store = ent_store; - ctx.space = space; - ctx.contact_lookup = &G.contact_lookup; - ctx.pre_solve_callback = on_collision; + struct phys_ctx phys = ZI; + phys.tick_id = ctx->tick.tick_id; + phys.store = ent_store; + phys.space = space; + phys.contact_lookup = &ctx->contact_lookup; + phys.pre_solve_callback = on_collision; + phys.pre_solve_callback_udata = ctx; #if COLLIDER_DEBUG - ctx.debug_lookup = &G.collision_debug_lookup; + phys.debug_lookup = &phys->collision_debug_lookup; #endif /* Mouse drag */ - ctx.dbg_cursor_pos = G.user_cursor; + phys.dbg_cursor_pos = ctx->user_cursor; for (struct sim_cmd *cmd = sim_cmds.first; cmd; cmd = cmd->next) { if (cmd->kind == SIM_CMD_KIND_DRAG_OBJECT) { if (cmd->state == SIM_CMD_STATE_START) { - ctx.dbg_start_dragging = true; + phys.dbg_start_dragging = true; } else if (cmd->state == SIM_CMD_STATE_STOP) { - ctx.dbg_stop_dragging = true; + phys.dbg_stop_dragging = true; } } } /* Step */ - G.last_phys_iteration = phys_step(&ctx, dt, G.last_phys_iteration); + ctx->last_phys_iteration = phys_step(&phys, dt, ctx->last_phys_iteration); } /* ========================== * @@ -1130,7 +1131,7 @@ INTERNAL void sim_update(void) if (!sim_ent_is_valid_and_active(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_BULLET)) continue; - if (ent->activation_tick == G.tick.tick_id) { + if (ent->activation_tick == ctx->tick.tick_id) { struct sim_ent *src = sim_ent_from_handle(ent_store, ent->bullet_src); struct xform src_xf = sim_ent_get_xform(src); @@ -1276,6 +1277,7 @@ INTERNAL void sim_update(void) arena_temp_end(temp); } +#if 0 /* ========================== * * Update sound emitters * ========================== */ @@ -1290,7 +1292,7 @@ INTERNAL void sim_update(void) if (sim_ent_has_prop(ent, SIM_ENT_PROP_TEST_SOUND_EMITTER)) { struct mixer_desc desc = ent->sound_desc; - desc.speed = G.tick.timescale; + desc.speed = ctx->tick.timescale; desc.pos = sim_ent_get_xform(ent).og; struct sound *sound = sound_load_async(ent->sound_name, 0); @@ -1304,12 +1306,13 @@ INTERNAL void sim_update(void) } } } +#endif /* ========================== * * Release entities * ========================== */ - release_entities_with_prop(SIM_ENT_PROP_RELEASE_THIS_TICK); + release_entities_with_prop(ctx, SIM_ENT_PROP_RELEASE_THIS_TICK); /* ========================== * * Publish tick @@ -1321,19 +1324,19 @@ INTERNAL void sim_update(void) /* TODO: Not like this */ struct sim_event snapshot_event = ZI; snapshot_event.kind = SIM_EVENT_KIND_SNAPSHOT_FULL; - snapshot_event.snapshot_data = sim_string_from_tick(temp.arena, &G.tick); + snapshot_event.snapshot_data = sim_string_from_tick(temp.arena, &ctx->tick); struct sim_event_list l = ZI; l.first = &snapshot_event; l.last = &snapshot_event; struct string msg = sim_string_from_events(temp.arena, l); - host_queue_write(G.host, HOST_CHANNEL_ID_ALL, msg, 0); + host_queue_write(ctx->host, HOST_CHANNEL_ID_ALL, msg, 0); arena_temp_end(temp); } - host_update(G.host); + host_update(ctx->host); __profframe("Sim"); /* ========================== * @@ -1345,281 +1348,19 @@ INTERNAL void sim_update(void) scratch_end(scratch); } -/* ========================== * - * Sim cmd - * ========================== */ - -struct string sim_string_from_cmds(struct arena *arena, struct sim_cmd_list cmds) -{ - __prof; - struct byte_writer bw = bw_from_arena(arena); - - for (struct sim_cmd *cmd = cmds.first; cmd; cmd = cmd->next) { - struct byte_writer bw_size = bw_branch(&bw, sizeof(u64)); - u64 start = bw_pos(&bw); - - bw_write_i8(&bw, cmd->kind); - bw_write_i8(&bw, cmd->state); - -#if COLLIDER_DEBUG - bw_write_u32(&bw, cmd->collider_gjk_steps); -#endif - - switch (cmd->kind) { - case SIM_CMD_KIND_PLAYER_MOVE: - { - bw_write_v2(&bw, cmd->move_dir); - bw_write_v2(&bw, cmd->aim_dir); - } break; - - case SIM_CMD_KIND_CURSOR_MOVE: - { - bw_write_v2(&bw, cmd->cursor_pos); - } break; - - default: break; - } - - u64 size = bw_pos(&bw) - start; - bw_write_u64(&bw_size, size); - } - - return bw_get_written(&bw); -} - -void sim_cmds_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_cmd_list *cmds_out) -{ - __prof; - for (u64 i = 0; i < host_events.count; ++i) { - struct host_event host_event = host_events.events[i]; - enum host_event_kind host_event_kind = host_event.kind; - switch (host_event_kind) { - case HOST_EVENT_KIND_CHANNEL_OPENED: - { - struct sim_cmd *cmd = arena_push_zero(arena, struct sim_cmd); - cmd->kind = SIM_CMD_KIND_SIM_CLIENT_CONNECT; - cmd->channel_id = host_event.channel_id; - if (cmds_out->last) { - cmds_out->last->next = cmd; - } else { - cmds_out->first = cmd; - } - cmds_out->last = cmd; - } break; - - case HOST_EVENT_KIND_CHANNEL_CLOSED: - { - struct sim_cmd *cmd = arena_push_zero(arena, struct sim_cmd); - cmd->kind = SIM_CMD_KIND_SIM_CLIENT_DISCONNECT; - cmd->disconnect_reason = LIT("Connection lost"); - if (cmds_out->last) { - cmds_out->last->next = cmd; - } else { - cmds_out->first = cmd; - } - cmds_out->last = cmd; - } break; - - case HOST_EVENT_KIND_MSG: - { - struct byte_reader br = br_from_buffer(host_event.msg); - while (br_bytes_left(&br) > 0) { - struct sim_cmd *cmd = arena_push_zero(arena, struct sim_cmd); - u64 cmd_size = br_read_u64(&br); - u64 cmd_pos_end = br_pos(&br) + cmd_size; - cmd->kind = br_read_i8(&br); - cmd->state = br_read_i8(&br); -#if COLLIDER_DEBUG - cmd->collider_gjk_steps = br_read_u32(&br); -#endif - - switch (cmd->kind) { - case SIM_CMD_KIND_PLAYER_MOVE: - { - cmd->move_dir = br_read_v2(&br); - cmd->aim_dir = br_read_v2(&br); - } break; - - case SIM_CMD_KIND_CURSOR_MOVE: - { - cmd->cursor_pos = br_read_v2(&br); - } break; - - default: break; - } - - ASSERT(br_pos(&br) == cmd_pos_end); - br_seek_to(&br, cmd_pos_end); - - if (cmds_out->last) { - cmds_out->last->next = cmd; - } else { - cmds_out->first = cmd; - } - cmds_out->last = cmd; - } - } break; - - default: break; - } - } -} - -/* ========================== * - * Sim event - * ========================== */ - -struct string sim_string_from_events(struct arena *arena, struct sim_event_list events) -{ - __prof; - struct byte_writer bw = bw_from_arena(arena); - for (struct sim_event *event = events.first; event; event = event->next) { - struct byte_writer bw_size = bw_branch(&bw, sizeof(u64)); - u64 start = bw_pos(&bw); - bw_write_i8(&bw, event->kind); - - switch (event->kind) { - case SIM_EVENT_KIND_SNAPSHOT_FULL: - { - bw_write_string(&bw, event->snapshot_data); - } break; - - default: break; - } - - u64 size = bw_pos(&bw) - start; - bw_write_u64(&bw_size, size); - } - return bw_get_written(&bw); -} - -void sim_events_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_event_list *events_out) -{ - __prof; - for (u64 i = 0; i < host_events.count; ++i) { - struct sim_event *sim_event = arena_push_zero(arena, struct sim_event); - struct host_event host_event = host_events.events[i]; - enum host_event_kind host_event_kind = host_event.kind; - sim_event->channel_id = host_event.channel_id; - switch (host_event_kind) { - case HOST_EVENT_KIND_CHANNEL_OPENED: - { - sim_event->kind = SIM_EVENT_KIND_CONNECT; - } break; - - case HOST_EVENT_KIND_CHANNEL_CLOSED: - { - sim_event->kind = SIM_EVENT_KIND_DISCONNECT; - sim_event->disconnect_reason = LIT("Connection lost"); - } break; - - case HOST_EVENT_KIND_MSG: - { - struct byte_reader br = br_from_buffer(host_event.msg); - while (br_bytes_left(&br) > 0) { - u64 event_size = br_read_u64(&br); - u64 event_pos_end = br_pos(&br) + event_size; - - sim_event->kind = br_read_i8(&br); - switch (sim_event->kind) { - case SIM_EVENT_KIND_SNAPSHOT_FULL: - { - sim_event->snapshot_data = br_read_string(arena, &br); - } break; - - default: break; - } - - ASSERT(br_pos(&br) == event_pos_end); - br_seek_to(&br, event_pos_end); - } - } break; - - default: break; - } - - if (events_out->last) { - events_out->last->next = sim_event; - } else { - events_out->first = sim_event; - } - events_out->last = sim_event; - } -} - -/* ========================== * - * Snapshot - * ========================== */ - -struct string sim_string_from_tick(struct arena *arena, struct world *tick) -{ - __prof; - struct byte_writer bw = bw_from_arena(arena); - - bw_write_var_uint(&bw, tick->continuity_gen); - bw_write_var_uint(&bw, tick->tick_id); - bw_write_var_sint(&bw, tick->publishtime_ns); - - bw_write_f64(&bw, tick->timescale); - bw_write_var_sint(&bw, tick->dt_ns); - bw_write_var_sint(&bw, tick->time_ns); - - u64 num_entities = tick->ent_store->num_reserved; - bw_write_var_uint(&bw, num_entities); - - struct string entities_src = ZI; - entities_src.text = (u8 *)tick->ent_store->entities; - entities_src.len = sizeof(struct sim_ent) * num_entities; - br_write_bytes(&bw, entities_src); - - return bw_get_written(&bw); -} - -void sim_tick_from_string(struct string str, struct world *tick_out) -{ - __prof; - struct byte_reader br = br_from_buffer(str); - - tick_out->continuity_gen = br_read_var_uint(&br); - tick_out->tick_id = br_read_var_uint(&br); - tick_out->publishtime_ns = br_read_var_sint(&br); - - tick_out->timescale = br_read_f64(&br); - tick_out->dt_ns = br_read_var_sint(&br); - tick_out->time_ns = br_read_var_sint(&br); - - u64 num_entities = br_read_var_uint(&br); - arena_push_array(&tick_out->ent_store->arena, struct sim_ent, num_entities - tick_out->ent_store->num_reserved); - tick_out->ent_store->num_reserved = num_entities; - - tick_out->ent_store->num_allocated = 0; - struct sim_ent *entities_src = br_seek(&br, num_entities * sizeof(struct sim_ent)); - if (entities_src) { - for (u64 i = 0; i < num_entities; ++i) { - struct sim_ent *src = &entities_src[i]; - struct sim_ent *dst = &tick_out->ent_store->entities[i]; - if (dst->valid) { - ++tick_out->ent_store->num_allocated; - } - *dst = *src; - } - } -} - /* ========================== * * Sim thread * ========================== */ - INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sim_thread_entry_point, arg) { - (UNUSED)arg; + struct sim_ctx *ctx = (struct sim_ctx *)arg; i64 last_frame_ns = 0; i64 target_dt_ns = NS_FROM_SECONDS(SIM_FPS > (0) ? (1.0 / SIM_FPS) : 0); - while (!atomic_i32_eval(&G.sim_thread_shutdown)) { + while (!atomic_i32_eval(&ctx->sim_thread_shutdown)) { __profscope(sim_update_w_sleep); sleep_frame(last_frame_ns, target_dt_ns); last_frame_ns = sys_time_ns(); - sim_update(); + sim_update(ctx); } } diff --git a/src/sim.h b/src/sim.h index 19e42f51..372afaca 100644 --- a/src/sim.h +++ b/src/sim.h @@ -1,12 +1,8 @@ #ifndef SIM_H #define SIM_H -#include "host.h" - -struct world; -struct mixer_startup_receipt; +struct sim_ctx; struct sprite_startup_receipt; -struct sound_startup_receipt; struct phys_startup_receipt; struct host_startup_receipt; @@ -20,116 +16,13 @@ struct host_startup_receipt; #define SIM_LAYER_RELATIVE_DEFAULT 0 #define SIM_LAYER_RELATIVE_WEAPON 1 -struct sim_startup_receipt { i32 _; }; -struct sim_startup_receipt sim_startup(struct mixer_startup_receipt *mixer_sr, - struct sprite_startup_receipt *sheet_sr, - struct sound_startup_receipt *sound_sr, - struct phys_startup_receipt *phys_sr, - struct host_startup_receipt *host_sr); +/* TODO: Get rid of startup receipts */ +struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr, + struct phys_startup_receipt *phys_sr, + struct host_startup_receipt *host_sr, + u16 host_port); +void sim_ctx_release(struct sim_ctx *ctx); -/* ========================== * - * Sim cmd - * ========================== */ - -enum sim_cmd_state { - SIM_CMD_STATE_STOP = -1, - SIM_CMD_STATE_NO_CHANGE = 0, - SIM_CMD_STATE_START = 1 -}; - -enum sim_cmd_kind { - SIM_CMD_KIND_NONE, - - SIM_CMD_KIND_PLAYER_MOVE, - SIM_CMD_KIND_PLAYER_FIRE, - - SIM_CMD_KIND_SIM_CLIENT_CONNECT, - SIM_CMD_KIND_SIM_CLIENT_DISCONNECT, - - /* Testing */ - SIM_CMD_KIND_CLEAR_ALL, - SIM_CMD_KIND_SPAWN_TEST, - SIM_CMD_KIND_PAUSE, - SIM_CMD_KIND_STEP, - SIM_CMD_KIND_DRAG_OBJECT, - SIM_CMD_KIND_CURSOR_MOVE, - - SIM_CMD_KIND_COUNT -}; - -struct sim_cmd { - enum sim_cmd_kind kind; - enum sim_cmd_state state; - struct host_channel_id channel_id; - - /* SIM_CMD_KIND_PLAYER_MOVE */ - struct v2 move_dir; - struct v2 aim_dir; - - /* SIM_CMD_KIND_CURSOR_MOVE */ - struct v2 cursor_pos; - - /* SIM_CMD_KIND_PLAYER_DISCONNECT */ - struct string disconnect_reason; - -#if RTC - u32 collider_gjk_steps; -#endif - - struct sim_cmd *next; -}; - -struct sim_cmd_list { - struct sim_cmd *first; - struct sim_cmd *last; -}; - -struct string sim_string_from_cmds(struct arena *arena, struct sim_cmd_list cmds); -void sim_cmds_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_cmd_list *cmds_out); - -/* ========================== * - * Sim event - * ========================== */ - -enum sim_event_kind { - SIM_EVENT_KIND_NONE, - - SIM_EVENT_KIND_CONNECT, - SIM_EVENT_KIND_DISCONNECT, - SIM_EVENT_KIND_SNAPSHOT_FULL, - - //SIM_EVENT_KIND_ENTITY_UPDATE, - //SIM_EVENT_KIND_ENTITY_CREATE, - //SIM_EVENT_KIND_ENTITY_DESTROY -}; - -struct sim_event { - enum sim_event_kind kind; - struct host_channel_id channel_id; - - struct string snapshot_data; - struct string disconnect_reason; - - //struct sim_ent_handle entity; - //struct string update_data; - - struct sim_event *next; -}; - -struct sim_event_list { - struct sim_event *first; - struct sim_event *last; -}; - -struct string sim_string_from_events(struct arena *arena, struct sim_event_list events); -void sim_events_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_event_list *events_out); - -/* ========================== * - * Snapshot - * ========================== */ - -struct string sim_string_from_tick(struct arena *arena, struct world *tick); -void sim_tick_from_string(struct string str, struct world *tick_out); #endif diff --git a/src/sim_client.c b/src/sim_client.c index 15312a06..f13cc23f 100644 --- a/src/sim_client.c +++ b/src/sim_client.c @@ -17,7 +17,7 @@ READONLY struct sim_client_store _g_sim_client_store_nil = { .valid = false }; * Store * ========================== */ -struct sim_client_store *client_store_alloc(void) +struct sim_client_store *sim_client_store_alloc(void) { struct arena arena = arena_alloc(GIGABYTE(64)); u64 num_channel_lookup_buckets = CHANNEL_LOOKUP_BUCKETS; @@ -34,7 +34,7 @@ struct sim_client_store *client_store_alloc(void) return store; } -void client_store_release(struct sim_client_store *store) +void sim_client_store_release(struct sim_client_store *store) { arena_release(&store->arena); } @@ -60,7 +60,7 @@ INTERNAL u64 hash_from_channel_id(struct host_channel_id channel_id) return hash_fnv64(HASH_FNV64_BASIS, STRING_FROM_STRUCT(&channel_id)); } -struct sim_client *client_from_handle(struct sim_client_store *store, struct client_handle handle) +struct sim_client *sim_client_from_handle(struct sim_client_store *store, struct client_handle handle) { if (handle.gen != 0 && handle.idx < store->clients_reserved) { struct sim_client *client = &store->clients[handle.idx]; @@ -71,7 +71,7 @@ struct sim_client *client_from_handle(struct sim_client_store *store, struct cli return client_nil(); } -struct sim_client *client_from_channel_id(struct sim_client_store *store, struct host_channel_id channel_id) +struct sim_client *sim_client_from_channel_id(struct sim_client_store *store, struct host_channel_id channel_id) { struct sim_client *res = client_nil(); u64 channel_hash = hash_from_channel_id(channel_id); @@ -86,7 +86,7 @@ struct sim_client *client_from_channel_id(struct sim_client_store *store, struct return res; } -struct sim_client *client_alloc(struct sim_client_store *store, struct host_channel_id channel_id) +struct sim_client *sim_client_alloc(struct sim_client_store *store, struct host_channel_id channel_id) { struct sim_client *client = NULL; struct client_handle handle = ZI; @@ -122,7 +122,7 @@ struct sim_client *client_alloc(struct sim_client_store *store, struct host_chan return client; } -void client_release(struct sim_client *client) +void sim_client_release(struct sim_client *client) { struct sim_client_store *store = client_store_from_client(client); client->valid = false; diff --git a/src/sim_client.h b/src/sim_client.h index c5c22a3e..c82fde87 100644 --- a/src/sim_client.h +++ b/src/sim_client.h @@ -50,12 +50,12 @@ INLINE struct sim_client_store *client_store_nil(void) return &_g_sim_client_store_nil; } -struct sim_client_store *client_store_alloc(void); -void client_store_release(struct sim_client_store *store); +struct sim_client_store *sim_client_store_alloc(void); +void sim_client_store_release(struct sim_client_store *store); struct sim_client_store *client_store_from_client(struct sim_client *client); -struct sim_client *client_from_handle(struct sim_client_store *store, struct client_handle handle); -struct sim_client *client_from_channel_id(struct sim_client_store *store, struct host_channel_id channel_id); -struct sim_client *client_alloc(struct sim_client_store *store, struct host_channel_id channel_id); -void client_release(struct sim_client *client); +struct sim_client *sim_client_from_handle(struct sim_client_store *store, struct client_handle handle); +struct sim_client *sim_client_from_channel_id(struct sim_client_store *store, struct host_channel_id channel_id); +struct sim_client *sim_client_alloc(struct sim_client_store *store, struct host_channel_id channel_id); +void sim_client_release(struct sim_client *client); #endif diff --git a/src/sim_msg.c b/src/sim_msg.c new file mode 100644 index 00000000..d93de2b9 --- /dev/null +++ b/src/sim_msg.c @@ -0,0 +1,265 @@ +#include "sim_msg.h" +#include "arena.h" +#include "byteio.h" +#include "world.h" + +/* ========================== * + * Sim cmd + * ========================== */ + +struct string sim_string_from_cmds(struct arena *arena, struct sim_cmd_list cmds) +{ + __prof; + struct byte_writer bw = bw_from_arena(arena); + + for (struct sim_cmd *cmd = cmds.first; cmd; cmd = cmd->next) { + struct byte_writer bw_size = bw_branch(&bw, sizeof(u64)); + u64 start = bw_pos(&bw); + + bw_write_i8(&bw, cmd->kind); + bw_write_i8(&bw, cmd->state); + +#if COLLIDER_DEBUG + bw_write_u32(&bw, cmd->collider_gjk_steps); +#endif + + switch (cmd->kind) { + case SIM_CMD_KIND_PLAYER_MOVE: + { + bw_write_v2(&bw, cmd->move_dir); + bw_write_v2(&bw, cmd->aim_dir); + } break; + + case SIM_CMD_KIND_CURSOR_MOVE: + { + bw_write_v2(&bw, cmd->cursor_pos); + } break; + + default: break; + } + + u64 size = bw_pos(&bw) - start; + bw_write_u64(&bw_size, size); + } + + return bw_get_written(&bw); +} + +void sim_cmds_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_cmd_list *cmds_out) +{ + __prof; + for (u64 i = 0; i < host_events.count; ++i) { + struct host_event host_event = host_events.events[i]; + enum host_event_kind host_event_kind = host_event.kind; + switch (host_event_kind) { + case HOST_EVENT_KIND_CHANNEL_OPENED: + { + struct sim_cmd *cmd = arena_push_zero(arena, struct sim_cmd); + cmd->kind = SIM_CMD_KIND_SIM_CLIENT_CONNECT; + cmd->channel_id = host_event.channel_id; + if (cmds_out->last) { + cmds_out->last->next = cmd; + } else { + cmds_out->first = cmd; + } + cmds_out->last = cmd; + } break; + + case HOST_EVENT_KIND_CHANNEL_CLOSED: + { + struct sim_cmd *cmd = arena_push_zero(arena, struct sim_cmd); + cmd->kind = SIM_CMD_KIND_SIM_CLIENT_DISCONNECT; + cmd->disconnect_reason = LIT("Connection lost"); + if (cmds_out->last) { + cmds_out->last->next = cmd; + } else { + cmds_out->first = cmd; + } + cmds_out->last = cmd; + } break; + + case HOST_EVENT_KIND_MSG: + { + struct byte_reader br = br_from_buffer(host_event.msg); + while (br_bytes_left(&br) > 0) { + struct sim_cmd *cmd = arena_push_zero(arena, struct sim_cmd); + u64 cmd_size = br_read_u64(&br); + u64 cmd_pos_end = br_pos(&br) + cmd_size; + cmd->kind = br_read_i8(&br); + cmd->state = br_read_i8(&br); +#if COLLIDER_DEBUG + cmd->collider_gjk_steps = br_read_u32(&br); +#endif + + switch (cmd->kind) { + case SIM_CMD_KIND_PLAYER_MOVE: + { + cmd->move_dir = br_read_v2(&br); + cmd->aim_dir = br_read_v2(&br); + } break; + + case SIM_CMD_KIND_CURSOR_MOVE: + { + cmd->cursor_pos = br_read_v2(&br); + } break; + + default: break; + } + + ASSERT(br_pos(&br) == cmd_pos_end); + br_seek_to(&br, cmd_pos_end); + + if (cmds_out->last) { + cmds_out->last->next = cmd; + } else { + cmds_out->first = cmd; + } + cmds_out->last = cmd; + } + } break; + + default: break; + } + } +} + +/* ========================== * + * Sim event + * ========================== */ + +struct string sim_string_from_events(struct arena *arena, struct sim_event_list events) +{ + __prof; + struct byte_writer bw = bw_from_arena(arena); + for (struct sim_event *event = events.first; event; event = event->next) { + struct byte_writer bw_size = bw_branch(&bw, sizeof(u64)); + u64 start = bw_pos(&bw); + bw_write_i8(&bw, event->kind); + + switch (event->kind) { + case SIM_EVENT_KIND_SNAPSHOT_FULL: + { + bw_write_string(&bw, event->snapshot_data); + } break; + + default: break; + } + + u64 size = bw_pos(&bw) - start; + bw_write_u64(&bw_size, size); + } + return bw_get_written(&bw); +} + +void sim_events_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_event_list *events_out) +{ + __prof; + for (u64 i = 0; i < host_events.count; ++i) { + struct sim_event *sim_event = arena_push_zero(arena, struct sim_event); + struct host_event host_event = host_events.events[i]; + enum host_event_kind host_event_kind = host_event.kind; + sim_event->channel_id = host_event.channel_id; + switch (host_event_kind) { + case HOST_EVENT_KIND_CHANNEL_OPENED: + { + sim_event->kind = SIM_EVENT_KIND_CONNECT; + } break; + + case HOST_EVENT_KIND_CHANNEL_CLOSED: + { + sim_event->kind = SIM_EVENT_KIND_DISCONNECT; + sim_event->disconnect_reason = LIT("Connection lost"); + } break; + + case HOST_EVENT_KIND_MSG: + { + struct byte_reader br = br_from_buffer(host_event.msg); + while (br_bytes_left(&br) > 0) { + u64 event_size = br_read_u64(&br); + u64 event_pos_end = br_pos(&br) + event_size; + + sim_event->kind = br_read_i8(&br); + switch (sim_event->kind) { + case SIM_EVENT_KIND_SNAPSHOT_FULL: + { + sim_event->snapshot_data = br_read_string(arena, &br); + } break; + + default: break; + } + + ASSERT(br_pos(&br) == event_pos_end); + br_seek_to(&br, event_pos_end); + } + } break; + + default: break; + } + + if (events_out->last) { + events_out->last->next = sim_event; + } else { + events_out->first = sim_event; + } + events_out->last = sim_event; + } +} + +/* ========================== * + * Snapshot + * ========================== */ + +struct string sim_string_from_tick(struct arena *arena, struct world *tick) +{ + __prof; + struct byte_writer bw = bw_from_arena(arena); + + bw_write_var_uint(&bw, tick->continuity_gen); + bw_write_var_uint(&bw, tick->tick_id); + bw_write_var_sint(&bw, tick->publishtime_ns); + + bw_write_f64(&bw, tick->timescale); + bw_write_var_sint(&bw, tick->dt_ns); + bw_write_var_sint(&bw, tick->time_ns); + + u64 num_entities = tick->ent_store->num_reserved; + bw_write_var_uint(&bw, num_entities); + + struct string entities_src = ZI; + entities_src.text = (u8 *)tick->ent_store->entities; + entities_src.len = sizeof(struct sim_ent) * num_entities; + br_write_bytes(&bw, entities_src); + + return bw_get_written(&bw); +} + +void sim_tick_from_string(struct string str, struct world *tick_out) +{ + __prof; + struct byte_reader br = br_from_buffer(str); + + tick_out->continuity_gen = br_read_var_uint(&br); + tick_out->tick_id = br_read_var_uint(&br); + tick_out->publishtime_ns = br_read_var_sint(&br); + + tick_out->timescale = br_read_f64(&br); + tick_out->dt_ns = br_read_var_sint(&br); + tick_out->time_ns = br_read_var_sint(&br); + + u64 num_entities = br_read_var_uint(&br); + arena_push_array(&tick_out->ent_store->arena, struct sim_ent, num_entities - tick_out->ent_store->num_reserved); + tick_out->ent_store->num_reserved = num_entities; + + tick_out->ent_store->num_allocated = 0; + struct sim_ent *entities_src = br_seek(&br, num_entities * sizeof(struct sim_ent)); + if (entities_src) { + for (u64 i = 0; i < num_entities; ++i) { + struct sim_ent *src = &entities_src[i]; + struct sim_ent *dst = &tick_out->ent_store->entities[i]; + if (dst->valid) { + ++tick_out->ent_store->num_allocated; + } + *dst = *src; + } + } +} diff --git a/src/sim_msg.h b/src/sim_msg.h new file mode 100644 index 00000000..4a877a69 --- /dev/null +++ b/src/sim_msg.h @@ -0,0 +1,112 @@ +#ifndef SIM_MSG_H +#define SIM_MSG_H + +#include "host.h" + +struct world; + +/* ========================== * + * Sim cmd + * ========================== */ + +enum sim_cmd_state { + SIM_CMD_STATE_STOP = -1, + SIM_CMD_STATE_NO_CHANGE = 0, + SIM_CMD_STATE_START = 1 +}; + +enum sim_cmd_kind { + SIM_CMD_KIND_NONE, + + SIM_CMD_KIND_PLAYER_MOVE, + SIM_CMD_KIND_PLAYER_FIRE, + + SIM_CMD_KIND_SIM_CLIENT_CONNECT, + SIM_CMD_KIND_SIM_CLIENT_DISCONNECT, + + /* Testing */ + SIM_CMD_KIND_CLEAR_ALL, + SIM_CMD_KIND_SPAWN_TEST, + SIM_CMD_KIND_PAUSE, + SIM_CMD_KIND_STEP, + SIM_CMD_KIND_DRAG_OBJECT, + SIM_CMD_KIND_CURSOR_MOVE, + + SIM_CMD_KIND_COUNT +}; + +struct sim_cmd { + enum sim_cmd_kind kind; + enum sim_cmd_state state; + struct host_channel_id channel_id; + + /* SIM_CMD_KIND_PLAYER_MOVE */ + struct v2 move_dir; + struct v2 aim_dir; + + /* SIM_CMD_KIND_CURSOR_MOVE */ + struct v2 cursor_pos; + + /* SIM_CMD_KIND_PLAYER_DISCONNECT */ + struct string disconnect_reason; + +#if RTC + u32 collider_gjk_steps; +#endif + + struct sim_cmd *next; +}; + +struct sim_cmd_list { + struct sim_cmd *first; + struct sim_cmd *last; +}; + +struct string sim_string_from_cmds(struct arena *arena, struct sim_cmd_list cmds); +void sim_cmds_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_cmd_list *cmds_out); + +/* ========================== * + * Sim event + * ========================== */ + +enum sim_event_kind { + SIM_EVENT_KIND_NONE, + + SIM_EVENT_KIND_CONNECT, + SIM_EVENT_KIND_DISCONNECT, + SIM_EVENT_KIND_SNAPSHOT_FULL, + + //SIM_EVENT_KIND_ENTITY_UPDATE, + //SIM_EVENT_KIND_ENTITY_CREATE, + //SIM_EVENT_KIND_ENTITY_DESTROY +}; + +struct sim_event { + enum sim_event_kind kind; + struct host_channel_id channel_id; + + struct string snapshot_data; + struct string disconnect_reason; + + //struct sim_ent_handle entity; + //struct string update_data; + + struct sim_event *next; +}; + +struct sim_event_list { + struct sim_event *first; + struct sim_event *last; +}; + +struct string sim_string_from_events(struct arena *arena, struct sim_event_list events); +void sim_events_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_event_list *events_out); + +/* ========================== * + * Snapshot + * ========================== */ + +struct string sim_string_from_tick(struct arena *arena, struct world *tick); +void sim_tick_from_string(struct string str, struct world *tick_out); + +#endif diff --git a/src/sock.h b/src/sock.h index 9ecc5a6c..7a4f7c1f 100644 --- a/src/sock.h +++ b/src/sock.h @@ -8,13 +8,8 @@ enum sock_address_family { SOCK_ADDRESS_FAMILY_IPV6 }; -struct sock { - i32 _; -}; - -struct sock_signal { - i32 _; -}; +struct sock; +struct sock_signal; struct sock_array { struct sock **socks; diff --git a/src/user.c b/src/user.c index 92d23ba0..7edbcde6 100644 --- a/src/user.c +++ b/src/user.c @@ -2,6 +2,7 @@ #include "app.h" #include "sim.h" #include "sim_ent.h" +#include "sim_msg.h" #include "renderer.h" #include "font.h" #include "sprite.h" @@ -46,9 +47,8 @@ GLOBAL struct { struct sys_thread user_thread; struct arena arena; - struct sys_window *window; - + struct sim_ctx *sim_ctx; struct host *host; /* Usage stats */ @@ -148,9 +148,10 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, struct font_startup_receipt *font_sr, struct sprite_startup_receipt *sprite_sr, struct draw_startup_receipt *draw_sr, - struct sim_startup_receipt *sim_sr, struct asset_cache_startup_receipt *asset_cache_sr, + struct sound_startup_receipt *sound_sr, struct mixer_startup_receipt *mixer_sr, + struct phys_startup_receipt *phys_sr, struct host_startup_receipt *host_sr, struct sys_window *window) { @@ -159,9 +160,10 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, (UNUSED)font_sr; (UNUSED)sprite_sr; (UNUSED)draw_sr; - (UNUSED)sim_sr; (UNUSED)asset_cache_sr; + (UNUSED)sound_sr; (UNUSED)mixer_sr; + (UNUSED)phys_sr; (UNUSED)host_sr; G.arena = arena_alloc(GIGABYTE(64)); @@ -170,8 +172,7 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, world_alloc(&G.world); //struct sock_address bind_addr = sock_address_from_any_local_interface_with_dynamic_port(); - //G.host = host_alloc(0); - G.host = host_alloc(5920); + G.host = host_alloc(0); G.world_to_ui_xf = XFORM_IDENT; G.world_cmd_buffer = renderer_cmd_buffer_alloc(); @@ -182,6 +183,8 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, G.window = window; sys_window_register_event_callback(G.window, &window_event_callback); + G.sim_ctx = sim_ctx_alloc(sprite_sr, phys_sr, host_sr, 12345); + G.debug_draw = true; G.user_thread = sys_thread_alloc(&user_thread_entry_point, NULL, LIT("[P1] User thread")); @@ -195,6 +198,10 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(user_shutdown) __prof; atomic_i32_eval_exchange(&G.user_thread_shutdown, true); sys_thread_wait_release(&G.user_thread); + + if (G.sim_ctx) { + sim_ctx_release(G.sim_ctx); + } } /* ========================== * @@ -1620,10 +1627,10 @@ INTERNAL void user_update(void) pos.y += spacing; pos.y += spacing; - draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Client data read: %F mbit/s"), FMT_FLOAT_P((f64)G.client_bytes_read.last_second * 8 / 1024 / 1024, 2))); + draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Client data read: %F mbit/s"), FMT_FLOAT_P((f64)G.client_bytes_read.last_second * 8 / 1000 / 1000, 2))); pos.y += spacing; - draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Client data sent: %F mbit/s"), FMT_FLOAT_P((f64)G.client_bytes_sent.last_second * 8 / 1024 / 1024, 2))); + draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Client data sent: %F mbit/s"), FMT_FLOAT_P((f64)G.client_bytes_sent.last_second * 8 / 1000 / 1000, 2))); pos.y += spacing; draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Memory usage: %F MiB"), FMT_FLOAT_P((f64)atomic_u64_eval(&app_statistics()->memory_committed) / 1024 / 1024, 2))); diff --git a/src/user.h b/src/user.h index a80739c3..6163c4b7 100644 --- a/src/user.h +++ b/src/user.h @@ -7,9 +7,10 @@ struct renderer_startup_receipt; struct font_startup_receipt; struct sprite_startup_receipt; struct draw_startup_receipt; -struct sim_startup_receipt; struct asset_cache_startup_receipt; +struct sound_startup_receipt; struct mixer_startup_receipt; +struct phys_startup_receipt; struct host_startup_receipt; enum user_bind_kind { @@ -54,9 +55,10 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, struct font_startup_receipt *font_sr, struct sprite_startup_receipt *sprite_sr, struct draw_startup_receipt *draw_sr, - struct sim_startup_receipt *sim_sr, struct asset_cache_startup_receipt *asset_cache_sr, + struct sound_startup_receipt *sound_sr, struct mixer_startup_receipt *mixer_sr, + struct phys_startup_receipt *phys_sr, struct host_startup_receipt *host_sr, struct sys_window *window);