send tile data via msgs separate from snapshots
This commit is contained in:
parent
76ce604a45
commit
f5a9733525
38
src/pp/pp.h
38
src/pp/pp.h
@ -192,6 +192,7 @@ Struct(P_World)
|
||||
P_FrameBin *frame_bins;
|
||||
P_Frame *first_free_frame;
|
||||
|
||||
u64 tiles_hash;
|
||||
u8 *tiles;
|
||||
};
|
||||
|
||||
@ -219,7 +220,6 @@ Struct(P_DeltaNode)
|
||||
Struct(P_Snapshot)
|
||||
{
|
||||
u64 world_seed;
|
||||
// i64 src_world_tick;
|
||||
i64 src_tick;
|
||||
i64 tick;
|
||||
i64 time_ns;
|
||||
@ -233,34 +233,38 @@ Struct(P_Snapshot)
|
||||
i64 debug_draw_nodes_count;
|
||||
};
|
||||
|
||||
Struct(P_SnapshotNode)
|
||||
{
|
||||
P_SnapshotNode *next;
|
||||
P_Snapshot snapshot;
|
||||
};
|
||||
|
||||
Struct(P_SnapshotList)
|
||||
{
|
||||
i64 count;
|
||||
P_SnapshotNode *first;
|
||||
P_SnapshotNode *last;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Message types
|
||||
|
||||
Enum(P_MsgKind)
|
||||
{
|
||||
P_MsgKind_None,
|
||||
P_MsgKind_Tile,
|
||||
P_MsgKind_Tiles,
|
||||
};
|
||||
|
||||
Struct(P_Msg)
|
||||
{
|
||||
P_MsgKind kind;
|
||||
|
||||
u64 tiles_hash;
|
||||
Rng2I32 tile_range;
|
||||
u8 *raw_tiles;
|
||||
};
|
||||
|
||||
Struct(P_MsgNode)
|
||||
{
|
||||
P_MsgNode *next;
|
||||
P_MsgNode *prev;
|
||||
P_Msg msg;
|
||||
};
|
||||
|
||||
Struct(P_MsgList)
|
||||
{
|
||||
P_MsgNode *first;
|
||||
P_MsgNode *last;
|
||||
i64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Collision types
|
||||
|
||||
@ -368,6 +372,7 @@ Enum(P_CmdKind)
|
||||
Struct(P_Cmd)
|
||||
{
|
||||
i64 tick;
|
||||
b32 predicted;
|
||||
P_CmdKind kind;
|
||||
|
||||
// Tile edit
|
||||
@ -410,7 +415,8 @@ Struct(P_OutputState)
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
P_SnapshotList snapshots;
|
||||
P_Snapshot snapshot;
|
||||
P_MsgList msgs;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@ -36,7 +36,7 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
// FIXME: Header
|
||||
|
||||
Rng user_cmd_tick_range = RNG(0, SIM_TICKS_PER_SECOND * 0.5);
|
||||
Rng user_cmd_tick_range = RNG(0, SIM_TICKS_PER_SECOND * 1.0);
|
||||
P_CmdList queued_user_cmds = Zi;
|
||||
P_CmdNode *first_free_user_cmd_node = 0;
|
||||
|
||||
@ -60,62 +60,16 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
P_tl.debug_draw_enabled = TweakBool("Simulation debug draw", 1);
|
||||
ResetArena(frame_arena);
|
||||
|
||||
//////////////////////////////
|
||||
//- Swap
|
||||
|
||||
// {
|
||||
// b32 swapin = IsSwappedIn();
|
||||
// b32 swapout = shutdown && IsSwappingOut();
|
||||
|
||||
// //- Swap in
|
||||
// if (!world)
|
||||
// {
|
||||
// String packed = Zi;
|
||||
// if (swapin)
|
||||
// {
|
||||
// packed = SwappedStateFromName(frame_arena, Lit("pp_sim.swp"));
|
||||
// }
|
||||
// P_UnpackedWorld unpacked = P_UnpackWorld(frame_arena, packed);
|
||||
|
||||
// ResetArena(world_arena);
|
||||
// world = PushStruct(world_arena, P_World);
|
||||
// world->seed = unpacked.seed;
|
||||
// world_frame->tick = unpacked.tick;
|
||||
// world_frame->time_ns = unpacked.time_ns;
|
||||
// if (world->seed == 0)
|
||||
// {
|
||||
// TrueRand(StringFromStruct(&world->seed));
|
||||
// }
|
||||
|
||||
// world_frame->ent_bins_count = Kibi(16);
|
||||
// world_frame->ent_bins = PushStructs(world_arena, P_EntBin, world_frame->ent_bins_count);
|
||||
|
||||
// // Copy tiles
|
||||
// world->tiles = PushStructsNoZero(world_arena, u8, P_TilesCount);
|
||||
// CopyStructs(world->tiles, unpacked.tiles, P_TilesCount);
|
||||
|
||||
// // Copy ents
|
||||
// P_SpawnEntsFromList(world_arena, world, unpacked.ents);
|
||||
// }
|
||||
|
||||
// //- Swap out
|
||||
// if (swapout)
|
||||
// {
|
||||
// String packed = P_PackWorld(frame_arena, world);
|
||||
// WriteSwappedState(Lit("pp_sim.swp"), packed);
|
||||
// }
|
||||
// }
|
||||
|
||||
//////////////////////////////
|
||||
//- Begin sim frame
|
||||
|
||||
P_Frame *prev_world_frame = world->last_frame;
|
||||
P_Frame *world_frame = P_PushFrame(world, prev_world_frame, prev_world_frame->tick + 1);
|
||||
b32 tiles_dirty = 0;
|
||||
|
||||
// TDOO: Remove this
|
||||
P_ClearFrames(world, I64Min, prev_world_frame->tick - 1);
|
||||
|
||||
|
||||
i64 frame_begin_ns = TimeNs();
|
||||
i64 sim_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND;
|
||||
f64 sim_dt = SecondsFromNs(sim_dt_ns);
|
||||
@ -139,7 +93,7 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
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
|
||||
// Prune queued user cmds
|
||||
{
|
||||
for (P_CmdNode *cmd_node = queued_user_cmds.first; cmd_node;)
|
||||
{
|
||||
@ -184,10 +138,18 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
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)
|
||||
i64 cmd_tick = src_cmd_node->cmd.tick;
|
||||
if (!src_cmd_node->cmd.predicted)
|
||||
{
|
||||
// We can execute unpredicted cmds this frame, since they don't
|
||||
// need to be buffered to match predicted behavior
|
||||
cmd_tick = world_frame->tick;
|
||||
}
|
||||
if (cmd_tick == world_frame->tick)
|
||||
{
|
||||
P_CmdNode *dst_cmd_node = PushStruct(frame_arena, P_CmdNode);
|
||||
dst_cmd_node->cmd = src_cmd_node->cmd;
|
||||
dst_cmd_node->cmd.tick = cmd_tick;
|
||||
DllQueuePush(user_cmds.first, user_cmds.last, dst_cmd_node);
|
||||
++user_cmds.count;
|
||||
}
|
||||
@ -195,6 +157,57 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Swap
|
||||
|
||||
{
|
||||
b32 swapin = IsSwappedIn();
|
||||
b32 swapout = shutdown && IsSwappingOut();
|
||||
|
||||
//- Swap in
|
||||
if (world->last_frame->tick == 1)
|
||||
{
|
||||
String packed = Zi;
|
||||
if (swapin)
|
||||
{
|
||||
packed = SwappedStateFromName(frame_arena, Lit("pp_sim.swp"));
|
||||
}
|
||||
P_UnpackedWorld unpacked = P_UnpackWorld(frame_arena, packed);
|
||||
|
||||
world_frame = P_PushFrame(world, &P_NilFrame, world->last_frame->tick);
|
||||
|
||||
world->seed = unpacked.seed;
|
||||
world_frame->time_ns = unpacked.time_ns;
|
||||
if (world->seed == 0)
|
||||
{
|
||||
TrueRand(StringFromStruct(&world->seed));
|
||||
}
|
||||
|
||||
// Copy tiles
|
||||
CopyStructs(world->tiles, unpacked.tiles, P_TilesCount);
|
||||
|
||||
// Spawn ents
|
||||
P_SpawnEntsFromList(world_frame, unpacked.ents);
|
||||
|
||||
// Hash tiles
|
||||
{
|
||||
u64 old_tiles_hash = world->tiles_hash;
|
||||
world->tiles_hash = HashString(STRING(P_TilesCount, world->tiles));
|
||||
if (world->tiles_hash != old_tiles_hash)
|
||||
{
|
||||
tiles_dirty = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- Swap out
|
||||
if (swapout)
|
||||
{
|
||||
String packed = P_PackWorld(frame_arena, world);
|
||||
WriteSwappedState(Lit("pp_sim.swp"), packed);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Update double-buffered entity data
|
||||
|
||||
@ -225,15 +238,13 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
// }
|
||||
|
||||
//////////////////////////////
|
||||
//- Process user world delta commands
|
||||
//- Process user edit commands
|
||||
|
||||
// FIXME: Only accept world deltas from users that can edit
|
||||
|
||||
// FIXME: Only apply relevant cmds based on tick
|
||||
|
||||
|
||||
{
|
||||
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;
|
||||
@ -266,13 +277,17 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
world->tiles[tile_idx] = (u8)tile;
|
||||
}
|
||||
}
|
||||
// Hash tiles
|
||||
{
|
||||
u64 old_tiles_hash = world->tiles_hash;
|
||||
world->tiles_hash = HashString(STRING(P_TilesCount, world->tiles));
|
||||
if (world->tiles_hash != old_tiles_hash)
|
||||
{
|
||||
tiles_dirty = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Hash tiles here
|
||||
// if (tiles_dirty)
|
||||
// {
|
||||
// }
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@ -1305,33 +1320,37 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
LockTicketMutex(&P.sim_output_back_tm);
|
||||
{
|
||||
P_OutputState *output = &P.sim_output_states[P.sim_output_back_idx];
|
||||
P_SnapshotNode *snapshot_node = PushStruct(output->arena, P_SnapshotNode);
|
||||
P_Snapshot *snapshot = &snapshot_node->snapshot;
|
||||
SllQueuePush(output->snapshots.first, output->snapshots.last, snapshot_node);
|
||||
++output->snapshots.count;
|
||||
|
||||
// Build messages
|
||||
{
|
||||
// Push tiles
|
||||
if (tiles_dirty)
|
||||
{
|
||||
P_Msg *msg = 0;
|
||||
{
|
||||
P_MsgNode *msg_node = PushStruct(output->arena, P_MsgNode);
|
||||
DllQueuePush(output->msgs.first, output->msgs.last, msg_node);
|
||||
++output->msgs.count;
|
||||
msg = &msg_node->msg;
|
||||
}
|
||||
msg->kind = P_MsgKind_Tiles;
|
||||
msg->tiles_hash = world->tiles_hash;
|
||||
msg->raw_tiles = PushStructsNoZero(output->arena, u8, P_TilesCount);
|
||||
msg->tile_range = RNG2I32(VEC2I32(0, 0), VEC2I32(P_TilesPitch, P_TilesPitch));
|
||||
CopyBytes(msg->raw_tiles, world->tiles, P_TilesCount);
|
||||
has_sent_initial_tick = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Build snapshot
|
||||
{
|
||||
P_Snapshot *snapshot = &output->snapshot;
|
||||
|
||||
snapshot->world_seed = world->seed;
|
||||
snapshot->tick = world_frame->tick;
|
||||
snapshot->time_ns = world_frame->time_ns;
|
||||
|
||||
// Push full tile delta
|
||||
// if (!has_sent_initial_tick)
|
||||
// {
|
||||
// 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;
|
||||
// }
|
||||
// delta->kind = P_DeltaKind_RawTiles;
|
||||
// delta->raw_tiles = PushStructsNoZero(output->arena, u8, P_TilesCount);
|
||||
// delta->tile_range = RNG2I32(VEC2I32(0, 0), VEC2I32(P_TilesPitch, P_TilesPitch));
|
||||
// CopyBytes(delta->raw_tiles, world->tiles, P_TilesCount);
|
||||
// has_sent_initial_tick = 1;
|
||||
// }
|
||||
|
||||
// Push raw entity deltas
|
||||
// Push entity deltas
|
||||
for (P_Ent *ent = P_FirstEnt(world_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
||||
{
|
||||
P_Delta *delta = 0;
|
||||
@ -1366,6 +1385,7 @@ void S_TickForever(WaveLaneCtx *lane)
|
||||
P_tl.debug_draw_nodes_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
UnlockTicketMutex(&P.sim_output_back_tm);
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
@ -12,7 +12,6 @@ String P_PackWorld(Arena *arena, P_World *src_world)
|
||||
|
||||
result.len += StringF(arena, "\n").len;
|
||||
result.len += StringF(arena, "seed: 0x%F\n", FmtHex(src_world->seed)).len;
|
||||
result.len += StringF(arena, "tick: %F\n", FmtSint(src_frame->tick)).len;
|
||||
result.len += StringF(arena, "time: %F\n", FmtSint(src_frame->time_ns)).len;
|
||||
|
||||
// Pack entities
|
||||
@ -100,10 +99,6 @@ P_UnpackedWorld P_UnpackWorld(Arena *arena, String packed)
|
||||
{
|
||||
result.seed = CR_IntFromString(top_item->value);
|
||||
}
|
||||
if (MatchString(top_item->name, Lit("tick")))
|
||||
{
|
||||
result.tick = CR_IntFromString(top_item->value);
|
||||
}
|
||||
if (MatchString(top_item->name, Lit("time")))
|
||||
{
|
||||
result.time_ns = CR_IntFromString(top_item->value);
|
||||
|
||||
@ -639,117 +639,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
frame->ui_dims.y = MaxF32(frame->ui_dims.y, 64);
|
||||
frame->draw_dims = frame->ui_dims;
|
||||
|
||||
// //////////////////////////////
|
||||
// //- Pop sim output
|
||||
|
||||
// P_OutputState *sim_output = 0;
|
||||
// LockTicketMutex(&P.sim_output_back_tm);
|
||||
// {
|
||||
// sim_output = &P.sim_output_states[P.sim_output_back_idx];
|
||||
// ++P.sim_output_back_idx;
|
||||
// if (P.sim_output_back_idx >= countof(P.sim_output_states))
|
||||
// {
|
||||
// P.sim_output_back_idx = 0;
|
||||
// }
|
||||
// }
|
||||
// UnlockTicketMutex(&P.sim_output_back_tm);
|
||||
|
||||
// //////////////////////////////
|
||||
// //- Apply sim snapshots
|
||||
|
||||
// // FIXME: Only apply latest snapshot
|
||||
|
||||
|
||||
|
||||
// // FIXME: Real ping
|
||||
// i64 ping_ns = NsFromSeconds(0.250);
|
||||
|
||||
// // TODO: Remove this (testing)
|
||||
|
||||
|
||||
|
||||
// // b32 received_unseen_tick = 0;
|
||||
// // b32 tiles_dirty = 0;
|
||||
// // b32 should_clear_particles = 0;
|
||||
// // for (P_SnapshotNode *n = sim_output->first_snapshot_node; n; n = n->next)
|
||||
// // {
|
||||
// // P_Snapshot *snapshot = &n->snapshot;
|
||||
// // if (snapshot->tick > world->tick)
|
||||
// // {
|
||||
// // world->seed = snapshot->seed;
|
||||
// // world->tick = snapshot->tick;
|
||||
// // world->time_ns = snapshot->time_ns;
|
||||
// // for (P_DeltaNode *dn = snapshot->first_delta_node; dn; dn = dn->next)
|
||||
// // {
|
||||
// // P_Delta *delta = &dn->delta;
|
||||
// // if (delta->kind == P_DeltaKind_Reset)
|
||||
// // {
|
||||
// // tiles_dirty = 1;
|
||||
// // should_clear_particles = 1;
|
||||
// // }
|
||||
// // if (delta->kind == P_DeltaKind_RawTiles || delta->kind == P_DeltaKind_Tile)
|
||||
// // {
|
||||
// // tiles_dirty = 1;
|
||||
// // }
|
||||
// // P_UpdateWorldFromDelta(world, delta);
|
||||
// // }
|
||||
// // received_unseen_tick = 1;
|
||||
// // }
|
||||
// // }
|
||||
|
||||
|
||||
// {
|
||||
// P_SnapshotList sim_snapshots = sim_output->snapshots;
|
||||
// P_UpdateWorldFromSnapshots(sim_world, sim_snapshots);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// //////////////////////////////
|
||||
// //- Update tiles from sim
|
||||
|
||||
// {
|
||||
// for (P_SnapshotNode *n = sim_output->first_snapshot_node; n; n = n->next)
|
||||
// {
|
||||
// P_Snapshot *snapshot = &n->snapshot;
|
||||
// if (snapshot->tick > world->tick)
|
||||
// {
|
||||
// for (u64 placement_idx = 0; placement_idx < snapshot->tile_placements_count; ++placement_idx)
|
||||
// {
|
||||
// P_TilePlacement placement = snapshot->tile_placements[placement_idx];
|
||||
// Rng2I32 dirty_rect = P_UpdateTilesInPlaceFromPlacement(tiles, placement);
|
||||
// G_CopyCpuToTexture(
|
||||
// frame->cl,
|
||||
// gpu_tiles, VEC3I32(dirty_rect.p0.x, dirty_rect.p0.y, 0),
|
||||
// tiles, VEC3I32(tiles_dims.x, tiles_dims.y, 1),
|
||||
// RNG3I32(VEC3I32(dirty_rect.p0.x, dirty_rect.p0.y, 0), VEC3I32(dirty_rect.p1.x, dirty_rect.p1.y, 1))
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// //////////////////////////////
|
||||
// //- Update world from sim
|
||||
|
||||
// if (sim_output->last_snapshot_node && sim_output->last_snapshot_node->snapshot.tick > world->tick)
|
||||
// {
|
||||
// ResetArena(world_arena);
|
||||
// world = P_WorldFromSnapshot(world_arena, &sim_output->last_snapshot_node->snapshot);
|
||||
// V.lookup = P_LookupFromWorld(world_arena, world);
|
||||
|
||||
// // Copy sim debug info
|
||||
// sim_debug_draw_descs_count = sim_output->debug_draw_descs_count;
|
||||
// sim_debug_draw_descs = PushStructsNoZero(world_arena, P_DebugDrawDesc, sim_debug_draw_descs_count);
|
||||
// CopyStructs(sim_debug_draw_descs, sim_output->debug_draw_descs, sim_debug_draw_descs_count);
|
||||
// }
|
||||
|
||||
//////////////////////////////
|
||||
//- Process controller events into vis cmds
|
||||
|
||||
@ -2631,10 +2520,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
//- Pop sim output
|
||||
|
||||
@ -2651,80 +2536,58 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
UnlockTicketMutex(&P.sim_output_back_tm);
|
||||
|
||||
//////////////////////////////
|
||||
//- Apply sim snapshots
|
||||
|
||||
// FIXME: Only apply latest snapshot
|
||||
|
||||
|
||||
// TODO: Remove this (testing)
|
||||
|
||||
|
||||
|
||||
// b32 received_unseen_tick = 0;
|
||||
// b32 tiles_dirty = 0;
|
||||
// b32 should_clear_particles = 0;
|
||||
// for (P_SnapshotNode *n = sim_output->first_snapshot_node; n; n = n->next)
|
||||
// {
|
||||
// P_Snapshot *snapshot = &n->snapshot;
|
||||
// if (snapshot->tick > world->tick)
|
||||
// {
|
||||
// world->seed = snapshot->seed;
|
||||
// world->tick = snapshot->tick;
|
||||
// world->time_ns = snapshot->time_ns;
|
||||
// for (P_DeltaNode *dn = snapshot->first_delta_node; dn; dn = dn->next)
|
||||
// {
|
||||
// P_Delta *delta = &dn->delta;
|
||||
// if (delta->kind == P_DeltaKind_Reset)
|
||||
// {
|
||||
// tiles_dirty = 1;
|
||||
// should_clear_particles = 1;
|
||||
// }
|
||||
// if (delta->kind == P_DeltaKind_RawTiles || delta->kind == P_DeltaKind_Tile)
|
||||
// {
|
||||
// tiles_dirty = 1;
|
||||
// }
|
||||
// P_UpdateWorldFromDelta(world, delta);
|
||||
// }
|
||||
// received_unseen_tick = 1;
|
||||
// }
|
||||
// }
|
||||
//- Apply sim msgs
|
||||
|
||||
// Apply msgs
|
||||
{
|
||||
// P_Msg
|
||||
for (P_MsgNode *msg_node = sim_output->msgs.first; msg_node; msg_node = msg_node->next)
|
||||
{
|
||||
P_Msg *msg = &msg_node->msg;
|
||||
|
||||
//- Tiles
|
||||
if (msg->kind == P_MsgKind_Tiles && sim_world->tiles_hash != msg->tiles_hash)
|
||||
{
|
||||
Rng2I32 range = msg->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 = msg->raw_tiles[src_tile_idx];
|
||||
|
||||
Vec2 tile_pos = VEC2(tile_x, tile_y);
|
||||
i32 tile_idx = P_TileIdxFromTilePos(tile_pos);
|
||||
sim_world->tiles_hash = msg->tiles_hash;
|
||||
sim_world->tiles[tile_idx] = src_tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply snapshot
|
||||
//////////////////////////////
|
||||
//- Apply sim snapshots
|
||||
|
||||
{
|
||||
if (sim_output->snapshots.last && sim_output->snapshots.last->snapshot.tick > sim_world->last_frame->tick)
|
||||
P_Snapshot *snapshot = &sim_output->snapshot;
|
||||
b32 skip_snapshot = 0;
|
||||
skip_snapshot = snapshot->tick < sim_world->last_frame->tick;
|
||||
if (!skip_snapshot)
|
||||
{
|
||||
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
|
||||
//- 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)
|
||||
if (delta->kind == P_DeltaKind_RawEnt)
|
||||
{
|
||||
P_Ent tmp_ent = delta->ent;
|
||||
P_EntListNode tmp_ent_node = Zi;
|
||||
@ -2734,46 +2597,9 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
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
|
||||
//- Update sim debug info
|
||||
{
|
||||
ResetArena(sim_debug_arena);
|
||||
first_sim_debug_draw_node = 0;
|
||||
@ -2790,19 +2616,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
@ -2830,6 +2644,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
// Push control cmd
|
||||
{
|
||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Control);
|
||||
cmd->predicted = 1;
|
||||
cmd->target = V.player_key;
|
||||
cmd->move = frame->move;
|
||||
cmd->look = frame->look;
|
||||
@ -2874,6 +2689,12 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
// Predict
|
||||
P_Frame *predict_frame = 0;
|
||||
{
|
||||
if (predict_world->tiles_hash != sim_world->tiles_hash)
|
||||
{
|
||||
predict_world->tiles_hash = sim_world->tiles_hash;
|
||||
CopyStructs(predict_world->tiles, sim_world->tiles, P_TilesCount);
|
||||
}
|
||||
|
||||
// i64 step_count = predict_to - sim_world->last_frame->tick;
|
||||
|
||||
// // TODO: Preserve constraints?
|
||||
@ -2912,20 +2733,24 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//- Update blended world
|
||||
|
||||
|
||||
b32 tiles_dirty = 0;
|
||||
b32 should_clear_particles = 0;
|
||||
|
||||
// TODO: Remove this
|
||||
P_Frame *blend_frame = 0;
|
||||
{
|
||||
if (blend_world->tiles_hash != predict_world->tiles_hash)
|
||||
{
|
||||
blend_world->tiles_hash = predict_world->tiles_hash;
|
||||
CopyStructs(blend_world->tiles, predict_world->tiles, P_TilesCount);
|
||||
tiles_dirty = 1;
|
||||
}
|
||||
|
||||
P_ClearFrames(blend_world, I64Min, I64Max);
|
||||
blend_frame = P_PushFrame(blend_world, predict_world->last_frame, predict_world->last_frame->tick);
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Compare tile hashes
|
||||
b32 tiles_dirty = 0;
|
||||
b32 should_clear_particles = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user