attach player key to client

This commit is contained in:
jacob 2026-01-18 02:46:10 -06:00
parent 8e29fa447b
commit 1c0009fb21
9 changed files with 319 additions and 373 deletions

View File

@ -26,7 +26,7 @@ Struct(LogEventsArray)
#define LogLevel(l) (l <= LogLevel_CompTime)
// Log level configuration
// Compile-time log level configuration
#ifndef LogLevel_CompTime
#if IsRtcEnabled
#define LogLevel_CompTime LogLevel_Debug
@ -42,7 +42,8 @@ Struct(LogEventsArray)
#define LogLevel_Success 3
#define LogLevel_Info 4
#define LogLevel_Debug 5
#define LogLevel_COUNT 6
#define LogLevel_Trace 6
#define LogLevel_COUNT 7
////////////////////////////////////////////////////////////
//~ Log level types
@ -75,7 +76,11 @@ Global Readonly LogLevelSettings log_settings[LogLevel_COUNT] = {
[LogLevel_Debug] = {
CompLit("DEBUG"),
}
},
[LogLevel_Trace] = {
CompLit("TRACE"),
},
};
////////////////////////////////////////////////////////////
@ -129,6 +134,14 @@ Global Readonly LogLevelSettings log_settings[LogLevel_COUNT] = {
#define LogDebugF(...)
#endif
#if LogLevel(LogLevel_Trace)
#define LogTrace(msg) Log_(LogLevel_Trace, msg)
#define LogTraceF(fmt_lit, ...) LogF_(LogLevel_Trace, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd)
#else
#define LogTrace(msg)
#define LogTraceF(...)
#endif
////////////////////////////////////////////////////////////
//~ @hookdecl Log

View File

@ -546,15 +546,15 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
}
}
// LogDebugF(
// "Received msg packet. seq: %F, msg seq: %F, new bottom ack: %F, new ack bits: %F, should_process: %F, data: \"%F\"",
// FmtSint(header.seq),
// FmtSint(header.msg_seq),
// FmtSint(peer->bottom_ack),
// FmtUint(peer->ack_bits),
// FmtUint(should_process),
// FmtString(src_data)
// );
LogTraceF(
"Received msg packet. seq: %F, msg seq: %F, new bottom ack: %F, new ack bits: %F, should_process: %F, data: \"%F\"",
FmtSint(header.seq),
FmtSint(header.msg_seq),
FmtSint(peer->bottom_ack),
FmtUint(peer->ack_bits),
FmtUint(should_process),
FmtString(src_data)
);
}
}
}
@ -596,7 +596,7 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
(pipe->last_attempted_bind_ns == 0 || now_ns - pipe->last_attempted_bind_ns > bind_retry_threshold_ns)
)
{
// LogDebugF("Binding to port \"%F\"", FmtUint(desired_port));
LogTraceF("Binding to port \"%F\"", FmtUint(desired_port));
b32 ok = 1;
String port_str = StringF(scratch.arena, "%F", FmtUint(desired_port));
@ -829,11 +829,11 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
msg_data.text = ArenaNext(msg_buff->arena, u8);
msg_data.len = 0;
// LogSuccessF(
// "Assembled msg with msg seq: %F, data (%F bytes)",
// FmtSint(packet->msg_seq),
// FmtUint(msg->data.len)
// );
LogTraceF(
"Assembled msg with msg seq: %F, data (%F bytes)",
FmtSint(packet->msg_seq),
FmtUint(msg->data.len)
);
}
}
else
@ -873,7 +873,7 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
String src_data = cmd->data;
i64 src_pos = 0;
i64 msg_seq = ++peer->msg_seq;
// LogDebugF("Queued msg with seq %F", FmtSint(msg_seq));
LogTraceF("Queued msg with seq %F", FmtSint(msg_seq));
// TODO: Raw packets
@ -1052,12 +1052,12 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
);
Atomic64FetchAdd(&pipe->total_bytes_sent, buff_len);
// LogDebugF(
// "Sent msg packet. seq: %F, msg seq: %F, data: \"%F\"",
// FmtSint(header.seq),
// FmtSint(header.msg_seq),
// FmtString(packet->data)
// );
LogTraceF(
"Sent msg packet. seq: %F, msg seq: %F, data: \"%F\"",
FmtSint(header.seq),
FmtSint(header.msg_seq),
FmtString(packet->data)
);
}
}
}

View File

@ -156,7 +156,7 @@ P_Shape P_LocalShapeFromEnt(P_Ent *ent)
P_Shape result = Zi;
// TODO: This is a temporary hack. We should eventually switch to using a prefab lookup table.
if (ent->is_player)
if (ent->is_guy)
{
result = P_ShapeFromDesc(
.mass = 10,
@ -164,13 +164,13 @@ P_Shape P_LocalShapeFromEnt(P_Ent *ent)
.radius = 0.3,
);
// f32 player_width = 0.6;
// f32 player_height = 0.3;
// f32 guy_width = 0.6;
// f32 guy_height = 0.3;
// result = P_ShapeFromDesc(
// .mass = 10,
// .count = 2,
// .points = { VEC2(-player_width / 2 + (player_height / 2), 0), VEC2(player_width / 2 - (player_height / 2), 0) },
// .radius = player_height / 2,
// .points = { VEC2(-guy_width / 2 + (guy_height / 2), 0), VEC2(guy_width / 2 - (guy_height / 2), 0) },
// .radius = guy_height / 2,
// );
// Rng2 test_rect = Zi;
@ -1474,7 +1474,7 @@ void P_StepFrame(P_Frame *frame)
// {
// desired_xf = XformWithWorldRotation(xf, AngleFromVec2(ent->control.look));
// }
// f32 move_speed = TweakFloat("Player move speed", 6.5, 0, 20);
// f32 move_speed = TweakFloat("Guy move speed", 6.5, 0, 20);
// desired_xf.og = AddVec2(xf.og, MulVec2(ent->control.move, move_speed * sim_dt));
// Vec2 pos_diff = SubVec2(desired_xf.og, xf.og);
@ -1488,7 +1488,7 @@ void P_StepFrame(P_Frame *frame)
if (Vec2Len(ent->solved_v) > 0.001)
{
f32 damp_force = TweakFloat("Player damp force", 50, 0, 100);
f32 damp_force = TweakFloat("Guy damp force", 50, 0, 100);
Vec2 damp = MulVec2(NegVec2(ent->solved_v), damp_force * sim_dt);
ent->solved_v = AddVec2(ent->solved_v, damp);
}
@ -1500,8 +1500,8 @@ void P_StepFrame(P_Frame *frame)
}
{
f32 move_force = TweakFloat("Player move force", 400, 0, 400);
f32 max_speed = TweakFloat("Player max speed", 10, 0, 20);
f32 move_force = TweakFloat("Guy move force", 400, 0, 400);
f32 max_speed = TweakFloat("Guy max speed", 10, 0, 20);
Vec2 new_velocity = ent->solved_v;
new_velocity = AddVec2(new_velocity, MulVec2(ent->control.move, move_force * sim_dt));
@ -1518,7 +1518,7 @@ void P_StepFrame(P_Frame *frame)
//////////////////////////////
//- Generate player wall constraints
//- Generate guy wall constraints
@ -2032,7 +2032,7 @@ void P_StepFrame(P_Frame *frame)
f32 closest_len_sq = Inf;
for (P_Ent *victim = P_FirstEnt(frame); !P_IsEntNil(victim); victim = P_NextEnt(victim))
{
if (victim->is_player && !P_MatchKey(victim->key, bullet->bullet_firer))
if (victim->is_guy && !P_MatchKey(victim->key, bullet->bullet_firer))
{
P_Shape victim_world_shape = P_WorldShapeFromEnt(victim);

View File

@ -99,7 +99,7 @@ Struct(P_Ent)
f32 exists;
b32 is_player;
b32 is_guy;
b32 is_dummy;
f32 health;
@ -121,14 +121,11 @@ Struct(P_Ent)
P_Control control;
//- User
//- Player
b32 is_user;
b32 is_player;
P_Key player;
// FIXME: Ensure this field isn't transmitted in snapshots
NET_Key net;
P_Key guy;
u8 string_len;
u8 string_text[P_MaxPlayerNameLen + 8];
@ -290,9 +287,9 @@ Struct(P_SimSnapshot)
};
////////////////////////////////////////////////////////////
//~ User snapshot types
//~ Player snapshot types
Struct(P_UserSnapshot)
Struct(P_PlayerSnapshot)
{
i64 tick;
@ -319,6 +316,7 @@ Enum(P_MsgKind)
P_MsgKind_ResetWorld,
P_MsgKind_TileEdit,
P_MsgKind_EntEdit,
P_MsgKind_Delete,
// Server -> Client
P_MsgKind_Tiles,
@ -334,7 +332,8 @@ Struct(P_Msg)
Rng2I32 tile_range;
u64 tiles_hash;
P_Ent ent;
P_Key key;
Vec2 pos;
String data;
};

View File

@ -98,7 +98,7 @@ void S_TickForever(WaveLaneCtx *lane)
b32 tiles_dirty = 0;
// TODO: Remove this
// TODO: Keep old frames around for user snapshot deltas
// TODO: Keep old frames around for player snapshot deltas
P_ClearFrames(world, I64Min, prev_world_frame->tick - 1);
i64 frame_begin_ns = TimeNs();
@ -251,6 +251,62 @@ void S_TickForever(WaveLaneCtx *lane)
}
}
//////////////////////////////
//- Create player entities (networked version of clients)
{
P_EntList new_players = Zi;
for (S_Client *client = S.first_client; !S_IsClientNil(client); client = client->next)
{
if (P_IsKeyNil(client->player_key))
{
client->player_key = P_RandKey();
}
P_Ent *player = P_EntFromKey(world_frame, client->player_key);
if (P_IsEntNil(player))
{
player = P_PushTempEnt(frame_arena, &new_players);
player->key = client->player_key;
}
player->is_player = 1;
// Update name
{
i64 name_len = client->name_len;
name_len = MinI64(name_len, P_MaxPlayerNameLen);
name_len = MinI64(name_len, countof(player->string_text));
player->string_len = name_len;
CopyBytes(player->string_text, client->name_text, player->string_len);
}
}
P_SpawnEntsFromList(world_frame, new_players);
}
//////////////////////////////
//- Create guy entities
{
P_EntList new_guys = Zi;
for (P_Ent *player = P_FirstEnt(world_frame); !P_IsEntNil(player); player = P_NextEnt(player))
{
if (player->is_player)
{
if (P_IsKeyNil(player->guy))
{
player->guy = P_RandKey();
}
P_Ent *guy = P_EntFromKey(world_frame, player->guy);
if (P_IsEntNil(guy))
{
guy = P_PushTempEnt(frame_arena, &new_guys);
guy->key = player->guy;
}
guy->is_guy = 1;
guy->has_weapon = 1;
}
}
P_SpawnEntsFromList(world_frame, new_guys);
}
//////////////////////////////
//- Process connection messages
@ -259,25 +315,25 @@ void S_TickForever(WaveLaneCtx *lane)
// {
// P_Msg *msg = &msg_node->msg;
// //- Register user
// //- Register player
// if (msg->kind == P_MsgKind_RegisterUser)
// {
// P_Key user_key = msg->src_user;
// P_Ent *user = P_EntFromKey(world_frame, user_key);
// if (P_EntIsNil(user))
// P_Ent *player = P_EntFromKey(world_frame, user_key);
// if (P_EntIsNil(player))
// {
// P_EntList tmp_list = Zi;
// user = P_PushTempEnt(frame_arena, &tmp_list);
// user->key = user_key;
// user->is_user = 1;
// user->exists = 1;
// player = P_PushTempEnt(frame_arena, &tmp_list);
// player->key = user_key;
// player->is_user = 1;
// player->exists = 1;
// // FIXME: Set net key here
// i32 min_name_len = P_MinPlayerNameLen;
// i32 max_name_len = P_MaxPlayerNameLen;
// // De-duplicate user name
// // De-duplicate player name
// String user_name = msg->data;
// user_name = TrimWhitespace(user_name);
// user_name.len = MinI64(user_name.len, max_name_len);
@ -311,7 +367,7 @@ void S_TickForever(WaveLaneCtx *lane)
// }
// }
// }
// P_SetEntString(user, user_name);
// P_SetEntString(player, user_name);
// P_Msg *msg = P_PushMsg(
// P_MsgKind_Chat,
// StringF(
@ -325,20 +381,20 @@ void S_TickForever(WaveLaneCtx *lane)
// }
// {
// P_Msg *msg = P_PushMsg(P_MsgKind_RegisterSuccess, Zstr);
// msg->dst_user = user->key;
// msg->dst_user = player->key;
// }
// }
// }
// }
//////////////////////////////
//- Apply user snapshots
//- Apply player snapshots
// P_MsgList user_msgs = Zi;
// {
// i64 user_msgs_min_tick = world_frame->tick + user_msg_tick_range.min;
// i64 user_msgs_max_tick = world_frame->tick + user_msg_tick_range.max;
// // Prune queued user msgs
// // Prune queued player msgs
// {
// for (P_MsgNode *msg_node = queued_user_msgs.first; msg_node;)
// {
@ -357,7 +413,7 @@ void S_TickForever(WaveLaneCtx *lane)
// msg_node = next;
// }
// }
// // Push user msgs to queue
// // Push player msgs to queue
// {
// for (P_MsgNode *src_msg_node = input->msgs.first; src_msg_node; src_msg_node = src_msg_node->next)
// {
@ -379,7 +435,7 @@ void S_TickForever(WaveLaneCtx *lane)
// }
// }
// }
// // Pop frame user msgs from queue
// // Pop frame player msgs from queue
// {
// for (P_MsgNode *src_msg_node = queued_user_msgs.first; src_msg_node;)
// {
@ -404,7 +460,7 @@ void S_TickForever(WaveLaneCtx *lane)
// }
//////////////////////////////
//- Process user edit messages
//- Process player edit messages
// FIXME: Only accept edits from privileged users
@ -414,27 +470,66 @@ void S_TickForever(WaveLaneCtx *lane)
{
P_Msg *msg = &msg_node->msg;
b32 allow = 0;
if (msg->kind == P_MsgKind_SaveWorld)
switch (msg->kind)
{
// FIXME: Only accept save from local user
//- Save world
case P_MsgKind_SaveWorld:
{
// FIXME: Only accept save from local player
should_save = 1;
}
if (msg->kind == P_MsgKind_ResetWorld)
} break;
//- Reset world
case P_MsgKind_ResetWorld:
{
// TODO: Real reset
for (P_Ent *ent = P_FirstEnt(world_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
{
ent->exists = 0;
}
}
if (msg->kind == P_MsgKind_EntEdit)
} break;
//- Edit entity
case P_MsgKind_EntEdit:
{
String name = msg->data;
P_EntList ents = Zi;
P_Ent *dst = P_PushTempEnt(frame_arena, &ents);
*dst = msg->ent;
P_SpawnEntsFromList(world_frame, ents);
// TODO: Enumerated prefabs
if (0)
{
}
if (msg->kind == P_MsgKind_TileEdit)
else if (MatchString(name, Lit("guy")))
{
P_Ent *ent = P_PushTempEnt(frame_arena, &ents);
*ent = P_NilEnt;
ent->key = msg->key;
ent->xf = XformFromPos(msg->pos);
ent->is_guy = 1;
ent->has_weapon = 1;
ent->exists = 1;
}
else if (MatchString(name, Lit("dummy")))
{
P_Ent *ent = P_PushTempEnt(frame_arena, &ents);
*ent = P_NilEnt;
ent->key = msg->key;
ent->xf = XformFromPos(msg->pos);
ent->is_guy = 1;
ent->is_dummy = 1;
ent->has_weapon = 1;
ent->exists = 1;
}
P_SpawnEntsFromList(world_frame, ents);
} break;
//- Delete entity
case P_MsgKind_Delete:
{
P_Ent *ent = P_EntFromKey(world_frame, msg->key);
if (!P_IsEntNil(ent))
{
ent->exists = 0;
}
} break;
//- Edit tiles
case P_MsgKind_TileEdit:
{
P_TileKind tile = msg->tile_kind;
Rng2I32 range = msg->tile_range;
@ -456,9 +551,10 @@ void S_TickForever(WaveLaneCtx *lane)
tiles_dirty = 1;
}
}
} break;
}
}
// Save world
// Commit world save
if (should_save)
{
String path = Lit("...");
@ -490,17 +586,17 @@ void S_TickForever(WaveLaneCtx *lane)
// ent->fire_presses = 0;
// }
// for (P_Ent *user = P_FirstEnt(frame); !P_IsEntNil(user); user = P_NextEnt(user))
// for (P_Ent *player = P_FirstEnt(frame); !P_IsEntNil(player); player = P_NextEnt(player))
// {
// if (user->is_iser)
// if (player->is_iser)
// {
// P_Ent *target = P_EntFromKey(user->player);
// P_Ent *target = P_EntFromKey(player->guy);
// if (!P_IsEntNil(target))
// {
// target->move = ClampVec2Len(user->move, 1);
// target->look = user->look;
// target->fire_held = user->fire_held;
// target->fire_presses += user->fire_presses;
// target->move = ClampVec2Len(player->move, 1);
// target->look = player->look;
// target->fire_held = player->fire_held;
// target->fire_presses += player->fire_presses;
// }
// }
// }
@ -517,7 +613,7 @@ void S_TickForever(WaveLaneCtx *lane)
//- Push tile messages
{
// TODO: Receive remote tile hashes via user snapshots
// TODO: Receive remote tile hashes via player snapshots
for (S_Client *client = S.first_client; !S_IsClientNil(client); client = client->next)
{
if (tiles_dirty || client->remote_tiles_hash != world->tiles_hash)
@ -536,13 +632,13 @@ void S_TickForever(WaveLaneCtx *lane)
//////////////////////////////
//- Push snapshot messages
// for (P_Ent *user = P_FirstEnt(world_frame); !P_IsEntNil(user); user = P_NextEnt(user))
// for (P_Ent *player = P_FirstEnt(world_frame); !P_IsEntNil(player); player = P_NextEnt(player))
// {
// if (user->is_user)
// if (player->is_user)
// {
// Arena *msgs_arena = P_tl.out_msgs_arena;
// P_Msg *msg = P_PushMsg(P_MsgKind_SimSnapshot, Zstr);
// msg->dst_user = user->key;
// msg->dst_user = player->key;
// NET_SendFlag_None = 1;
// P_SimSnapshot *snapshot = &msg->sim_snapshot;
// {
@ -648,6 +744,8 @@ void S_TickForever(WaveLaneCtx *lane)
BB_WriteIV(&packer_bbw, src_frame->tick);
BB_WriteIV(&packer_bbw, world_frame->tick);
BB_WriteIV(&packer_bbw, world_frame->time_ns);
BB_WriteUBits(&packer_bbw, world->seed, 64);
BB_WriteUBits(&packer_bbw, client->player_key.v, 64);
}
//- Append packed delta
@ -790,21 +888,21 @@ void S_TickForever(WaveLaneCtx *lane)
// {
// // Broadcast
// String packed = P_PackMessage(frame_arena, msg);
// for (P_Ent *user = P_FirstEnt(world_frame); !P_IsEntNil(user); user = P_NextEnt(user))
// for (P_Ent *player = P_FirstEnt(world_frame); !P_IsEntNil(player); player = P_NextEnt(player))
// {
// if (user->is_user)
// if (player->is_user)
// {
// NET_Send(net_pipe, user->net, packed, NET_SendFlag_None);
// NET_Send(net_pipe, player->net, packed, NET_SendFlag_None);
// }
// }
// }
// else
// {
// P_Ent *user = P_EntFromKey(world_frame, msg->dst_user);
// if (!NET_IsKeyNil(user->net))
// P_Ent *player = P_EntFromKey(world_frame, msg->dst_user);
// if (!NET_IsKeyNil(player->net))
// {
// String packed = P_PackMessage(frame_arena, msg);
// NET_Send(net_pipe, user->net, packed, NET_SendFlag_None);
// NET_Send(net_pipe, player->net, packed, NET_SendFlag_None);
// }
// }
// }
@ -823,21 +921,21 @@ void S_TickForever(WaveLaneCtx *lane)
// {
// // Broadcast
// String packed = P_PackMessage(frame_arena, msg);
// for (P_Ent *user = P_FirstEnt(world_frame); !P_IsEntNil(user); user = P_NextEnt(user))
// for (P_Ent *player = P_FirstEnt(world_frame); !P_IsEntNil(player); player = P_NextEnt(player))
// {
// if (user->is_user)
// if (player->is_user)
// {
// NET_Send(net_pipe, user->net, packed, NET_SendFlag_None);
// NET_Send(net_pipe, player->net, packed, NET_SendFlag_None);
// }
// }
// }
// else
// {
// P_Ent *user = P_EntFromKey(world_frame, msg->dst_user);
// if (!NET_IsKeyNil(user->net))
// P_Ent *player = P_EntFromKey(world_frame, msg->dst_user);
// if (!NET_IsKeyNil(player->net))
// {
// String packed = P_PackMessage(frame_arena, msg);
// NET_Send(net_pipe, user->net, packed, NET_SendFlag_None);
// NET_Send(net_pipe, player->net, packed, NET_SendFlag_None);
// }
// }
// }
@ -934,7 +1032,7 @@ void S_TickForever(WaveLaneCtx *lane)
for (i64 prune_idx = 0; prune_idx < ents_to_prune_count; ++prune_idx)
{
// FIXME: Ensure sure prunes are received by user
// FIXME: Ensure sure prunes are received by player
P_Ent *ent = ents_to_prune[prune_idx];
P_EntBin *bin = &world_frame->ent_bins[ent->key.v % world_frame->ent_bins_count];
DllQueueRemoveNP(bin->first, bin->last, ent, next_in_bin, prev_in_bin);

View File

@ -12,6 +12,8 @@ Struct(S_Client)
NET_Key net_key;
P_MsgList out_msgs;
P_Key player_key;
i32 name_len;
u8 name_text[P_MaxPlayerNameLen];

View File

@ -21,7 +21,16 @@ String P_PackWorld(Arena *arena, P_World *src_world)
for (P_Ent *ent = P_FirstEnt(src_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
{
// TODO: Pack bullets
if (!ent->is_bullet)
b32 should_pack = 1;
if (ent->is_bullet)
{
should_pack = 0;
}
if (ent->is_player)
{
should_pack = 0;
}
if (should_pack)
{
result.len += StringF(arena, " 0x%F:\n", FmtHex(ent->key.v)).len;
result.len += PushString(arena, Lit(" {\n")).len;
@ -33,6 +42,10 @@ String P_PackWorld(Arena *arena, P_World *src_world)
{
result.len += PushString(arena, Lit(" player\n")).len;
}
if (ent->is_guy)
{
result.len += PushString(arena, Lit(" guy\n")).len;
}
if (ent->is_dummy)
{
result.len += PushString(arena, Lit(" dummy\n")).len;
@ -129,6 +142,10 @@ P_UnpackedWorld P_UnpackWorld(Arena *arena, String packed)
{
ent->is_player = 1;
}
if (MatchString(prop->value, Lit("guy")))
{
ent->is_guy = 1;
}
if (MatchString(prop->value, Lit("dummy")))
{
ent->is_dummy = 1;

View File

@ -511,6 +511,9 @@ void V_TickForever(WaveLaneCtx *lane)
//////////////////////////////
//- Begin frame
b32 tiles_dirty = 0;
b32 should_clear_particles = 0;
V.current_frame_tick += 1;
V_Frame *prev_frame = V_PrevFrame();
V_Frame *frame = V_CurrentFrame();
@ -552,9 +555,9 @@ void V_TickForever(WaveLaneCtx *lane)
frame->dt = SecondsFromNs(frame->dt_ns);
frame->rand = prev_frame->rand;
if (P_IsKeyNil(V.user_key))
if (P_IsKeyNil(V.player_key))
{
TrueRand(StringFromStruct(&V.user_key));
TrueRand(StringFromStruct(&V.player_key));
}
//////////////////////////////
@ -586,7 +589,7 @@ void V_TickForever(WaveLaneCtx *lane)
//- Transcode swap state
if (swapout)
{
BB_WriteUBits(&bbw, V.user_key.v, 64);
BB_WriteUBits(&bbw, V.player_key.v, 64);
BB_WriteBit(&bbw, prev_frame->is_editing);
BB_WriteF32(&bbw, prev_frame->edit_camera_pos.x);
BB_WriteF32(&bbw, prev_frame->edit_camera_pos.y);
@ -595,7 +598,7 @@ void V_TickForever(WaveLaneCtx *lane)
}
else
{
V.user_key.v = BB_ReadUBits(&bbr, 64);
V.player_key.v = BB_ReadUBits(&bbr, 64);
frame->is_editing = BB_ReadBit(&bbr);
frame->edit_camera_pos.x = BB_ReadF32(&bbr);
frame->edit_camera_pos.y = BB_ReadF32(&bbr);
@ -652,7 +655,7 @@ void V_TickForever(WaveLaneCtx *lane)
//////////////////////////////
//- Pop sim -> user data
//- Pop sim -> vis data
{
LockTicketMutex(&P.s2v_tm);
@ -816,12 +819,12 @@ void V_TickForever(WaveLaneCtx *lane)
Vec2 look_ratio = Zi;
look_ratio.y = 0.5;
look_ratio.x = look_ratio.y / (16.0 / 9.0);
P_Ent *user = P_EntFromKey(blend_world->last_frame, V.user_key);
P_Ent *player = P_EntFromKey(blend_world->last_frame, user->player);
Vec2 player_center = P_WorldShapeFromEnt(player).centroid;
P_Ent *player = P_EntFromKey(blend_world->last_frame, V.player_key);
P_Ent *guy = P_EntFromKey(blend_world->last_frame, player->guy);
Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid;
Vec2 ui_center = MulVec2(frame->ui_dims, 0.5);
Vec2 look = MulXformBasisV2(prev_frame->xf.ui_to_world, SubVec2(ui_frame->cursor_pos, ui_center));
target_camera_pos = player_center;
target_camera_pos = guy_center;
target_camera_pos = AddVec2(target_camera_pos, MulVec2Vec2(look, look_ratio));
target_camera_zoom = 1;
}
@ -972,8 +975,8 @@ void V_TickForever(WaveLaneCtx *lane)
//////////////////////////////
//- Query entities
P_Ent *user = P_EntFromKey(blend_world->last_frame, V.user_key);
P_Ent *player = P_EntFromKey(blend_world->last_frame, user->player);
P_Ent *local_player = P_EntFromKey(blend_world->last_frame, V.player_key);
P_Ent *local_guy = P_EntFromKey(blend_world->last_frame, local_player->guy);
P_Ent *hovered_ent = &P_NilEnt;
{
// TODO: Real world query
@ -2382,10 +2385,13 @@ void V_TickForever(WaveLaneCtx *lane)
b32 minimized = 0;
// i32 console_level = minimized ? LogLevel_Success : LogLevel_Debug;
i32 console_level = LogLevel_Debug;
i32 console_level = LogLevel_Trace;
Vec4 colors[LogLevel_COUNT][2] = Zi;
SetBytes(colors, 0xFF, sizeof(colors));
// Trace colors
colors[LogLevel_Trace][0] = Rgb(0.1, 0.4, 0.4);
colors[LogLevel_Trace][1] = Rgb(0.2, 0.5, 0.5);
// Debug colors
colors[LogLevel_Debug][0] = Rgb(0.4, 0.1, 0.4);
colors[LogLevel_Debug][1] = Rgb(0.5, 0.2, 0.5);
@ -2607,49 +2613,66 @@ void V_TickForever(WaveLaneCtx *lane)
// case V_CmdKind_spawn:
// {
// // Reset world
// Vec2 player_pos = VEC2(5, 0);
// Vec2 guy_pos = VEC2(5, 0);
// if (kind == V_CmdKind_reset_world)
// {
// P_Msg *msg = P_PushMsg(P_MsgKind_ResetWorld, Zstr);
// }
// else
// {
// player_pos = frame->world_cursor;
// guy_pos = frame->world_cursor;
// }
// // Spawn player
// // Spawn guy
// {
// P_Msg *msg = P_PushMsg(P_MsgKind_EntEdit, Zstr);
// P_Ent *ent = &cmd->ent;
// *ent = P_NilEnt;
// ent->key = V.player_key;
// ent->xf = XformFromPos(player_pos);
// ent->is_player = 1;
// ent->key = V.guy_key;
// ent->xf = XformFromPos(guy_pos);
// ent->is_guy = 1;
// ent->has_weapon = 1;
// ent->exists = 1;
// }
// } break;
case V_CmdKind_reset_world:
case V_CmdKind_spawn:
{
// Reset world
Vec2 guy_pos = VEC2(5, 0);
if (kind == V_CmdKind_reset_world)
{
P_Msg *msg = P_PushMsg(P_MsgKind_ResetWorld, Zstr);
}
else
{
guy_pos = frame->world_cursor;
}
// Spawn player guy
{
P_Msg *msg = P_PushMsg(P_MsgKind_EntEdit, Lit("guy"));
msg->key = local_guy->key;
msg->pos = guy_pos;
if (P_IsKeyNil(msg->key))
{
msg->key = P_RandKey();
}
}
} break;
case V_CmdKind_spawn_dummy:
{
P_Msg *msg = P_PushMsg(P_MsgKind_EntEdit, Zstr);
P_Ent *ent = &msg->ent;
*ent = P_NilEnt;
ent->key = P_RandKey();
ent->xf = XformFromPos(frame->world_cursor);
ent->is_player = 1;
ent->is_dummy = 1;
ent->has_weapon = 1;
ent->exists = 1;
P_Msg *msg = P_PushMsg(P_MsgKind_EntEdit, Lit("dummy"));
msg->key = P_RandKey();
msg->pos = frame->world_cursor;
} break;
case V_CmdKind_delete:
{
if (!P_IsEntNil(hovered_ent))
{
P_Msg *msg = P_PushMsg(P_MsgKind_EntEdit, Zstr);
P_Ent *ent = &msg->ent;
ent->key = hovered_ent->key;
ent->exists = 0;
P_Msg *msg = P_PushMsg(P_MsgKind_Delete, Zstr);
msg->key = hovered_ent->key;
}
} break;
@ -2661,10 +2684,10 @@ void V_TickForever(WaveLaneCtx *lane)
// }
// } break;
// case V_CmdKind_clear_particles:
// {
// should_clear_particles = 1;
// } break;
case V_CmdKind_clear_particles:
{
should_clear_particles = 1;
} break;
case V_CmdKind_test:
{
@ -2709,8 +2732,7 @@ void V_TickForever(WaveLaneCtx *lane)
BB_ResetWriter(&packer_bbw);
String packed = P_PackMessages(&packer_bbw, tmp_msglist);
// FIXME: Real connection packet
NET_Send(net_pipe, frame->desired_sim_key, packed, NET_SendFlag_None);
NET_Send(net_pipe, frame->desired_sim_key, packed, NET_SendFlag_Raw);
V.connect_try_ns = now_ns;
}
}
@ -2764,85 +2786,6 @@ void V_TickForever(WaveLaneCtx *lane)
}
}
// P_MsgList in_msgs = Zi;
// {
// NET_Bind(net_pipe, 0);
// NET_MsgList net_msgs = NET_Swap(frame->arena, net_pipe);
// for (NET_Msg *net_msg = net_msgs.first; net_msg; net_msg = net_msg->next)
// {
// NET_Key net_key = net_msg->sender;
// String address_str = NET_StringFromKey(frame->arena, net_key);
// LogDebugF("Received message from server \"%F\"", FmtString(address_str));
// String packed = net_msg->data;
// P_MsgNode *dst_msg_node = PushStruct(frame->arena, P_MsgNode);
// P_Msg *dst_msg = &dst_msg_node->msg;
// *dst_msg = P_UnpackMsg(frame->arena, packed);
// // FIXME: Set src user here based on net key
// // dst_msg->src_user =
// DllQueuePush(in_msgs.first, in_msgs.last, dst_msg_node);
// ++in_msgs.count;
// }
// }
// {
// LockTicketMutex(&P.s2v_snapshot_mutex);
// P_SimSnapshot *src_snapshot = &P.s2v_snapshot;
// if (src_snapshot->tick > sim_snapshot.tick)
// {
// ResetArena(sim_snapshot_arena);
// ZeroStruct(&sim_snapshot);
// sim_snapshot.world_seed = src_snapshot->world_seed;
// sim_snapshot.src_tick = src_snapshot->src_tick;
// sim_snapshot.tick = src_snapshot->tick;
// sim_snapshot.time_ns = src_snapshot->time_ns;
// {
// //- Copy deltas
// {
// P_SimDeltaNode *dst_nodes = PushStructsNoZero(sim_snapshot_arena, P_SimDeltaNode, src_snapshot->deltas_count);
// for (P_SimDeltaNode *src_delta_node = src_snapshot->first_delta_node; src_delta_node; src_delta_node = src_delta_node->next)
// {
// P_SimDeltaNode *dst_delta_node = &dst_nodes[sim_snapshot.deltas_count];
// *dst_delta_node = *src_delta_node;
// SllQueuePush(sim_snapshot.first_delta_node, sim_snapshot.last_delta_node, dst_delta_node);
// sim_snapshot.deltas_count += 1;
// }
// }
// //- Copy debug info
// {
// P_DebugDrawNode *dst_nodes = PushStructsNoZero(sim_snapshot_arena, P_DebugDrawNode, src_snapshot->debug_draw_nodes_count);
// for (P_DebugDrawNode *src = src_snapshot->first_debug_draw_node; src; src = src->next)
// {
// P_DebugDrawNode *dst = &dst_nodes[sim_snapshot.debug_draw_nodes_count];
// *dst = *src;
// SllQueuePush(sim_snapshot.first_debug_draw_node, sim_snapshot.last_debug_draw_node, dst);
// sim_snapshot.debug_draw_nodes_count += 1;
// }
// }
// }
// ResetArena(P.s2v_snapshot_arena);
// ZeroStruct(&P.s2v_snapshot);
// }
// UnlockTicketMutex(&P.s2v_snapshot_mutex);
// }
//////////////////////////////
//- Apply sim snapshots
@ -2863,16 +2806,21 @@ void V_TickForever(WaveLaneCtx *lane)
i64 src_tick = BB_ReadIV(&bbr);
i64 dst_tick = BB_ReadIV(&bbr);
i64 time_ns = BB_ReadIV(&bbr);
u64 world_seed = BB_ReadUBits(&bbr, 64);
P_Key player_key = { .v = BB_ReadUBits(&bbr, 64) };
P_Frame *src_frame = P_FrameFromTick(sim_world, src_tick);
if (src_frame->tick == src_tick)
{
V.player_key = player_key;
P_Frame *dst_frame = P_FrameFromTick(sim_world, dst_tick);
if (P_IsFrameNil(dst_frame))
{
dst_frame = P_PushFrame(sim_world, src_frame, dst_tick);
}
dst_frame->time_ns = time_ns;
sim_world->seed = world_seed;
//- Read deltas
BB_ReadAlignToNextByte(&bbr);
@ -2909,14 +2857,6 @@ void V_TickForever(WaveLaneCtx *lane)
{
P_Msg *msg = &msg_node->msg;
// if (msg->kind == P_MsgKind_SimSnapshot && msg->sim_snapshot.tick > sim_world->last_frame->tick)
// {
// if (!newest_snapshot_msg || msg->sim_snapshot.tick > newest_snapshot_msg->sim_snapshot.tick)
// {
// newest_snapshot_msg = msg;
// }
// }
//- Chat
if (msg->kind == P_MsgKind_Chat)
{
@ -2952,54 +2892,6 @@ void V_TickForever(WaveLaneCtx *lane)
}
}
//////////////////////////////
//- Apply sim snapshot
// if (newest_snapshot_msg)
// {
// P_SimSnapshot *snapshot = &newest_snapshot_msg->sim_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_SimDeltaNode *dn = snapshot->first_delta_node; dn; dn = dn->next)
// {
// P_SimDelta *delta = &dn->delta;
// //- Raw ent
// if (delta->kind == P_SimDeltaKind_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);
// }
// }
// //- 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);
// // }
// // }
// // }
// }
// TODO: Remove this
P_ClearFrames(sim_world, I64Min, sim_world->last_frame->tick - 1);
P_Frame *sim_frame = sim_world->last_frame;
@ -3020,7 +2912,7 @@ void V_TickForever(WaveLaneCtx *lane)
f32 fire_presses = fire_held && !prev_frame->held_buttons[Button_M1];
Vec2 look = Zi;
{
Vec2 center = P_WorldShapeFromEnt(player).centroid;
Vec2 center = P_WorldShapeFromEnt(local_guy).centroid;
look = SubVec2(frame->world_cursor, center);
}
if (frame->is_editing)
@ -3041,7 +2933,7 @@ void V_TickForever(WaveLaneCtx *lane)
}
//////////////////////////////
//- Push user snapshots
//- Push player snapshots
// FIXME: Real ping
// f64 ping = 0.250;
@ -3053,7 +2945,7 @@ void V_TickForever(WaveLaneCtx *lane)
// {
// {
// P_UserSnapshot snapshot = Zi;
// snapshot->user = V.user_user;
// snapshot->user = V.;
// snapshot->src_tick = 0;
// // FIXME: Generate snapshots for all new frames, not just last
// snapshot->tick = frame->predict_to;
@ -3141,9 +3033,6 @@ void V_TickForever(WaveLaneCtx *lane)
//////////////////////////////
//- Update blended world
b32 tiles_dirty = 0;
b32 should_clear_particles = 0;
// TODO: Remove this
P_Frame *blend_frame = &P_NilFrame;
{
@ -3641,59 +3530,6 @@ void V_TickForever(WaveLaneCtx *lane)
P_tl.debug_draw_nodes_count = 0;
}
//////////////////////////////
//- Draw entities
// for (P_Ent *ent = P_FirstEnt(blend_frame); ent->valid; ent = P_NextEnt(ent))
// {
// Xform ent_to_world_xf = ent->xf;
// Xform ent_to_draw_xf = MulXform(frame->xf.world_to_draw, ent_to_world_xf);
// P_Shape draw_shape = P_MulXformShape(ent_to_draw_xf, ent->local_shape);
// f32 opacity = 0.5;
// b32 is_visible = 1;
// if (is_visible)
// {
// // // Draw shape
// // {
// // Vec4 color = Color_Purple;
// // color.w *= opacity;
// // i32 detail = 32;
// // V_DrawShape(draw_shape, color, detail, V_DrawFlag_Line);
// // }
// // Draw weapon
// // if (ent->has_weapon)
// // {
// // Vec4 color = Color_Cyan;
// // color.w *= opacity;
// // f32 width = 0.1;
// // f32 height = 0.75;
// // P_Shape local_shape = P_ShapeFromDesc(
// // .count = 4,
// // .points = {
// // VEC2(-width / 2, -height), VEC2(width / 2, -height),
// // VEC2(width / 2, 0), VEC2(-width / 2, 0),
// // }
// // );
// // Xform local_xf = XformFromTrs(TRS(.t = { 0, 0 }, .r = Tau / 4));
// // Xform xf = MulXform(ent_to_draw_xf, local_xf);
// // P_Shape shape = P_MulXformShape(xf, local_shape);
// // V_DrawShape(shape, color, 10, V_DrawFlag_Line);
// // }
// // // Draw aabb
// // {
// // Vec4 color = Color_Orange;
// // color.w *= opacity;
// // Rng2 bb = P_BoundingBoxFromShape(draw_shape);
// // V_DrawRect(bb, color, V_DrawFlag_Line);
// // }
// }
// }
//////////////////////////////
//- Render
@ -3912,25 +3748,6 @@ void V_TickForever(WaveLaneCtx *lane)
}
}
//////////////////////////////
//- Prune sim cmds
// {
// for (P_MsgNode *msg_node = V.sim_cmds.first; cmd_node;)
// {
// P_MsgNode *next = cmd_node->next;
// {
// if (!cmd_node->cmd.predicted || cmd_node->cmd.tick <= sim_world->last_frame->tick)
// {
// DllQueueRemove(V.sim_cmds.first, V.sim_cmds.last, cmd_node);
// SllStackPush(V.first_free_sim_cmd_node, cmd_node);
// --V.sim_cmds.count;
// }
// }
// cmd_node = next;
// }
// }
//////////////////////////////
//- Prune sim ents

View File

@ -301,7 +301,7 @@ Struct(V_Frame)
Struct(V_Ctx)
{
P_Key user_key;
P_Key player_key;
i64 panels_count;
i64 windows_count;