From 1c0009fb2129f99b0d6b39380affc06fa7b718f3 Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 18 Jan 2026 02:46:10 -0600 Subject: [PATCH] attach player key to client --- src/base/base_log.h | 19 +- src/net/net_win32/net_win32.c | 44 ++--- src/pp/pp.c | 22 +-- src/pp/pp.h | 19 +- src/pp/pp_sim/pp_sim_core.c | 248 ++++++++++++++++++-------- src/pp/pp_sim/pp_sim_core.h | 2 + src/pp/pp_transcode.c | 19 +- src/pp/pp_vis/pp_vis_core.c | 317 +++++++--------------------------- src/pp/pp_vis/pp_vis_core.h | 2 +- 9 files changed, 319 insertions(+), 373 deletions(-) diff --git a/src/base/base_log.h b/src/base/base_log.h index e2aed782..514369fb 100644 --- a/src/base/base_log.h +++ b/src/base/base_log.h @@ -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 diff --git a/src/net/net_win32/net_win32.c b/src/net/net_win32/net_win32.c index 7365f596..db1c4e9f 100644 --- a/src/net/net_win32/net_win32.c +++ b/src/net/net_win32/net_win32.c @@ -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) + ); } } } diff --git a/src/pp/pp.c b/src/pp/pp.c index ee6a5c4c..471b3453 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -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); diff --git a/src/pp/pp.h b/src/pp/pp.h index 859901d7..ae8f1f06 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -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; }; diff --git a/src/pp/pp_sim/pp_sim_core.c b/src/pp/pp_sim/pp_sim_core.c index eca32808..d0c08849 100644 --- a/src/pp/pp_sim/pp_sim_core.c +++ b/src/pp/pp_sim/pp_sim_core.c @@ -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,51 +470,91 @@ 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 - should_save = 1; - } - if (msg->kind == P_MsgKind_ResetWorld) - { - // TODO: Real reset - for (P_Ent *ent = P_FirstEnt(world_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) + //- Save world + case P_MsgKind_SaveWorld: { - ent->exists = 0; - } - } - if (msg->kind == P_MsgKind_EntEdit) - { - P_EntList ents = Zi; - P_Ent *dst = P_PushTempEnt(frame_arena, &ents); - *dst = msg->ent; - P_SpawnEntsFromList(world_frame, ents); - } - if (msg->kind == P_MsgKind_TileEdit) - { - P_TileKind tile = msg->tile_kind; - Rng2I32 range = msg->tile_range; - for (i32 tile_y = range.p0.y; tile_y < range.p1.y; ++tile_y) + // FIXME: Only accept save from local player + should_save = 1; + } break; + //- Reset world + case P_MsgKind_ResetWorld: { - for (i32 tile_x = range.p0.x; tile_x < range.p1.x; ++tile_x) + // TODO: Real reset + for (P_Ent *ent = P_FirstEnt(world_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) { - Vec2 tile_pos = VEC2(tile_x, tile_y); - i32 tile_idx = P_TileIdxFromTilePos(tile_pos); - world->tiles[tile_idx] = (u8)tile; + ent->exists = 0; } - } - // Hash tiles + } break; + //- Edit entity + case P_MsgKind_EntEdit: { - u64 old_tiles_hash = world->tiles_hash; - world->tiles_hash = HashString(STRING(P_TilesCount, world->tiles)); - if (world->tiles_hash != old_tiles_hash) + String name = msg->data; + P_EntList ents = Zi; + // TODO: Enumerated prefabs + if (0) { - tiles_dirty = 1; } - } + 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; + 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; + } + } + // 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; + } + } + } 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); diff --git a/src/pp/pp_sim/pp_sim_core.h b/src/pp/pp_sim/pp_sim_core.h index 4733a0b0..335b254d 100644 --- a/src/pp/pp_sim/pp_sim_core.h +++ b/src/pp/pp_sim/pp_sim_core.h @@ -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]; diff --git a/src/pp/pp_transcode.c b/src/pp/pp_transcode.c index bcc87fde..a60cf09c 100644 --- a/src/pp/pp_transcode.c +++ b/src/pp/pp_transcode.c @@ -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; diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 08408332..b1747037 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -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 diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index f9271282..8ecaa2d1 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -301,7 +301,7 @@ Struct(V_Frame) Struct(V_Ctx) { - P_Key user_key; + P_Key player_key; i64 panels_count; i64 windows_count;