diff --git a/src/.vscode/settings.json b/src/.vscode/settings.json deleted file mode 100644 index e517b64a..00000000 --- a/src/.vscode/settings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "files.associations": { - "*.rst": "hlsl", - "*.knl": "hlsl", - "chrono": "c", - "system_error": "c", - "xlocale": "c" - } -} \ No newline at end of file diff --git a/src/pp/pp_core.c b/src/pp/pp_core.c index c58b04f8..d6c7c746 100644 --- a/src/pp/pp_core.c +++ b/src/pp/pp_core.c @@ -2147,7 +2147,7 @@ JobDef(SimJob, UNUSED sig, UNUSED id) BB_Buff msg_writer_bb = AcquireBitbuff(Gibi(64)); BB_Buff snapshot_writer_bb = AcquireBitbuff(Gibi(64)); - SimAccel accel = sim_accel_acquire(); + SimAccel accel = AcquireSimAccel(); ClientStore *store = sim_client_store_acquire(); Client *user_input_client = sim_client_acquire(store); /* Stores snapshots containing commands to be published to local client */ @@ -2496,7 +2496,7 @@ JobDef(SimJob, UNUSED sig, UNUSED id) Snapshot *prev_world = sim_snapshot_from_tick(local_client, prev_tick); ctx.world = sim_snapshot_acquire(local_client, prev_world, next_tick); GenerateuserInputCmds(user_input_client, next_tick); - sim_step(&ctx); + StepSim(&ctx); } else if (master_client->valid) { @@ -2723,7 +2723,7 @@ JobDef(SimJob, UNUSED sig, UNUSED id) { sim_snapshot_sync_ents(ctx.world, master_ss, master_player->id, SIM_SYNC_FLAG_NOSYNC_PREDICTABLES); } - sim_step(&ctx); + StepSim(&ctx); prev_ss = ctx.world; ++step_tick; } @@ -2811,7 +2811,7 @@ JobDef(SimJob, UNUSED sig, UNUSED id) } sim_client_store_release(store); - sim_accel_release(&accel); + ReleaseSimAccel(&accel); ReleaseBitbuff(&snapshot_writer_bb); ReleaseBitbuff(&msg_writer_bb); N_ReleaseHost(host); diff --git a/src/pp/pp_step.c b/src/pp/pp_step.c index 56423519..4dca3b66 100644 --- a/src/pp/pp_step.c +++ b/src/pp/pp_step.c @@ -1,20 +1,19 @@ -/* ========================== * - * Sim accel - * ========================== */ +//////////////////////////////// +//~ Sim accel -SimAccel sim_accel_acquire(void) +SimAccel AcquireSimAccel(void) { SimAccel accel = ZI; accel.space = space_acquire(SPACE_CELL_SIZE, SPACE_CELL_BINS_SQRT); return accel; } -void sim_accel_release(SimAccel *accel) +void ReleaseSimAccel(SimAccel *accel) { space_release(accel->space); } -void sim_accel_reset(Snapshot *ss, SimAccel *accel) +void ResetSimAccel(Snapshot *ss, SimAccel *accel) { space_reset(accel->space); @@ -27,13 +26,12 @@ void sim_accel_reset(Snapshot *ss, SimAccel *accel) } } -/* ========================== * - * Test - * ========================== */ +//////////////////////////////// +//~ Spawn test operations - /* TODO: Remove this */ +/* TODO: Remove this */ -internal Entity *test_spawn_smg(Entity *parent) +Entity *SpawnTestSmg(Entity *parent) { Entity *e = sim_ent_acquire_sync_src(parent); e->sprite = S_TagFromPath(Lit("sprite/gun.ase")); @@ -49,7 +47,7 @@ internal Entity *test_spawn_smg(Entity *parent) return e; } -internal Entity *test_spawn_launcher(Entity *parent) +Entity *SpawnTestLauncher(Entity *parent) { Entity *e = sim_ent_acquire_sync_src(parent); e->sprite = S_TagFromPath(Lit("sprite/gun.ase")); @@ -65,7 +63,7 @@ internal Entity *test_spawn_launcher(Entity *parent) return e; } -internal Entity *test_spawn_chucker(Entity *parent) +Entity *SpawnTestChucker(Entity *parent) { Entity *chucker = sim_ent_acquire_sync_src(parent); chucker->sprite = S_TagFromPath(Lit("sprite/gun.ase")); @@ -100,7 +98,7 @@ internal Entity *test_spawn_chucker(Entity *parent) return chucker; } -internal Entity *test_spawn_employee(Entity *parent) +Entity *SpawnTestEmployee(Entity *parent) { /* Player */ Entity *employee = sim_ent_nil(); @@ -170,11 +168,11 @@ internal Entity *test_spawn_employee(Entity *parent) /* Player weapon */ if (employee->valid) { - LAX test_spawn_smg; - LAX test_spawn_launcher; - LAX test_spawn_chucker; + LAX SpawnTestSmg; + LAX SpawnTestLauncher; + LAX SpawnTestChucker; - Entity *e = test_spawn_chucker(employee); + Entity *e = SpawnTestChucker(employee); employee->equipped = e->id; sim_ent_enable_prop(e, SEPROP_LIGHT_TEST); @@ -184,7 +182,7 @@ internal Entity *test_spawn_employee(Entity *parent) return employee; } -internal Entity *test_spawn_camera(Entity *parent, Entity *follow) +Entity *SpawnTestCamera(Entity *parent, Entity *follow) { Entity *camera_ent = sim_ent_nil(); if (follow->valid) { @@ -203,7 +201,7 @@ internal Entity *test_spawn_camera(Entity *parent, Entity *follow) return camera_ent; } -internal Entity *test_spawn_explosion(Entity *parent, Vec2 pos, f32 strength, f32 radius) +Entity *SpawnTestExplosion(Entity *parent, Vec2 pos, f32 strength, f32 radius) { Entity *ent = sim_ent_acquire_sync_src(parent); sim_ent_set_xform(ent, XformFromPos(pos)); @@ -219,7 +217,7 @@ internal Entity *test_spawn_explosion(Entity *parent, Vec2 pos, f32 strength, f3 return ent; } -internal void test_teleport(Entity *ent, Vec2 pos) +void TeleportTest(Entity *ent, Vec2 pos) { //++ent->continuity_gen; Xform xf = sim_ent_get_xform(ent); @@ -227,20 +225,20 @@ internal void test_teleport(Entity *ent, Vec2 pos) sim_ent_set_xform(ent, xf); } -internal void test_spawn_entities1(Entity *parent, Vec2 pos) +void SpawnTestEntities1(Entity *parent, Vec2 pos) { LAX pos; /* Enemy */ { - Entity *e = test_spawn_employee(parent); + Entity *e = SpawnTestEmployee(parent); Xform xf = sim_ent_get_xform(e); xf.og = pos; sim_ent_set_xform(e, xf); } } -internal void test_spawn_entities2(Entity *parent, Vec2 pos) +void SpawnTestEntities2(Entity *parent, Vec2 pos) { LAX pos; @@ -311,7 +309,7 @@ internal void test_spawn_entities2(Entity *parent, Vec2 pos) #endif } -internal void test_spawn_entities3(Entity *parent, Vec2 pos) +void SpawnTestEntities3(Entity *parent, Vec2 pos) { LAX pos; @@ -336,7 +334,7 @@ internal void test_spawn_entities3(Entity *parent, Vec2 pos) } } -internal void test_spawn_entities4(Entity *parent, Vec2 pos) +void SpawnTestEntities4(Entity *parent, Vec2 pos) { LAX pos; @@ -358,7 +356,7 @@ internal void test_spawn_entities4(Entity *parent, Vec2 pos) e->sprite_tint = Rgb32F(1, 1, 1); } -internal void test_spawn_tile(Snapshot *world, Vec2 world_pos) +void SpawnTestTile(Snapshot *world, Vec2 world_pos) { #if 0 Entity *e = sim_ent_acquire_sync_src(parent); @@ -397,15 +395,21 @@ internal void test_spawn_tile(Snapshot *world, Vec2 world_pos) #endif } +void ClearLevelTest(SimStepCtx *ctx) +{ + Snapshot *world = ctx->world; + for (u64 j = 0; j < world->num_ents_reserved; ++j) { + Entity *ent = &world->ents[j]; + if (ent->valid) { + sim_ent_enable_prop(ent, SEPROP_RELEASE); + } + } +} +//////////////////////////////// +//~ Tile test operations - - - - - - -internal MergesortCompareFuncDef(tile_chunk_sort_x, arg_a, arg_b, _) +MergesortCompareFuncDef(SortTileXCmp, arg_a, arg_b, _) { Entity *a = *(Entity **)arg_a; Entity *b = *(Entity **)arg_b; @@ -417,7 +421,7 @@ internal MergesortCompareFuncDef(tile_chunk_sort_x, arg_a, arg_b, _) return result; } -internal MergesortCompareFuncDef(tile_chunk_sort_y, arg_a, arg_b, _) +MergesortCompareFuncDef(SortTileYCmp, arg_a, arg_b, _) { Entity *a = *(Entity **)arg_a; Entity *b = *(Entity **)arg_b; @@ -429,7 +433,7 @@ internal MergesortCompareFuncDef(tile_chunk_sort_y, arg_a, arg_b, _) return result; } -internal void test_generate_walls(Snapshot *world) +void GenerateTestWalls(Snapshot *world) { __prof; TempArena scratch = BeginScratchNoConflict(); @@ -460,8 +464,8 @@ internal void test_generate_walls(Snapshot *world) /* NOTE: We sort x & y separately because it's possible that a wall * should merge with another wall that was generated from a diagonal chunk. */ - Mergesort(x_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*x_sorted_tile_chunks), tile_chunk_sort_x, 0); - Mergesort(y_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*y_sorted_tile_chunks), tile_chunk_sort_y, 0); + Mergesort(x_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*x_sorted_tile_chunks), SortTileXCmp, 0); + Mergesort(y_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*y_sorted_tile_chunks), SortTileYCmp, 0); } struct wall_node { @@ -682,33 +686,10 @@ internal void test_generate_walls(Snapshot *world) EndScratch(scratch); } +//////////////////////////////// +//~ On collision - - - - - - - - - - -internal void test_clear_level(SimStepCtx *ctx) -{ - Snapshot *world = ctx->world; - for (u64 j = 0; j < world->num_ents_reserved; ++j) { - Entity *ent = &world->ents[j]; - if (ent->valid) { - sim_ent_enable_prop(ent, SEPROP_RELEASE); - } - } -} - -/* ========================== * - * Respond to physics collisions - * ========================== */ - -internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx) +PHYS_COLLISION_CALLBACK_FUNC_DEF(OnEntityCollision, data, step_ctx) { Snapshot *world = step_ctx->world; Entity *e0 = sim_ent_from_id(world, data->e0); @@ -770,7 +751,7 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx) /* Create explosion */ if (bullet->bullet_explosion_strength > 0) { - test_spawn_explosion(root, point, bullet->bullet_explosion_strength, bullet->bullet_explosion_radius); + SpawnTestExplosion(root, point, bullet->bullet_explosion_strength, bullet->bullet_explosion_radius); } /* Update bullet */ @@ -830,11 +811,10 @@ internal PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx) return skip_solve; } -/* ========================== * - * Update - * ========================== */ +//////////////////////////////// +//~ Step -void sim_step(SimStepCtx *ctx) +void StepSim(SimStepCtx *ctx) { __prof; TempArena scratch = BeginScratchNoConflict(); @@ -850,9 +830,7 @@ void sim_step(SimStepCtx *ctx) i64 sim_dt_ns = ctx->sim_dt_ns; - /* ========================== * - * Begin frame - * ========================== */ + //- Begin frame world->sim_dt_ns = MaxI64(0, sim_dt_ns); world->sim_time_ns += world->sim_dt_ns; @@ -863,9 +841,7 @@ void sim_step(SimStepCtx *ctx) Entity *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); root->owner = world->client->player_id; - /* ========================== * - * Sync ents from cmd producing clients - * ========================== */ + //- Sync ents from cmd producing clients { /* FIXME: Ensure only cmds are synced to master player */ @@ -940,16 +916,14 @@ void sim_step(SimStepCtx *ctx) } } - /* ========================== * - * Release entities at beginning of frame - * ========================== */ + + //- Release entities at beginning of frame sim_ent_release_all_with_prop(world, SEPROP_RELEASE); - sim_accel_reset(world, ctx->accel); + ResetSimAccel(world, ctx->accel); - /* ========================== * - * Activate entities - * ========================== */ + + //- Activate entities for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -964,9 +938,8 @@ void sim_step(SimStepCtx *ctx) } } - /* ========================== * - * Process player cmds - * ========================== */ + + //- Process player cmds for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *cmd_ent = &world->ents[ent_index]; @@ -1023,7 +996,7 @@ void sim_step(SimStepCtx *ctx) } } if (flags & SIM_CONTROL_FLAG_CLEAR_ALL) { - test_clear_level(ctx); + ClearLevelTest(ctx); } if (flags & SIM_CONTROL_FLAG_SPAWN1_TEST) { P_LogDebugF("Spawn test 1"); @@ -1032,7 +1005,7 @@ void sim_step(SimStepCtx *ctx) for (u32 j = 0; j < count; ++j) { Vec2 pos = player->player_cursor_pos; pos.y += (((f32)j / (f32)count) - 0.5) * spread; - test_spawn_entities1(root, pos); + SpawnTestEntities1(root, pos); } } if (flags & SIM_CONTROL_FLAG_SPAWN2_TEST) { @@ -1042,7 +1015,7 @@ void sim_step(SimStepCtx *ctx) for (u32 j = 0; j < count; ++j) { Vec2 pos = player->player_cursor_pos; pos.y += (((f32)j / (f32)count) - 0.5) * spread; - test_spawn_entities2(root, pos); + SpawnTestEntities2(root, pos); } } if (flags & SIM_CONTROL_FLAG_SPAWN3_TEST) { @@ -1052,7 +1025,7 @@ void sim_step(SimStepCtx *ctx) for (u32 j = 0; j < count; ++j) { Vec2 pos = player->player_cursor_pos; pos.y += (((f32)j / (f32)count) - 0.5) * spread; - test_spawn_entities3(root, pos); + SpawnTestEntities3(root, pos); } } if (flags & SIM_CONTROL_FLAG_SPAWN4_TEST) { @@ -1062,22 +1035,22 @@ void sim_step(SimStepCtx *ctx) for (u32 j = 0; j < count; ++j) { Vec2 pos = player->player_cursor_pos; pos.y += (((f32)j / (f32)count) - 0.5) * spread; - test_spawn_entities4(root, pos); + SpawnTestEntities4(root, pos); } } if (flags & SIM_CONTROL_FLAG_WALLS_TEST) { - test_generate_walls(world); + GenerateTestWalls(world); } if (flags & SIM_CONTROL_FLAG_EXPLODE_TEST) { P_LogDebugF("Explosion test"); - test_spawn_explosion(root, player->player_cursor_pos, 100, 2); + SpawnTestExplosion(root, player->player_cursor_pos, 100, 2); } } if (flags & SIM_CONTROL_FLAG_TILE_TEST) { - test_spawn_tile(world, player->player_cursor_pos); + SpawnTestTile(world, player->player_cursor_pos); } else if (old_control.flags & SIM_CONTROL_FLAG_TILE_TEST) { - test_generate_walls(world); + GenerateTestWalls(world); } } } break; @@ -1111,9 +1084,8 @@ void sim_step(SimStepCtx *ctx) } } - /* ========================== * - * Update entity control from player control - * ========================== */ + + //- Update entity control from player control for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1127,9 +1099,8 @@ void sim_step(SimStepCtx *ctx) } } - /* ========================== * - * Create employees - * ========================== */ + + //- Create employees if (is_master) { for (u64 i = 0; i < world->num_ents_reserved; ++i) { @@ -1139,7 +1110,7 @@ void sim_step(SimStepCtx *ctx) /* FIXME: Ents never released when client disconnects */ Entity *control_ent = sim_ent_from_id(world, ent->player_control_ent); if (!control_ent->valid) { - control_ent = test_spawn_employee(root); + control_ent = SpawnTestEmployee(root); control_ent->predictor = ent->id; sim_ent_enable_prop(control_ent, SEPROP_CONTROLLED); ent->player_control_ent = control_ent->id; @@ -1147,7 +1118,7 @@ void sim_step(SimStepCtx *ctx) } Entity *camera_ent = sim_ent_from_id(world, ent->player_camera_ent); if (!camera_ent->valid) { - camera_ent = test_spawn_camera(root, control_ent); + camera_ent = SpawnTestCamera(root, control_ent); camera_ent->predictor = ent->id; ent->player_camera_ent = camera_ent->id; } @@ -1159,9 +1130,8 @@ void sim_step(SimStepCtx *ctx) } } - /* ========================== * - * Update entities from sprite - * ========================== */ + + //- Update entities from sprite for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1261,9 +1231,8 @@ void sim_step(SimStepCtx *ctx) #endif } - /* ========================== * - * Update attachments - * ========================== */ + + //- Update attachments for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1286,9 +1255,8 @@ void sim_step(SimStepCtx *ctx) sim_ent_set_local_xform(ent, xf); } - /* ========================== * - * Process ent control - * ========================== */ + + //- Process ent control for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1310,14 +1278,13 @@ void sim_step(SimStepCtx *ctx) } } if (flags & SIM_CONTROL_FLAG_TELEPORT_TEST) { - test_teleport(ent, control->dbg_cursor); + TeleportTest(ent, control->dbg_cursor); } } } - /* ========================== * - * Process triggered entities - * ========================== */ + + //- Process triggered entities for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1476,9 +1443,8 @@ void sim_step(SimStepCtx *ctx) } } - /* ========================== * - * Create & update motor joints from control move - * ========================== */ + + //- Create & update motor joints from control move for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1512,9 +1478,8 @@ void sim_step(SimStepCtx *ctx) } } - /* ========================== * - * Create & update motor joints from control focus (aim) - * ========================== */ + + //- Create & update motor joints from control focus (aim) #if SIM_PLAYER_AIM for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { @@ -1610,9 +1575,8 @@ void sim_step(SimStepCtx *ctx) } #endif - /* ========================== * - * Create motor joints from ground friction (gravity) - * ========================== */ + + //- Create motor joints from ground friction (gravity) #if 1 for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { @@ -1641,9 +1605,8 @@ void sim_step(SimStepCtx *ctx) } #endif - /* ========================== * - * Create mouse joints from client debug drag - * ========================== */ + + //- Create mouse joints from client debug drag if (is_master) { for (u64 i = 0; i < world->num_ents_reserved; ++i) { @@ -1696,20 +1659,18 @@ void sim_step(SimStepCtx *ctx) } } - /* ========================== * - * Physics step - * ========================== */ + + //- Physics step { PhysStepCtx phys = ZI; phys.sim_step_ctx = ctx; - phys.collision_callback = on_collision; + phys.collision_callback = OnEntityCollision; phys_step(&phys, sim_dt); } - /* ========================== * - * Update explosions - * ========================== */ + + //- Update explosions for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1720,9 +1681,8 @@ void sim_step(SimStepCtx *ctx) sim_ent_disable_prop(ent, SEPROP_SENSOR); } - /* ========================== * - * Update tracers - * ========================== */ + + //- Update tracers for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1744,9 +1704,8 @@ void sim_step(SimStepCtx *ctx) ent->tracer_gradient_end = gradient_end; } - /* ========================== * - * Initialize bullet kinematics from sources - * ========================== */ + + //- Initialize bullet kinematics from sources for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1803,9 +1762,8 @@ void sim_step(SimStepCtx *ctx) } } - /* ========================== * - * Update cameras - * ========================== */ + + //- Update cameras for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1859,9 +1817,8 @@ void sim_step(SimStepCtx *ctx) sim_ent_set_xform(ent, xf); } - /* ========================== * - * Update quakes - * ========================== */ + + //- Update quakes for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { Entity *ent = &world->ents[ent_index]; @@ -1874,9 +1831,8 @@ void sim_step(SimStepCtx *ctx) } } - /* ========================== * - * Update relative layers - * ========================== */ + + //- Update relative layers { TempArena temp = BeginTempArena(scratch.arena); @@ -1903,15 +1859,13 @@ void sim_step(SimStepCtx *ctx) EndTempArena(temp); } - /* ========================== * - * Release entities at end of frame - * ========================== */ + + //- Release entities at end of frame sim_ent_release_all_with_prop(world, SEPROP_RELEASE); - /* ========================== * - * Sync to publish client - * ========================== */ + + //- Sync to publish client if (publish_client->valid && world->tick > publish_client->last_tick) { Snapshot *prev_pub_world = sim_snapshot_from_tick(publish_client, publish_client->last_tick); @@ -1936,9 +1890,8 @@ void sim_step(SimStepCtx *ctx) pub_world->local_player = world->local_player; } - /* ========================== * - * End frame - * ========================== */ + + //- End frame S_EndScope(sprite_frame_scope); diff --git a/src/pp/pp_step.h b/src/pp/pp_step.h index 63935182..eebfc992 100644 --- a/src/pp/pp_step.h +++ b/src/pp/pp_step.h @@ -1,6 +1,5 @@ -/* ========================== * - * Sim accel - * ========================== */ +//////////////////////////////// +//~ Acceleration structure types /* Structure used to accelerate up entity lookup (rebuilt every step) */ /* TODO: Remove this and do something better. Just a hack to de-couple old sim ctx from step. */ @@ -10,13 +9,8 @@ struct SimAccel { Space *space; }; -SimAccel sim_accel_acquire(void); -void sim_accel_release(SimAccel *accel); -void sim_accel_reset(Snapshot *ss, SimAccel *accel); - -/* ========================== * - * Sim step - * ========================== */ +//////////////////////////////// +//~ Step ctx typedef struct SimStepCtx SimStepCtx; struct SimStepCtx { @@ -32,4 +26,43 @@ struct SimStepCtx { Client *publish_client; /* The publish client to write syncable state to (nil if skipping publish) */ }; -void sim_step(SimStepCtx *ctx); +//////////////////////////////// +//~ Accel operations + +SimAccel AcquireSimAccel(void); +void ReleaseSimAccel(SimAccel *accel); +void ResetSimAccel(Snapshot *ss, SimAccel *accel); + +//////////////////////////////// +//~ Spawn test operations + +Entity *SpawnTestSmg(Entity *parent); +Entity *SpawnTestLauncher(Entity *parent); +Entity *SpawnTestChucker(Entity *parent); +Entity *SpawnTestEmployee(Entity *parent); +Entity *SpawnTestCamera(Entity *parent, Entity *follow); +Entity *SpawnTestExplosion(Entity *parent, Vec2 pos, f32 strength, f32 radius); +void TeleportTest(Entity *ent, Vec2 pos); +void SpawnTestEntities1(Entity *parent, Vec2 pos); +void SpawnTestEntities2(Entity *parent, Vec2 pos); +void SpawnTestEntities3(Entity *parent, Vec2 pos); +void SpawnTestEntities4(Entity *parent, Vec2 pos); +void SpawnTestTile(Snapshot *world, Vec2 world_pos); +void ClearLevelTest(SimStepCtx *ctx); + +//////////////////////////////// +//~ Tile test operations + +MergesortCompareFuncDef(SortTileXCmp, arg_a, arg_b, _); +MergesortCompareFuncDef(SortTileYCmp, arg_a, arg_b, _); +void GenerateTestWalls(Snapshot *world); + +//////////////////////////////// +//~ Collision response + +PHYS_COLLISION_CALLBACK_FUNC_DEF(OnEntityCollision, data, step_ctx); + +//////////////////////////////// +//~ Step + +void StepSim(SimStepCtx *ctx);