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