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_FrameBin *frame_bins;
|
||||||
P_Frame *first_free_frame;
|
P_Frame *first_free_frame;
|
||||||
|
|
||||||
|
u64 tiles_hash;
|
||||||
u8 *tiles;
|
u8 *tiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -219,7 +220,6 @@ Struct(P_DeltaNode)
|
|||||||
Struct(P_Snapshot)
|
Struct(P_Snapshot)
|
||||||
{
|
{
|
||||||
u64 world_seed;
|
u64 world_seed;
|
||||||
// i64 src_world_tick;
|
|
||||||
i64 src_tick;
|
i64 src_tick;
|
||||||
i64 tick;
|
i64 tick;
|
||||||
i64 time_ns;
|
i64 time_ns;
|
||||||
@ -233,34 +233,38 @@ Struct(P_Snapshot)
|
|||||||
i64 debug_draw_nodes_count;
|
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
|
//~ Message types
|
||||||
|
|
||||||
Enum(P_MsgKind)
|
Enum(P_MsgKind)
|
||||||
{
|
{
|
||||||
P_MsgKind_None,
|
P_MsgKind_None,
|
||||||
P_MsgKind_Tile,
|
P_MsgKind_Tiles,
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(P_Msg)
|
Struct(P_Msg)
|
||||||
{
|
{
|
||||||
|
P_MsgKind kind;
|
||||||
|
|
||||||
|
u64 tiles_hash;
|
||||||
Rng2I32 tile_range;
|
Rng2I32 tile_range;
|
||||||
u8 *raw_tiles;
|
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
|
//~ Collision types
|
||||||
|
|
||||||
@ -368,6 +372,7 @@ Enum(P_CmdKind)
|
|||||||
Struct(P_Cmd)
|
Struct(P_Cmd)
|
||||||
{
|
{
|
||||||
i64 tick;
|
i64 tick;
|
||||||
|
b32 predicted;
|
||||||
P_CmdKind kind;
|
P_CmdKind kind;
|
||||||
|
|
||||||
// Tile edit
|
// Tile edit
|
||||||
@ -410,7 +415,8 @@ Struct(P_OutputState)
|
|||||||
{
|
{
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
|
|
||||||
P_SnapshotList snapshots;
|
P_Snapshot snapshot;
|
||||||
|
P_MsgList msgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -36,7 +36,7 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
// FIXME: Header
|
// 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_CmdList queued_user_cmds = Zi;
|
||||||
P_CmdNode *first_free_user_cmd_node = 0;
|
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);
|
P_tl.debug_draw_enabled = TweakBool("Simulation debug draw", 1);
|
||||||
ResetArena(frame_arena);
|
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
|
//- Begin sim frame
|
||||||
|
|
||||||
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);
|
||||||
|
b32 tiles_dirty = 0;
|
||||||
|
|
||||||
// TDOO: Remove this
|
// TDOO: Remove this
|
||||||
P_ClearFrames(world, I64Min, prev_world_frame->tick - 1);
|
P_ClearFrames(world, I64Min, prev_world_frame->tick - 1);
|
||||||
|
|
||||||
|
|
||||||
i64 frame_begin_ns = TimeNs();
|
i64 frame_begin_ns = TimeNs();
|
||||||
i64 sim_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND;
|
i64 sim_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND;
|
||||||
f64 sim_dt = SecondsFromNs(sim_dt_ns);
|
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_min_tick = world_frame->tick - user_cmd_tick_range.min;
|
||||||
i64 user_cmds_max_tick = world_frame->tick + user_cmd_tick_range.max;
|
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;)
|
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)
|
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);
|
P_CmdNode *dst_cmd_node = PushStruct(frame_arena, P_CmdNode);
|
||||||
dst_cmd_node->cmd = src_cmd_node->cmd;
|
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);
|
DllQueuePush(user_cmds.first, user_cmds.last, dst_cmd_node);
|
||||||
++user_cmds.count;
|
++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
|
//- 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 accept world deltas from users that can edit
|
||||||
|
|
||||||
// FIXME: Only apply relevant cmds based on tick
|
// 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)
|
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;
|
||||||
@ -266,13 +277,17 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
world->tiles[tile_idx] = (u8)tile;
|
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);
|
LockTicketMutex(&P.sim_output_back_tm);
|
||||||
{
|
{
|
||||||
P_OutputState *output = &P.sim_output_states[P.sim_output_back_idx];
|
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;
|
// Build messages
|
||||||
SllQueuePush(output->snapshots.first, output->snapshots.last, snapshot_node);
|
{
|
||||||
++output->snapshots.count;
|
// 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->world_seed = world->seed;
|
||||||
snapshot->tick = world_frame->tick;
|
snapshot->tick = world_frame->tick;
|
||||||
snapshot->time_ns = world_frame->time_ns;
|
snapshot->time_ns = world_frame->time_ns;
|
||||||
|
|
||||||
// Push full tile delta
|
// Push entity deltas
|
||||||
// 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
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
P_Delta *delta = 0;
|
P_Delta *delta = 0;
|
||||||
@ -1366,6 +1385,7 @@ void S_TickForever(WaveLaneCtx *lane)
|
|||||||
P_tl.debug_draw_nodes_count = 0;
|
P_tl.debug_draw_nodes_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
UnlockTicketMutex(&P.sim_output_back_tm);
|
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, "\n").len;
|
||||||
result.len += StringF(arena, "seed: 0x%F\n", FmtHex(src_world->seed)).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;
|
result.len += StringF(arena, "time: %F\n", FmtSint(src_frame->time_ns)).len;
|
||||||
|
|
||||||
// Pack entities
|
// Pack entities
|
||||||
@ -100,10 +99,6 @@ P_UnpackedWorld P_UnpackWorld(Arena *arena, String packed)
|
|||||||
{
|
{
|
||||||
result.seed = CR_IntFromString(top_item->value);
|
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")))
|
if (MatchString(top_item->name, Lit("time")))
|
||||||
{
|
{
|
||||||
result.time_ns = CR_IntFromString(top_item->value);
|
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->ui_dims.y = MaxF32(frame->ui_dims.y, 64);
|
||||||
frame->draw_dims = frame->ui_dims;
|
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
|
//- Process controller events into vis cmds
|
||||||
|
|
||||||
@ -2631,10 +2520,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Pop sim output
|
//- Pop sim output
|
||||||
|
|
||||||
@ -2651,80 +2536,58 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
UnlockTicketMutex(&P.sim_output_back_tm);
|
UnlockTicketMutex(&P.sim_output_back_tm);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Apply sim snapshots
|
//- Apply sim msgs
|
||||||
|
|
||||||
// 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 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 *src_frame = P_FrameFromTick(sim_world, snapshot->src_tick);
|
||||||
P_Frame *dst_frame = P_PushFrame(sim_world, src_frame, snapshot->tick);
|
P_Frame *dst_frame = P_PushFrame(sim_world, src_frame, snapshot->tick);
|
||||||
sim_world->seed = snapshot->world_seed;
|
sim_world->seed = snapshot->world_seed;
|
||||||
dst_frame->time_ns = snapshot->time_ns;
|
dst_frame->time_ns = snapshot->time_ns;
|
||||||
|
|
||||||
// Apply deltas
|
//- Apply deltas
|
||||||
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;
|
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
|
//- Raw ent
|
||||||
else if (delta->kind == P_DeltaKind_RawEnt)
|
if (delta->kind == P_DeltaKind_RawEnt)
|
||||||
{
|
{
|
||||||
P_Ent tmp_ent = delta->ent;
|
P_Ent tmp_ent = delta->ent;
|
||||||
P_EntListNode tmp_ent_node = Zi;
|
P_EntListNode tmp_ent_node = Zi;
|
||||||
@ -2734,46 +2597,9 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
ent_list.last = &tmp_ent_node;
|
ent_list.last = &tmp_ent_node;
|
||||||
P_SpawnEntsFromList(dst_frame, ent_list);
|
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);
|
ResetArena(sim_debug_arena);
|
||||||
first_sim_debug_draw_node = 0;
|
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
|
// TODO: Remove this
|
||||||
@ -2830,6 +2644,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
// Push control cmd
|
// Push control cmd
|
||||||
{
|
{
|
||||||
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Control);
|
P_Cmd *cmd = V_PushSimCmd(P_CmdKind_Control);
|
||||||
|
cmd->predicted = 1;
|
||||||
cmd->target = V.player_key;
|
cmd->target = V.player_key;
|
||||||
cmd->move = frame->move;
|
cmd->move = frame->move;
|
||||||
cmd->look = frame->look;
|
cmd->look = frame->look;
|
||||||
@ -2874,6 +2689,12 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
// Predict
|
// Predict
|
||||||
P_Frame *predict_frame = 0;
|
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;
|
// i64 step_count = predict_to - sim_world->last_frame->tick;
|
||||||
|
|
||||||
// // TODO: Preserve constraints?
|
// // TODO: Preserve constraints?
|
||||||
@ -2912,20 +2733,24 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
//- Update blended world
|
//- Update blended world
|
||||||
|
|
||||||
|
|
||||||
|
b32 tiles_dirty = 0;
|
||||||
|
b32 should_clear_particles = 0;
|
||||||
|
|
||||||
// TODO: Remove this
|
// TODO: Remove this
|
||||||
P_Frame *blend_frame = 0;
|
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);
|
P_ClearFrames(blend_world, I64Min, I64Max);
|
||||||
blend_frame = P_PushFrame(blend_world, predict_world->last_frame, predict_world->last_frame->tick);
|
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