queue user cmds from sim
This commit is contained in:
parent
25a8a3c39a
commit
db7cbad4b3
@ -890,11 +890,13 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
|
||||
G_D12_Resource *resource = 0;
|
||||
|
||||
b32 is_buffer = desc.kind == G_ResourceKind_Buffer;
|
||||
b32 is_texture = desc.kind == G_ResourceKind_Texture1D ||
|
||||
b32 is_texture=
|
||||
desc.kind == G_ResourceKind_Texture1D ||
|
||||
desc.kind == G_ResourceKind_Texture2D ||
|
||||
desc.kind == G_ResourceKind_Texture3D;
|
||||
b32 is_sampler = desc.kind == G_ResourceKind_Sampler;
|
||||
G_ResourceFlag flags = is_buffer ? desc.buffer.flags :
|
||||
G_ResourceFlag flags =
|
||||
is_buffer ? desc.buffer.flags :
|
||||
is_texture ? desc.texture.flags :
|
||||
desc.sampler.flags;
|
||||
|
||||
|
||||
119
src/pp/pp.c
119
src/pp/pp.c
@ -7,7 +7,8 @@ Readonly P_Ent P_NilEnt = {
|
||||
};
|
||||
|
||||
Readonly P_Frame P_NilFrame = {
|
||||
0
|
||||
.first_ent = &P_NilEnt,
|
||||
.last_ent = &P_NilEnt,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -1056,7 +1057,7 @@ P_Ent *P_EntFromKey(P_Frame *frame, P_Key key)
|
||||
P_Ent *P_FirstEnt(P_Frame *frame)
|
||||
{
|
||||
P_Ent *result = &P_NilEnt;
|
||||
if (frame->first_ent)
|
||||
if (!P_IsEntNil(frame->first_ent))
|
||||
{
|
||||
result = frame->first_ent;
|
||||
}
|
||||
@ -1066,7 +1067,7 @@ P_Ent *P_FirstEnt(P_Frame *frame)
|
||||
P_Ent *P_NextEnt(P_Ent *e)
|
||||
{
|
||||
P_Ent *result = &P_NilEnt;
|
||||
if (e && e->next)
|
||||
if (!P_IsEntNil(e) && !P_IsEntNil(e->next))
|
||||
{
|
||||
result = e->next;
|
||||
}
|
||||
@ -1164,7 +1165,7 @@ P_World *P_AcquireWorld(void)
|
||||
|
||||
world->first_frame = &P_NilFrame;
|
||||
world->last_frame = &P_NilFrame;
|
||||
world->frame_bins_count = Kibi(1);
|
||||
world->frame_bins_count = Kibi(16);
|
||||
world->frame_bins = PushStructs(world->arena, P_FrameBin, world->frame_bins_count);
|
||||
|
||||
// TODO
|
||||
@ -1189,8 +1190,6 @@ void P_UpdateWorldFromSnapshots(P_World *world, P_SnapshotList snapshots)
|
||||
world->seed = snapshot->world_seed;
|
||||
frame->time_ns = snapshot->time_ns;
|
||||
|
||||
if (frame->ents_count == 0)
|
||||
{
|
||||
for (P_DeltaNode *dn = snapshot->first_delta_node; dn; dn = dn->next)
|
||||
{
|
||||
P_Delta *delta = &dn->delta;
|
||||
@ -1199,16 +1198,16 @@ void P_UpdateWorldFromSnapshots(P_World *world, P_SnapshotList snapshots)
|
||||
{
|
||||
}
|
||||
//- Reset
|
||||
else if (delta->kind == P_DeltaKind_Reset)
|
||||
{
|
||||
// FIXME: Free list entities
|
||||
frame->ents_count = 0;
|
||||
frame->first_ent = 0;
|
||||
frame->last_ent = 0;
|
||||
ZeroStructs(world->tiles, P_TilesCount);
|
||||
ZeroStructs(frame->ent_bins, frame->ent_bins_count);
|
||||
tiles_dirty = 1;
|
||||
}
|
||||
// else if (delta->kind == P_DeltaKind_Reset)
|
||||
// {
|
||||
// // FIXME: Freelist entities
|
||||
// frame->ents_count = 0;
|
||||
// frame->first_ent = 0;
|
||||
// frame->last_ent = 0;
|
||||
// ZeroStructs(world->tiles, P_TilesCount);
|
||||
// ZeroStructs(frame->ent_bins, frame->ent_bins_count);
|
||||
// tiles_dirty = 1;
|
||||
// }
|
||||
//- Raw ent
|
||||
else if (delta->kind == P_DeltaKind_RawEnt)
|
||||
{
|
||||
@ -1242,21 +1241,21 @@ void P_UpdateWorldFromSnapshots(P_World *world, P_SnapshotList snapshots)
|
||||
tiles_dirty = 1;
|
||||
}
|
||||
//- Tile range
|
||||
else if (delta->kind == P_DeltaKind_Tile)
|
||||
{
|
||||
P_TileKind tile = delta->tile_kind;
|
||||
Rng2I32 range = delta->tile_range;
|
||||
for (i32 tile_y = range.p0.y; tile_y < range.p1.y; ++tile_y)
|
||||
{
|
||||
for (i32 tile_x = range.p0.x; tile_x < range.p1.x; ++tile_x)
|
||||
{
|
||||
Vec2 tile_pos = VEC2(tile_x, tile_y);
|
||||
i32 tile_idx = P_TileIdxFromTilePos(tile_pos);
|
||||
world->tiles[tile_idx] = (u8)tile;
|
||||
}
|
||||
}
|
||||
tiles_dirty = 1;
|
||||
}
|
||||
// else if (delta->kind == P_DeltaKind_Tile)
|
||||
// {
|
||||
// P_TileKind tile = delta->tile_kind;
|
||||
// Rng2I32 range = delta->tiles_range;
|
||||
// for (i32 tile_y = range.p0.y; tile_y < range.p1.y; ++tile_y)
|
||||
// {
|
||||
// for (i32 tile_x = range.p0.x; tile_x < range.p1.x; ++tile_x)
|
||||
// {
|
||||
// Vec2 tile_pos = VEC2(tile_x, tile_y);
|
||||
// i32 tile_idx = P_TileIdxFromTilePos(tile_pos);
|
||||
// world->tiles[tile_idx] = (u8)tile;
|
||||
// }
|
||||
// }
|
||||
// tiles_dirty = 1;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -1267,7 +1266,6 @@ void P_UpdateWorldFromSnapshots(P_World *world, P_SnapshotList snapshots)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Rehash statics
|
||||
// if (tiles_dirty)
|
||||
@ -1295,9 +1293,16 @@ void P_SpawnEntsFromList(P_Frame *frame, P_EntList ents)
|
||||
}
|
||||
if (!dst)
|
||||
{
|
||||
// FIXME: Use free list
|
||||
dst = PushStructNoZero(world->arena, P_Ent);
|
||||
DllQueuePush(frame->first_ent, frame->last_ent, dst);
|
||||
dst = world->first_free_ent;
|
||||
if (dst)
|
||||
{
|
||||
SllStackPop(world->first_free_ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst = PushStructNoZero(world->frames_arena, P_Ent);
|
||||
}
|
||||
DllQueuePushNPZ(&P_NilEnt, frame->first_ent, frame->last_ent, dst, next, prev);
|
||||
DllQueuePushNP(bin->first, bin->last, dst, next_in_bin, prev_in_bin);
|
||||
}
|
||||
P_Ent *old_next = dst->next;
|
||||
@ -1345,14 +1350,18 @@ void P_ClearFrames(P_World *world, i64 tick_min, i64 tick_max)
|
||||
P_Frame *next_frame = frame->next;
|
||||
if (frame->tick >= tick_min && frame->tick <= tick_max)
|
||||
{
|
||||
// FIXME: Freelist ents
|
||||
|
||||
// FIXME: Freelist frame
|
||||
if (!P_IsEntNil(frame->first_ent))
|
||||
{
|
||||
frame->last_ent->next = world->first_free_ent;
|
||||
world->first_free_ent = frame->first_ent;
|
||||
}
|
||||
|
||||
u64 hash = MixU64(frame->tick);
|
||||
P_FrameBin *bin = &world->frame_bins[hash % world->frame_bins_count];
|
||||
DllQueueRemoveNPZ(&P_NilFrame, world->first_frame, world->last_frame, frame, next, prev);
|
||||
DllQueueRemoveNPZ(0, bin->first, bin->last, frame, next_in_bin, prev_in_bin);
|
||||
|
||||
SllStackPush(world->first_free_frame, frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1367,16 +1376,34 @@ P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
|
||||
Assert(!(src_frame->world == world && tick <= src_frame->tick)); // Can't read from tick that is being overwritten by new tick
|
||||
P_ClearFrames(world, tick, I64Max);
|
||||
|
||||
P_Frame *frame = PushStruct(world->frames_arena, P_Frame);
|
||||
P_Frame *frame = world->first_free_frame;
|
||||
if (frame)
|
||||
{
|
||||
// FIXME: Pull from freelist
|
||||
SllStackPop(world->first_free_frame);
|
||||
i64 old_ent_bins_count = frame->ent_bins_count;
|
||||
P_EntBin *old_ent_bins = frame->ent_bins;
|
||||
ZeroStruct(frame);
|
||||
frame->ent_bins_count = old_ent_bins_count;
|
||||
frame->ent_bins = old_ent_bins;
|
||||
ZeroStructs(frame->ent_bins, frame->ent_bins_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
frame = PushStruct(world->frames_arena, P_Frame);
|
||||
}
|
||||
|
||||
{
|
||||
frame->world = world;
|
||||
frame->tick = tick;
|
||||
frame->time_ns = src_frame->time_ns;
|
||||
|
||||
frame->first_ent = &P_NilEnt;
|
||||
frame->last_ent = &P_NilEnt;
|
||||
if (frame->ent_bins_count == 0)
|
||||
{
|
||||
frame->ent_bins_count = Kibi(16);
|
||||
frame->ent_bins = PushStructs(world->frames_arena, P_EntBin, frame->ent_bins_count);
|
||||
}
|
||||
|
||||
u64 hash = MixU64(tick);
|
||||
P_FrameBin *bin = &world->frame_bins[hash % world->frame_bins_count];
|
||||
@ -1388,10 +1415,18 @@ P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
|
||||
for (P_Ent *src = P_FirstEnt(src_frame); !P_IsEntNil(src); src = P_NextEnt(src))
|
||||
{
|
||||
// FIXME: Pull from freelist
|
||||
P_Ent *dst = PushStruct(world->frames_arena, P_Ent);
|
||||
P_Ent *dst = world->first_free_ent;
|
||||
if (dst)
|
||||
{
|
||||
SllStackPop(world->first_free_ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst = PushStructNoZero(world->frames_arena, P_Ent);
|
||||
}
|
||||
*dst = *src;
|
||||
P_EntBin *bin = &frame->ent_bins[src->key.v % frame->ent_bins_count];
|
||||
DllQueuePush(frame->first_ent, frame->last_ent, dst);
|
||||
DllQueuePushNPZ(&P_NilEnt, frame->first_ent, frame->last_ent, dst, next, prev);
|
||||
DllQueuePushNP(bin->first, bin->last, dst, next_in_bin, prev_in_bin);
|
||||
++frame->ents_count;
|
||||
}
|
||||
|
||||
26
src/pp/pp.h
26
src/pp/pp.h
@ -151,13 +151,14 @@ Struct(P_World)
|
||||
Arena *statics_arena;
|
||||
|
||||
u64 seed;
|
||||
// P_Ent *first_free_ent;
|
||||
|
||||
P_Ent *first_free_ent;
|
||||
|
||||
P_Frame *first_frame;
|
||||
P_Frame *last_frame;
|
||||
i64 frame_bins_count;
|
||||
P_FrameBin *frame_bins;
|
||||
// P_Frame *first_free_frame;
|
||||
P_Frame *first_free_frame;
|
||||
|
||||
u8 *tiles;
|
||||
};
|
||||
@ -167,18 +168,14 @@ Enum(P_DeltaKind)
|
||||
P_DeltaKind_Reset,
|
||||
P_DeltaKind_RawEnt,
|
||||
P_DeltaKind_RawTiles,
|
||||
P_DeltaKind_Tile,
|
||||
};
|
||||
|
||||
Struct(P_Delta)
|
||||
{
|
||||
P_DeltaKind kind;
|
||||
|
||||
P_Ent ent;
|
||||
|
||||
u8 *raw_tiles;
|
||||
P_TileKind tile_kind;
|
||||
Rng2I32 tile_range;
|
||||
u8 *raw_tiles;
|
||||
};
|
||||
|
||||
Struct(P_DeltaNode)
|
||||
@ -342,8 +339,10 @@ Struct(P_DebugDrawNode)
|
||||
Enum(P_CmdKind)
|
||||
{
|
||||
P_CmdKind_Nop,
|
||||
P_CmdKind_Save,
|
||||
P_CmdKind_Delta,
|
||||
P_CmdKind_SaveWorld,
|
||||
P_CmdKind_ResetWorld,
|
||||
P_CmdKind_TileEdit,
|
||||
P_CmdKind_EntEdit,
|
||||
P_CmdKind_Control,
|
||||
};
|
||||
|
||||
@ -352,8 +351,12 @@ Struct(P_Cmd)
|
||||
i64 tick;
|
||||
P_CmdKind kind;
|
||||
|
||||
// Delta
|
||||
P_Delta delta;
|
||||
// Tile edit
|
||||
P_TileKind tile_kind;
|
||||
Rng2I32 tile_range;
|
||||
|
||||
// Ent edit
|
||||
P_Ent ent;
|
||||
|
||||
// Control
|
||||
P_Key target;
|
||||
@ -366,6 +369,7 @@ Struct(P_Cmd)
|
||||
Struct(P_CmdNode)
|
||||
{
|
||||
P_CmdNode *next;
|
||||
P_CmdNode *prev;
|
||||
P_Cmd cmd;
|
||||
};
|
||||
|
||||
|
||||
@ -29,6 +29,27 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
// TODO: Real per-client deltas
|
||||
b32 has_sent_initial_tick = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// FIXME: Header
|
||||
|
||||
Rng user_cmd_tick_range = RNG(0, SIM_TICKS_PER_SECOND * 0.5);
|
||||
P_CmdList queued_user_cmds = Zi;
|
||||
P_CmdNode *first_free_user_cmd_node = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
//- Sim loop
|
||||
|
||||
@ -91,7 +112,8 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
P_Frame *prev_world_frame = world->last_frame;
|
||||
P_Frame *world_frame = P_PushFrame(world, prev_world_frame, prev_world_frame->tick + 1);
|
||||
|
||||
// FIXME: Copy frame
|
||||
// TDOO: Remove this
|
||||
P_ClearFrames(world, I64Min, prev_world_frame->tick - 1);
|
||||
|
||||
|
||||
i64 frame_begin_ns = TimeNs();
|
||||
@ -113,6 +135,66 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
UnlockTicketMutex(&P.sim_input_back_tm);
|
||||
|
||||
P_CmdList user_cmds = Zi;
|
||||
{
|
||||
i64 user_cmds_min_tick = world_frame->tick - user_cmd_tick_range.min;
|
||||
i64 user_cmds_max_tick = world_frame->tick + user_cmd_tick_range.max;
|
||||
// Prune user cmds
|
||||
{
|
||||
for (P_CmdNode *cmd_node = queued_user_cmds.first; cmd_node;)
|
||||
{
|
||||
P_CmdNode *next = cmd_node->next;
|
||||
b32 prune = 0;
|
||||
if (cmd_node->cmd.tick < user_cmds_min_tick || cmd_node->cmd.tick > user_cmds_max_tick)
|
||||
{
|
||||
prune = 1;
|
||||
}
|
||||
if (prune)
|
||||
{
|
||||
DllQueueRemove(queued_user_cmds.first, queued_user_cmds.last, cmd_node);
|
||||
SllStackPush(first_free_user_cmd_node, cmd_node);
|
||||
--queued_user_cmds.count;
|
||||
}
|
||||
cmd_node = next;
|
||||
}
|
||||
}
|
||||
// Push user cmds to queue
|
||||
{
|
||||
for (P_CmdNode *src_cmd_node = input->cmds.first; src_cmd_node; src_cmd_node = src_cmd_node->next)
|
||||
{
|
||||
if (src_cmd_node->cmd.tick >= user_cmds_min_tick && src_cmd_node->cmd.tick <= user_cmds_max_tick)
|
||||
{
|
||||
P_CmdNode *dst_cmd_node = first_free_user_cmd_node;
|
||||
if (dst_cmd_node)
|
||||
{
|
||||
SllStackPop(first_free_user_cmd_node);
|
||||
ZeroStruct(dst_cmd_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_cmd_node = PushStruct(perm, P_CmdNode);
|
||||
}
|
||||
dst_cmd_node->cmd = src_cmd_node->cmd;
|
||||
DllQueuePush(queued_user_cmds.first, queued_user_cmds.last, dst_cmd_node);
|
||||
++queued_user_cmds.count;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Copy queued commands for current tick
|
||||
{
|
||||
for (P_CmdNode *src_cmd_node = queued_user_cmds.first; src_cmd_node; src_cmd_node = src_cmd_node->next)
|
||||
{
|
||||
if (src_cmd_node->cmd.tick == world_frame->tick)
|
||||
{
|
||||
P_CmdNode *dst_cmd_node = PushStruct(frame_arena, P_CmdNode);
|
||||
dst_cmd_node->cmd = src_cmd_node->cmd;
|
||||
DllQueuePush(user_cmds.first, user_cmds.last, dst_cmd_node);
|
||||
++user_cmds.count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Update double-buffered entity data
|
||||
|
||||
@ -126,21 +208,21 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
// FIXME: Only accept save command from local user
|
||||
|
||||
b32 should_save = 0;
|
||||
for (P_CmdNode *cmd_node = input->cmds.first; cmd_node; cmd_node = cmd_node->next)
|
||||
{
|
||||
P_Cmd *cmd = &cmd_node->cmd;
|
||||
if (cmd->kind == P_CmdKind_Save)
|
||||
{
|
||||
should_save = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (should_save)
|
||||
{
|
||||
String path = Lit("HAH");
|
||||
LogInfoF("Saving world to %F", FmtString(path));
|
||||
}
|
||||
// b32 should_save = 0;
|
||||
// for (P_CmdNode *cmd_node = user_cmds.first; cmd_node; cmd_node = cmd_node->next)
|
||||
// {
|
||||
// P_Cmd *cmd = &cmd_node->cmd;
|
||||
// if (cmd->kind == P_CmdKind_SaveWorld)
|
||||
// {
|
||||
// should_save = 1;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (should_save)
|
||||
// {
|
||||
// String path = Lit("...");
|
||||
// LogInfoF("Saving world to %F", FmtString(path));
|
||||
// }
|
||||
|
||||
//////////////////////////////
|
||||
//- Process user world delta commands
|
||||
@ -149,53 +231,44 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
// FIXME: Only apply relevant cmds based on tick
|
||||
|
||||
i64 applied_user_deltas_count = 0;
|
||||
P_Delta **applied_user_deltas = PushStructsNoZero(frame_arena, P_Delta *, input->cmds.count);
|
||||
for (P_CmdNode *cmd_node = input->cmds.first; cmd_node; cmd_node = cmd_node->next)
|
||||
|
||||
{
|
||||
b32 tiles_dirty = 0;
|
||||
for (P_CmdNode *cmd_node = user_cmds.first; cmd_node; cmd_node = cmd_node->next)
|
||||
{
|
||||
P_Cmd *cmd = &cmd_node->cmd;
|
||||
if (cmd->kind == P_CmdKind_Delta)
|
||||
{
|
||||
P_Delta *delta = &cmd->delta;
|
||||
b32 allow = 0;
|
||||
b32 forward = 0;
|
||||
if (delta->kind == P_DeltaKind_Reset)
|
||||
if (cmd->kind == P_CmdKind_ResetWorld)
|
||||
{
|
||||
allow = 1;
|
||||
forward = 1;
|
||||
// TODO
|
||||
}
|
||||
if (delta->kind == P_DeltaKind_RawEnt)
|
||||
if (cmd->kind == P_CmdKind_EntEdit)
|
||||
{
|
||||
allow = 1;
|
||||
P_EntList ents = Zi;
|
||||
P_Ent *dst = P_PushTempEnt(frame_arena, &ents);
|
||||
*dst = cmd->ent;
|
||||
P_SpawnEntsFromList(world_frame, ents);
|
||||
}
|
||||
if (delta->kind == P_DeltaKind_Tile)
|
||||
if (cmd->kind == P_CmdKind_TileEdit)
|
||||
{
|
||||
allow = 1;
|
||||
forward = 1;
|
||||
P_TileKind tile = cmd->tile_kind;
|
||||
Rng2I32 range = cmd->tile_range;
|
||||
for (i32 tile_y = range.p0.y; tile_y < range.p1.y; ++tile_y)
|
||||
{
|
||||
for (i32 tile_x = range.p0.x; tile_x < range.p1.x; ++tile_x)
|
||||
{
|
||||
Vec2 tile_pos = VEC2(tile_x, tile_y);
|
||||
i32 tile_idx = P_TileIdxFromTilePos(tile_pos);
|
||||
world->tiles[tile_idx] = (u8)tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (forward)
|
||||
{
|
||||
applied_user_deltas[applied_user_deltas_count] = delta;
|
||||
applied_user_deltas_count += 1;
|
||||
}
|
||||
if (allow)
|
||||
{
|
||||
P_DeltaNode tmp_delta_node = Zi;
|
||||
tmp_delta_node.delta = *delta;
|
||||
|
||||
P_SnapshotNode tmp_snapshot_node = Zi;
|
||||
tmp_snapshot_node.snapshot.deltas_count = 1;
|
||||
tmp_snapshot_node.snapshot.first_delta_node = &tmp_delta_node;
|
||||
tmp_snapshot_node.snapshot.last_delta_node = &tmp_delta_node;
|
||||
|
||||
P_SnapshotList tmp_snapshot_list = Zi;
|
||||
tmp_snapshot_list.count = 1;
|
||||
tmp_snapshot_list.first = &tmp_snapshot_node;
|
||||
tmp_snapshot_list.last = &tmp_snapshot_node;
|
||||
|
||||
P_UpdateWorldFromSnapshots(world, tmp_snapshot_list);
|
||||
}
|
||||
}
|
||||
// TODO: Hash tiles here
|
||||
// if (tiles_dirty)
|
||||
// {
|
||||
// }
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@ -208,7 +281,7 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
ent->fire_presses = 0;
|
||||
}
|
||||
|
||||
for (P_CmdNode *cmd_node = input->cmds.first; cmd_node; cmd_node = cmd_node->next)
|
||||
for (P_CmdNode *cmd_node = user_cmds.first; cmd_node; cmd_node = cmd_node->next)
|
||||
{
|
||||
P_Cmd cmd = cmd_node->cmd;
|
||||
if (cmd.kind == P_CmdKind_Control)
|
||||
@ -1237,20 +1310,6 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
snapshot->tick = world_frame->tick;
|
||||
snapshot->time_ns = world_frame->time_ns;
|
||||
|
||||
// Forward user edit deltas
|
||||
for (i64 applied_user_delta_idx = 0; applied_user_delta_idx < applied_user_deltas_count; ++applied_user_delta_idx)
|
||||
{
|
||||
P_Delta *delta = 0;
|
||||
{
|
||||
P_DeltaNode *dn = PushStruct(output->arena, P_DeltaNode);
|
||||
snapshot->deltas_count += 1;
|
||||
SllQueuePush(snapshot->first_delta_node, snapshot->last_delta_node, dn);
|
||||
delta = &dn->delta;
|
||||
}
|
||||
P_Delta *src = applied_user_deltas[applied_user_delta_idx];
|
||||
*delta = *src;
|
||||
}
|
||||
|
||||
// Push full tile delta
|
||||
if (!has_sent_initial_tick)
|
||||
{
|
||||
@ -1320,13 +1379,13 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
for (i64 prune_idx = 0; prune_idx < ents_to_prune_count; ++prune_idx)
|
||||
{
|
||||
// FIXME: Add to freelist
|
||||
// FIXME: Ensure sure prunes are received by user
|
||||
P_Ent *ent = ents_to_prune[prune_idx];
|
||||
P_EntBin *bin = &world_frame->ent_bins[ent->key.v % world_frame->ent_bins_count];
|
||||
DllQueueRemoveNP(bin->first, bin->last, ent, next_in_bin, prev_in_bin);
|
||||
DllQueueRemove(world_frame->first_ent, world_frame->last_ent, ent);
|
||||
DllQueueRemoveNPZ(&P_NilEnt, world_frame->first_ent, world_frame->last_ent, ent, next, prev);
|
||||
world_frame->ents_count -= 1;
|
||||
SllStackPush(world->first_free_ent, ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -37,17 +37,25 @@ V_Cmd *V_PushVisCmd(String name)
|
||||
cmd->name = name;
|
||||
}
|
||||
++frame->cmds_count;
|
||||
SllQueuePush(frame->first_cmd_node, frame->last_cmd_node, cmd_node);
|
||||
DllQueuePush(frame->first_cmd_node, frame->last_cmd_node, cmd_node);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
P_Cmd *V_PushSimCmd(P_CmdKind kind)
|
||||
{
|
||||
// FIXME: Free list
|
||||
Arena *perm = PermArena();
|
||||
P_CmdNode *n = PushStruct(perm, P_CmdNode);
|
||||
P_CmdNode *n = V.first_free_sim_cmd_node;
|
||||
if (n)
|
||||
{
|
||||
SllStackPop(V.first_free_sim_cmd_node);
|
||||
ZeroStruct(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = PushStruct(perm, P_CmdNode);
|
||||
}
|
||||
n->cmd.kind = kind;
|
||||
SllQueuePush(V.sim_cmds.first, V.sim_cmds.last, n);
|
||||
DllQueuePush(V.sim_cmds.first, V.sim_cmds.last, n);
|
||||
++V.sim_cmds.count;
|
||||
return &n->cmd;
|
||||
}
|
||||
@ -1002,7 +1010,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Place tiles
|
||||
|
||||
// TODO: Push vis cmd
|
||||
// TODO: Push vis cmd instead
|
||||
|
||||
if (frame->is_editing && prev_frame->is_selecting && !frame->is_selecting)
|
||||
{
|
||||
@ -1013,10 +1021,9 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
tile_range.p0 = Vec2I32FromVec(FloorVec2(MulXformV2(frame->xf.world_to_tile, prev_frame->world_selection.p0)));
|
||||
tile_range.p1 = Vec2I32FromVec(CeilVec2(MulXformV2(frame->xf.world_to_tile, prev_frame->world_selection.p1)));
|
||||
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Delta);
|
||||
cmd->delta.kind = P_DeltaKind_Tile;
|
||||
cmd->delta.tile_kind = prev_frame->equipped_tile;
|
||||
cmd->delta.tile_range = tile_range;
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_TileEdit);
|
||||
cmd->tile_kind = prev_frame->equipped_tile;
|
||||
cmd->tile_range = tile_range;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2234,12 +2241,20 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||
{
|
||||
UI_BuildLabelF("World seed: 0x%F", FmtHex(blend_world->seed));
|
||||
UI_BuildLabelF("Entities count: %F", FmtSint(blend_world->last_frame->ents_count));
|
||||
UI_BuildLabelF("Sim world seed: 0x%F", FmtHex(sim_world->seed));
|
||||
UI_BuildLabelF("Sim world tick: %F", FmtSint(sim_world->last_frame->tick));
|
||||
UI_BuildLabelF("Sim world entities: %F", FmtSint(sim_world->last_frame->ents_count));
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||
UI_BuildLabelF("Predict world seed: 0x%F", FmtHex(predict_world->seed));
|
||||
UI_BuildLabelF("Predict world tick: %F", FmtSint(predict_world->last_frame->tick));
|
||||
UI_BuildLabelF("Predict world entities: %F", FmtSint(predict_world->last_frame->ents_count));
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||
UI_BuildLabelF("Blend world seed: 0x%F", FmtHex(blend_world->seed));
|
||||
UI_BuildLabelF("Blend world tick: %F", FmtSint(blend_world->last_frame->tick));
|
||||
UI_BuildLabelF("Blend world entities: %F", FmtSint(blend_world->last_frame->ents_count));
|
||||
}
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||
{
|
||||
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
|
||||
Vec2 tile_pos = MulXformV2(frame->xf.world_to_tile, frame->world_cursor);
|
||||
Vec2 cell_pos = MulXformV2(frame->xf.world_to_cell, frame->world_cursor);
|
||||
i32 tile_idx = P_TileIdxFromTilePos(tile_pos);
|
||||
@ -2521,8 +2536,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Vec2 player_pos = VEC2(5, 0);
|
||||
if (kind == V_CmdKind_reset_world)
|
||||
{
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Delta);
|
||||
cmd->delta.kind = P_DeltaKind_Reset;
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_ResetWorld);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2530,9 +2544,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
// Spawn player
|
||||
{
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Delta);
|
||||
cmd->delta.kind = P_DeltaKind_RawEnt;
|
||||
P_Ent *ent = &cmd->delta.ent;
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_EntEdit);
|
||||
P_Ent *ent = &cmd->ent;
|
||||
*ent = P_NilEnt;
|
||||
ent->key = V.player_key;
|
||||
ent->xf = XformFromPos(player_pos);
|
||||
@ -2544,9 +2557,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
case V_CmdKind_spawn_dummy:
|
||||
{
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Delta);
|
||||
cmd->delta.kind = P_DeltaKind_RawEnt;
|
||||
P_Ent *ent = &cmd->delta.ent;
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_EntEdit);
|
||||
P_Ent *ent = &cmd->ent;
|
||||
*ent = P_NilEnt;
|
||||
ent->key = P_RandKey();
|
||||
ent->xf = XformFromPos(frame->world_cursor);
|
||||
@ -2559,9 +2571,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
if (!P_IsEntNil(hovered_ent))
|
||||
{
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Delta);
|
||||
cmd->delta.kind = P_DeltaKind_RawEnt;
|
||||
P_Ent *ent = &cmd->delta.ent;
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_EntEdit);
|
||||
P_Ent *ent = &cmd->ent;
|
||||
ent->key = hovered_ent->key;
|
||||
ent->exists = 0;
|
||||
}
|
||||
@ -2571,7 +2582,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
if (frame->is_editing)
|
||||
{
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Save);
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_SaveWorld);
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -2617,16 +2628,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
}
|
||||
|
||||
// Push control cmd
|
||||
{
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Control);
|
||||
cmd->target = V.player_key;
|
||||
cmd->move = frame->move;
|
||||
cmd->look = frame->look;
|
||||
cmd->fire_held = frame->fire_held;
|
||||
cmd->fire_presses = frame->fire_presses;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2646,9 +2647,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
UnlockTicketMutex(&P.sim_output_back_tm);
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
//- Apply sim snapshots
|
||||
|
||||
@ -2699,6 +2697,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
P_UpdateWorldFromSnapshots(sim_world, sim_snapshots);
|
||||
}
|
||||
|
||||
// TODO: Remove this
|
||||
P_ClearFrames(sim_world, I64Min, sim_world->last_frame->tick - 1);
|
||||
P_Frame *sim_frame = sim_world->last_frame;
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2708,21 +2710,46 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Submit sim commands
|
||||
|
||||
i64 predict_to = sim_world->last_frame->tick + 10;
|
||||
frame->predict_to = sim_world->last_frame->tick + 1;
|
||||
if (frame->predict_to != prev_frame->predict_to)
|
||||
{
|
||||
// Push control cmd
|
||||
{
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Control);
|
||||
cmd->target = V.player_key;
|
||||
cmd->move = frame->move;
|
||||
cmd->look = frame->look;
|
||||
cmd->fire_held = frame->fire_held;
|
||||
cmd->fire_presses = frame->fire_presses;
|
||||
}
|
||||
|
||||
LockTicketMutex(&P.sim_input_back_tm);
|
||||
{
|
||||
P_InputState *v2s = &P.sim_input_states[P.sim_input_back_idx];
|
||||
for (P_CmdNode *src = V.sim_cmds.first; src; src = src->next)
|
||||
for (P_CmdNode *src_cmd_node = V.sim_cmds.first; src_cmd_node; src_cmd_node = src_cmd_node->next)
|
||||
{
|
||||
P_CmdNode *cmd_node = PushStruct(v2s->arena, P_CmdNode);
|
||||
cmd_node->cmd = src->cmd;
|
||||
cmd_node->cmd.tick = predict_to;
|
||||
SllQueuePush(v2s->cmds.first, v2s->cmds.last, cmd_node);
|
||||
if (src_cmd_node->cmd.kind == P_CmdKind_EntEdit)
|
||||
{
|
||||
DEBUGBREAKABLE;
|
||||
}
|
||||
|
||||
P_CmdNode *dst_cmd_node = PushStruct(v2s->arena, P_CmdNode);
|
||||
dst_cmd_node->cmd = src_cmd_node->cmd;
|
||||
dst_cmd_node->cmd.tick = frame->predict_to;
|
||||
DllQueuePush(v2s->cmds.first, v2s->cmds.last, dst_cmd_node);
|
||||
++v2s->cmds.count;
|
||||
}
|
||||
}
|
||||
UnlockTicketMutex(&P.sim_input_back_tm);
|
||||
if (V.sim_cmds.first)
|
||||
{
|
||||
V.sim_cmds.last->next = V.first_free_sim_cmd_node;
|
||||
V.first_free_sim_cmd_node = V.sim_cmds.first;
|
||||
}
|
||||
V.sim_cmds.first = 0;
|
||||
V.sim_cmds.last = 0;
|
||||
V.sim_cmds.count = 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
@ -2750,7 +2777,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
// {
|
||||
// P_CmdNode *n = PushStructNoZero(frame->arena, P_CmdNode);
|
||||
// *n = *src;
|
||||
// SllQueuePush(step_cmds.first, step_cmds.last, n);
|
||||
// DllQueuePush(step_cmds.first, step_cmds.last, n);
|
||||
// ++step_cmds.count;
|
||||
// }
|
||||
|
||||
@ -2775,9 +2802,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
// TODO: Remove this
|
||||
P_Frame *blend_frame = 0;
|
||||
{
|
||||
// P_ResetWorldFromFrame(blended_world, predict_world->last_frame);
|
||||
// P_Frame *blend_frame = blended_world->last_frame;
|
||||
blend_frame = predict_frame;
|
||||
P_ClearFrames(blend_world, I64Min, I64Max);
|
||||
blend_frame = P_PushFrame(blend_world, sim_world->last_frame, sim_world->last_frame->tick);
|
||||
}
|
||||
|
||||
|
||||
@ -3206,85 +3232,85 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Debug draw
|
||||
|
||||
// {
|
||||
// // Copy debug draw data from sim
|
||||
{
|
||||
// Copy debug draw data from sim
|
||||
// if (received_unseen_tick)
|
||||
// {
|
||||
// ResetArena(sim_debug_arena);
|
||||
// first_sim_debug_draw_node = 0;
|
||||
// last_sim_debug_draw_node = 0;
|
||||
// {
|
||||
// i64 dst_idx = 0;
|
||||
// P_DebugDrawNode *dst_nodes = PushStructsNoZero(sim_debug_arena, P_DebugDrawNode, sim_output->debug_draw_nodes_count);
|
||||
// for (P_DebugDrawNode *src = sim_output->first_debug_draw_node; src; src = src->next)
|
||||
// {
|
||||
// P_DebugDrawNode *dst = &dst_nodes[dst_idx];
|
||||
// *dst = *src;
|
||||
// dst_idx += 1;
|
||||
// SllQueuePush(first_sim_debug_draw_node, last_sim_debug_draw_node, dst);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
{
|
||||
ResetArena(sim_debug_arena);
|
||||
first_sim_debug_draw_node = 0;
|
||||
last_sim_debug_draw_node = 0;
|
||||
{
|
||||
i64 dst_idx = 0;
|
||||
P_DebugDrawNode *dst_nodes = PushStructsNoZero(sim_debug_arena, P_DebugDrawNode, sim_output->debug_draw_nodes_count);
|
||||
for (P_DebugDrawNode *src = sim_output->first_debug_draw_node; src; src = src->next)
|
||||
{
|
||||
P_DebugDrawNode *dst = &dst_nodes[dst_idx];
|
||||
*dst = *src;
|
||||
dst_idx += 1;
|
||||
SllQueuePush(first_sim_debug_draw_node, last_sim_debug_draw_node, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // Merge vis debug draws with sim debug draws
|
||||
// P_DebugDrawNode *first_debug_draw_node = first_sim_debug_draw_node;
|
||||
// P_DebugDrawNode *last_debug_draw_node = last_sim_debug_draw_node;
|
||||
// if (P_tl.first_debug_draw_node)
|
||||
// {
|
||||
// if (last_debug_draw_node)
|
||||
// {
|
||||
// last_debug_draw_node->next = P_tl.first_debug_draw_node;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// first_debug_draw_node = P_tl.first_debug_draw_node;
|
||||
// }
|
||||
// last_debug_draw_node = P_tl.last_debug_draw_node;
|
||||
// }
|
||||
// Merge vis debug draws with sim debug draws
|
||||
P_DebugDrawNode *first_debug_draw_node = first_sim_debug_draw_node;
|
||||
P_DebugDrawNode *last_debug_draw_node = last_sim_debug_draw_node;
|
||||
if (P_tl.first_debug_draw_node)
|
||||
{
|
||||
if (last_debug_draw_node)
|
||||
{
|
||||
last_debug_draw_node->next = P_tl.first_debug_draw_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_debug_draw_node = P_tl.first_debug_draw_node;
|
||||
}
|
||||
last_debug_draw_node = P_tl.last_debug_draw_node;
|
||||
}
|
||||
|
||||
// // Push draws
|
||||
// for (P_DebugDrawNode *n = first_debug_draw_node; n; n = n->next)
|
||||
// {
|
||||
// Vec4 color = Vec4FromU32(n->srgb32);
|
||||
// i32 detail = 24;
|
||||
// f32 radius = 5;
|
||||
// switch(n->kind)
|
||||
// {
|
||||
// case P_DebugDrawKind_Point:
|
||||
// {
|
||||
// Vec2 ui_p = MulXformV2(frame->xf.world_to_ui, n->point.p);
|
||||
// V_DrawPoint(ui_p, color);
|
||||
// } break;
|
||||
// Push draws
|
||||
for (P_DebugDrawNode *n = first_debug_draw_node; n; n = n->next)
|
||||
{
|
||||
Vec4 color = Vec4FromU32(n->srgb32);
|
||||
i32 detail = 24;
|
||||
f32 radius = 5;
|
||||
switch(n->kind)
|
||||
{
|
||||
case P_DebugDrawKind_Point:
|
||||
{
|
||||
Vec2 ui_p = MulXformV2(frame->xf.world_to_ui, n->point.p);
|
||||
V_DrawPoint(ui_p, color);
|
||||
} break;
|
||||
|
||||
// case P_DebugDrawKind_Line:
|
||||
// {
|
||||
// Vec2 ui_p0 = MulXformV2(frame->xf.world_to_ui, n->line.p0);
|
||||
// Vec2 ui_p1 = MulXformV2(frame->xf.world_to_ui, n->line.p1);
|
||||
// V_DrawLine(ui_p0, ui_p1, color);
|
||||
// } break;
|
||||
case P_DebugDrawKind_Line:
|
||||
{
|
||||
Vec2 ui_p0 = MulXformV2(frame->xf.world_to_ui, n->line.p0);
|
||||
Vec2 ui_p1 = MulXformV2(frame->xf.world_to_ui, n->line.p1);
|
||||
V_DrawLine(ui_p0, ui_p1, color);
|
||||
} break;
|
||||
|
||||
// case P_DebugDrawKind_Rect:
|
||||
// {
|
||||
// Rng2 ui_rect = Zi;
|
||||
// ui_rect.p0 = MulXformV2(frame->xf.world_to_ui, n->rect.p0);
|
||||
// ui_rect.p1 = MulXformV2(frame->xf.world_to_ui, n->rect.p1);
|
||||
// V_DrawRect(ui_rect, color, V_DrawFlag_Line);
|
||||
// } break;
|
||||
case P_DebugDrawKind_Rect:
|
||||
{
|
||||
Rng2 ui_rect = Zi;
|
||||
ui_rect.p0 = MulXformV2(frame->xf.world_to_ui, n->rect.p0);
|
||||
ui_rect.p1 = MulXformV2(frame->xf.world_to_ui, n->rect.p1);
|
||||
V_DrawRect(ui_rect, color, V_DrawFlag_Line);
|
||||
} break;
|
||||
|
||||
// case P_DebugDrawKind_Shape:
|
||||
// {
|
||||
// P_Shape ui_shape = P_MulXformShape(frame->xf.world_to_ui, n->shape);
|
||||
// V_DrawShape(ui_shape, color, detail, V_DrawFlag_Line);
|
||||
// } break;
|
||||
// }
|
||||
// }
|
||||
case P_DebugDrawKind_Shape:
|
||||
{
|
||||
P_Shape ui_shape = P_MulXformShape(frame->xf.world_to_ui, n->shape);
|
||||
V_DrawShape(ui_shape, color, detail, V_DrawFlag_Line);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
// // Reset vis debug draws
|
||||
// ResetArena(P_tl.debug_arena);
|
||||
// P_tl.first_debug_draw_node = 0;
|
||||
// P_tl.last_debug_draw_node = 0;
|
||||
// P_tl.debug_draw_nodes_count = 0;
|
||||
// }
|
||||
// Reset vis debug draws
|
||||
ResetArena(P_tl.debug_arena);
|
||||
P_tl.first_debug_draw_node = 0;
|
||||
P_tl.last_debug_draw_node = 0;
|
||||
P_tl.debug_draw_nodes_count = 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
@ -3560,29 +3586,28 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Prune ents
|
||||
|
||||
// {
|
||||
// i64 ents_to_prune_count = 0;
|
||||
// P_Ent **ents_to_prune = PushStructsNoZero(frame->arena, P_Ent *, world->ents_count);
|
||||
// for (P_Ent *ent = P_FirstEnt(world); ent->valid; ent = P_NextEnt(ent))
|
||||
// {
|
||||
// if (ent->exists <= 0)
|
||||
// {
|
||||
// ents_to_prune[ents_to_prune_count] = ent;
|
||||
// ents_to_prune_count += 1;
|
||||
// }
|
||||
// }
|
||||
|
||||
// for (i64 prune_idx = 0; prune_idx < ents_to_prune_count; ++prune_idx)
|
||||
// {
|
||||
// // FIXME: Add to free list
|
||||
// P_Ent *ent = ents_to_prune[prune_idx];
|
||||
// P_EntBin *bin = &world->ent_bins[ent->key.v % world->ent_bins_count];
|
||||
// DllQueueRemoveNP(bin->first, bin->last, ent, next_in_bin, prev_in_bin);
|
||||
// DllQueueRemove(world->first_ent, world->last_ent, ent);
|
||||
// world->ents_count -= 1;
|
||||
// }
|
||||
// }
|
||||
{
|
||||
i64 ents_to_prune_count = 0;
|
||||
P_Ent **ents_to_prune = PushStructsNoZero(frame->arena, P_Ent *, sim_frame->ents_count);
|
||||
for (P_Ent *ent = P_FirstEnt(sim_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
||||
{
|
||||
if (ent->exists <= 0)
|
||||
{
|
||||
ents_to_prune[ents_to_prune_count] = ent;
|
||||
ents_to_prune_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i64 prune_idx = 0; prune_idx < ents_to_prune_count; ++prune_idx)
|
||||
{
|
||||
P_Ent *ent = ents_to_prune[prune_idx];
|
||||
P_EntBin *bin = &sim_frame->ent_bins[ent->key.v % sim_frame->ent_bins_count];
|
||||
DllQueueRemoveNP(bin->first, bin->last, ent, next_in_bin, prev_in_bin);
|
||||
DllQueueRemoveNPZ(&P_NilEnt, sim_frame->first_ent, sim_frame->last_ent, ent, next, prev);
|
||||
sim_frame->ents_count -= 1;
|
||||
SllStackPush(sim_world->first_free_ent, ent);
|
||||
}
|
||||
}
|
||||
//////////////////////////////
|
||||
//- End frame
|
||||
|
||||
|
||||
@ -123,6 +123,7 @@ Struct(V_Cmd)
|
||||
Struct(V_CmdNode)
|
||||
{
|
||||
V_CmdNode *next;
|
||||
V_CmdNode *prev;
|
||||
V_Cmd cmd;
|
||||
};
|
||||
|
||||
@ -265,6 +266,8 @@ Struct(V_Frame)
|
||||
V_CmdNode *first_cmd_node;
|
||||
V_CmdNode *last_cmd_node;
|
||||
|
||||
i64 predict_to;
|
||||
|
||||
// Control
|
||||
Vec2 move;
|
||||
Vec2 look;
|
||||
@ -288,6 +291,7 @@ Struct(V_Ctx)
|
||||
|
||||
// Sim commands
|
||||
P_CmdList sim_cmds;
|
||||
P_CmdNode *first_free_sim_cmd_node;
|
||||
|
||||
// Atomic monotonically increasing allocation counter sequence for GPU particle ring buffer
|
||||
u32 particle_seq;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user