move sim debug draw data into snapshot

This commit is contained in:
jacob 2026-01-13 12:59:41 -06:00
parent 8bae9d0da2
commit 76ce604a45
4 changed files with 191 additions and 187 deletions

View File

@ -1176,103 +1176,6 @@ P_World *P_AcquireWorld(void)
return world; return world;
} }
void P_UpdateWorldFromSnapshots(P_World *world, P_SnapshotList snapshots)
{
b32 tiles_dirty = 0;
for (P_SnapshotNode *n = snapshots.first; n; n = n->next)
{
P_Snapshot *snapshot = &n->snapshot;
// FIXME: Process intermediate ticks
if (snapshot->tick > world->last_frame->tick)
{
P_Frame *src_frame = P_FrameFromTick(world, snapshot->src_tick);
P_Frame *frame = P_PushFrame(world, src_frame, snapshot->tick);
world->seed = snapshot->world_seed;
frame->time_ns = snapshot->time_ns;
for (P_DeltaNode *dn = snapshot->first_delta_node; dn; dn = dn->next)
{
P_Delta *delta = &dn->delta;
// FIXME: Bounds check tile deltas
if (0)
{
}
//- Reset
// 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)
{
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;
// }
}
}
// TODO: Rehash statics
// if (tiles_dirty)
// {
// }
}
void P_SpawnEntsFromList(P_Frame *frame, P_EntList ents) void P_SpawnEntsFromList(P_Frame *frame, P_EntList ents)
{ {
P_World *world = frame->world; P_World *world = frame->world;

View File

@ -30,6 +30,38 @@ Struct(P_Shape)
Vec2 points[8]; Vec2 points[8];
}; };
////////////////////////////////////////////////////////////
//~ Debug visualization types
Enum(P_DebugDrawKind)
{
P_DebugDrawKind_Point,
P_DebugDrawKind_Line,
P_DebugDrawKind_Rect,
P_DebugDrawKind_Shape,
};
Struct(P_DebugDrawNode)
{
P_DebugDrawNode *next;
P_DebugDrawKind kind;
u32 srgb32;
union
{
struct
{
Vec2 p;
} point;
struct
{
Vec2 p0;
Vec2 p1;
} line;
Rng2 rect;
P_Shape shape;
};
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Ent types //~ Ent types
@ -163,19 +195,19 @@ Struct(P_World)
u8 *tiles; u8 *tiles;
}; };
////////////////////////////////////////////////////////////
//~ Snapshot types
Enum(P_DeltaKind) Enum(P_DeltaKind)
{ {
P_DeltaKind_Reset, P_DeltaKind_None,
P_DeltaKind_RawEnt, P_DeltaKind_RawEnt,
P_DeltaKind_RawTiles,
}; };
Struct(P_Delta) Struct(P_Delta)
{ {
P_DeltaKind kind; P_DeltaKind kind;
P_Ent ent; P_Ent ent;
Rng2I32 tile_range;
u8 *raw_tiles;
}; };
Struct(P_DeltaNode) Struct(P_DeltaNode)
@ -195,6 +227,10 @@ Struct(P_Snapshot)
i64 deltas_count; i64 deltas_count;
P_DeltaNode *first_delta_node; P_DeltaNode *first_delta_node;
P_DeltaNode *last_delta_node; P_DeltaNode *last_delta_node;
P_DebugDrawNode *first_debug_draw_node;
P_DebugDrawNode *last_debug_draw_node;
i64 debug_draw_nodes_count;
}; };
Struct(P_SnapshotNode) Struct(P_SnapshotNode)
@ -210,6 +246,21 @@ Struct(P_SnapshotList)
P_SnapshotNode *last; P_SnapshotNode *last;
}; };
////////////////////////////////////////////////////////////
//~ Message types
Enum(P_MsgKind)
{
P_MsgKind_None,
P_MsgKind_Tile,
};
Struct(P_Msg)
{
Rng2I32 tile_range;
u8 *raw_tiles;
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Collision types //~ Collision types
@ -301,38 +352,6 @@ Struct(P_Constraint)
P_ContactPoint points[2]; P_ContactPoint points[2];
}; };
////////////////////////////////////////////////////////////
//~ Debug visualization types
Enum(P_DebugDrawKind)
{
P_DebugDrawKind_Point,
P_DebugDrawKind_Line,
P_DebugDrawKind_Rect,
P_DebugDrawKind_Shape,
};
Struct(P_DebugDrawNode)
{
P_DebugDrawNode *next;
P_DebugDrawKind kind;
u32 srgb32;
union
{
struct
{
Vec2 p;
} point;
struct
{
Vec2 p0;
Vec2 p1;
} line;
Rng2 rect;
P_Shape shape;
};
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Command types //~ Command types
@ -392,10 +411,6 @@ Struct(P_OutputState)
Arena *arena; Arena *arena;
P_SnapshotList snapshots; P_SnapshotList snapshots;
P_DebugDrawNode *first_debug_draw_node;
P_DebugDrawNode *last_debug_draw_node;
i64 debug_draw_nodes_count;
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -509,7 +524,6 @@ void P_DebugDrawShape(P_Shape shape, Vec4 srgb);
//~ World //~ World
P_World *P_AcquireWorld(void); P_World *P_AcquireWorld(void);
void P_UpdateWorldFromSnapshots(P_World *world, P_SnapshotList snapshots);
void P_SpawnEntsFromList(P_Frame *frame, P_EntList ents); void P_SpawnEntsFromList(P_Frame *frame, P_EntList ents);
P_Frame *P_FrameFromTick(P_World *world, i64 tick); P_Frame *P_FrameFromTick(P_World *world, i64 tick);

View File

@ -1315,21 +1315,21 @@ void S_TickForever(WaveLaneCtx *lane)
snapshot->time_ns = world_frame->time_ns; snapshot->time_ns = world_frame->time_ns;
// Push full tile delta // Push full tile delta
if (!has_sent_initial_tick) // if (!has_sent_initial_tick)
{ // {
P_Delta *delta = 0; // P_Delta *delta = 0;
{ // {
P_DeltaNode *dn = PushStruct(output->arena, P_DeltaNode); // P_DeltaNode *dn = PushStruct(output->arena, P_DeltaNode);
snapshot->deltas_count += 1; // snapshot->deltas_count += 1;
SllQueuePush(snapshot->first_delta_node, snapshot->last_delta_node, dn); // SllQueuePush(snapshot->first_delta_node, snapshot->last_delta_node, dn);
delta = &dn->delta; // delta = &dn->delta;
} // }
delta->kind = P_DeltaKind_RawTiles; // delta->kind = P_DeltaKind_RawTiles;
delta->raw_tiles = PushStructsNoZero(output->arena, u8, P_TilesCount); // delta->raw_tiles = PushStructsNoZero(output->arena, u8, P_TilesCount);
delta->tile_range = RNG2I32(VEC2I32(0, 0), VEC2I32(P_TilesPitch, P_TilesPitch)); // delta->tile_range = RNG2I32(VEC2I32(0, 0), VEC2I32(P_TilesPitch, P_TilesPitch));
CopyBytes(delta->raw_tiles, world->tiles, P_TilesCount); // CopyBytes(delta->raw_tiles, world->tiles, P_TilesCount);
has_sent_initial_tick = 1; // has_sent_initial_tick = 1;
} // }
// Push raw entity deltas // Push raw entity deltas
for (P_Ent *ent = P_FirstEnt(world_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) for (P_Ent *ent = P_FirstEnt(world_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
@ -1348,15 +1348,17 @@ void S_TickForever(WaveLaneCtx *lane)
// Push debug draw information // Push debug draw information
{ {
i64 dst_idx = 0; i64 dst_idx = 0;
P_DebugDrawNode *dst_nodes = PushStructsNoZero(output->arena, P_DebugDrawNode, P_tl.debug_draw_nodes_count); snapshot->first_debug_draw_node = 0;
snapshot->last_debug_draw_node = 0;
snapshot->debug_draw_nodes_count = P_tl.debug_draw_nodes_count;
P_DebugDrawNode *dst_nodes = PushStructsNoZero(output->arena, P_DebugDrawNode, snapshot->debug_draw_nodes_count);
for (P_DebugDrawNode *src = P_tl.first_debug_draw_node; src; src = src->next) for (P_DebugDrawNode *src = P_tl.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(output->first_debug_draw_node, output->last_debug_draw_node, dst); SllQueuePush(snapshot->first_debug_draw_node, snapshot->last_debug_draw_node, dst);
} }
output->debug_draw_nodes_count += P_tl.debug_draw_nodes_count;
ResetArena(P_tl.debug_arena); ResetArena(P_tl.debug_arena);
P_tl.first_debug_draw_node = 0; P_tl.first_debug_draw_node = 0;

View File

@ -876,7 +876,7 @@ void V_TickForever(WaveLaneCtx *lane)
else else
{ {
Vec2 look_ratio = Zi; Vec2 look_ratio = Zi;
look_ratio.y = 0.25; look_ratio.y = 0.5;
look_ratio.x = look_ratio.y / (16.0 / 9.0); look_ratio.x = look_ratio.y / (16.0 / 9.0);
P_Ent *player = P_EntFromKey(blend_world->last_frame, V.player_key); P_Ent *player = P_EntFromKey(blend_world->last_frame, V.player_key);
Vec2 player_center = P_WorldShapeFromEnt(player).centroid; Vec2 player_center = P_WorldShapeFromEnt(player).centroid;
@ -2689,11 +2689,120 @@ void V_TickForever(WaveLaneCtx *lane)
// } // }
// } // }
// Apply msgs
// Apply snapshots to sim world
{ {
P_SnapshotList sim_snapshots = sim_output->snapshots; // P_Msg
P_UpdateWorldFromSnapshots(sim_world, sim_snapshots); }
// Apply snapshot
{
if (sim_output->snapshots.last && sim_output->snapshots.last->snapshot.tick > sim_world->last_frame->tick)
{
P_Snapshot *snapshot = &sim_output->snapshots.last->snapshot;
P_Frame *src_frame = P_FrameFromTick(sim_world, snapshot->src_tick);
P_Frame *dst_frame = P_PushFrame(sim_world, src_frame, snapshot->tick);
sim_world->seed = snapshot->world_seed;
dst_frame->time_ns = snapshot->time_ns;
// Apply deltas
for (P_DeltaNode *dn = snapshot->first_delta_node; dn; dn = dn->next)
{
P_Delta *delta = &dn->delta;
// FIXME: Bounds check tile deltas
if (0)
{
}
//- Reset
// else if (delta->kind == P_DeltaKind_Reset)
// {
// // FIXME: Freelist entities
// dst_frame->ents_count = 0;
// dst_frame->first_ent = 0;
// dst_frame->last_ent = 0;
// ZeroStructs(sim_world->tiles, P_TilesCount);
// ZeroStructs(dst_frame->ent_bins, dst_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(dst_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);
// sim_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);
// sim_world->tiles[tile_idx] = (u8)tile;
// }
// }
// tiles_dirty = 1;
// }
}
// Update sim debug info
{
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, snapshot->debug_draw_nodes_count);
for (P_DebugDrawNode *src = snapshot->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);
}
}
}
// FIXME: Real prune
// for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
// {
// ent->exists = 0;
// }
}
// TODO: Rehash statics
// if (tiles_dirty)
// {
// }
} }
// TODO: Remove this // TODO: Remove this
@ -2710,8 +2819,8 @@ void V_TickForever(WaveLaneCtx *lane)
//- Submit sim commands //- Submit sim commands
// FIXME: Real ping // FIXME: Real ping
f64 ping = 0.250; // f64 ping = 0.250;
// f64 ping = 0; f64 ping = 0;
i64 ping_ns = NsFromSeconds(ping); i64 ping_ns = NsFromSeconds(ping);
frame->predict_to = sim_world->last_frame->tick + MaxF64(CeilF64(ping * SIM_TICKS_PER_SECOND), 1.0); frame->predict_to = sim_world->last_frame->tick + MaxF64(CeilF64(ping * SIM_TICKS_PER_SECOND), 1.0);
@ -2733,11 +2842,6 @@ void V_TickForever(WaveLaneCtx *lane)
P_InputState *v2s = &P.sim_input_states[P.sim_input_back_idx]; 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) 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); P_CmdNode *dst_cmd_node = PushStruct(v2s->arena, P_CmdNode);
dst_cmd_node->cmd = src_cmd_node->cmd; dst_cmd_node->cmd = src_cmd_node->cmd;
dst_cmd_node->cmd.tick = frame->predict_to; dst_cmd_node->cmd.tick = frame->predict_to;
@ -3243,25 +3347,6 @@ void V_TickForever(WaveLaneCtx *lane)
//- Debug draw //- Debug draw
{ {
// 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);
}
}
}
// 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;