From fa96c5410466c8bd9ac1411a3ed9e5f4c7e1a10b Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 18 Jan 2026 18:53:37 -0600 Subject: [PATCH] add debug scoreboard --- src/pp/pp.c | 199 ++++++++++++++++++------------------ src/pp/pp_sim/pp_sim_core.c | 14 ++- src/pp/pp_vis/pp_vis_core.c | 80 +++++++++++++-- 3 files changed, 184 insertions(+), 109 deletions(-) diff --git a/src/pp/pp.c b/src/pp/pp.c index 918f778c..a2277c51 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -1561,71 +1561,27 @@ void P_StepFrame(P_Frame *frame) for (P_Ent *ent0 = P_FirstEnt(frame); !P_IsEntNil(ent0); ent0 = P_NextEnt(ent0)) { - P_Shape shape0 = P_WorldShapeFromEnt(ent0); - for (P_Ent *ent1 = P_FirstEnt(frame); !P_IsEntNil(ent1); ent1 = P_NextEnt(ent1)) + if (ent0->is_guy) { - if (ent1 > ent0) + P_Shape shape0 = P_WorldShapeFromEnt(ent0); + for (P_Ent *ent1 = P_FirstEnt(frame); !P_IsEntNil(ent1); ent1 = P_NextEnt(ent1)) { - P_Shape shape1 = P_WorldShapeFromEnt(ent1); - - // TODO: World query - P_CollisionResult collision = P_CollisionResultFromShapes(shape0, shape1); - if (collision.collision_points_count > 0) + if (ent1->is_guy && ent1 > ent0) { - // FIXME: Key lookup - P_Constraint *constraint = 0; + P_Shape shape1 = P_WorldShapeFromEnt(ent1); + + // TODO: World query + P_CollisionResult collision = P_CollisionResultFromShapes(shape0, shape1); + if (collision.collision_points_count > 0) { - b32 match = 0; - for (i64 constraint_idx = 0; constraint_idx < frame->constraints_count; ++constraint_idx) + // FIXME: Key lookup + P_Constraint *constraint = 0; { - constraint = &frame->constraints[constraint_idx]; - if (P_MatchKey(constraint->ent0, ent0->key) && P_MatchKey(constraint->ent1, ent1->key)) - { - match = 1; - break; - } - } - if (!match) - { - if (frame->constraints_count < frame->max_constraints) - { - constraint = &frame->constraints[frame->constraints_count]; - frame->constraints_count += 1; - ZeroStruct(constraint); - } - } - } - if (constraint) - { - constraint->last_touched_tick = frame->tick; - constraint->normal = collision.collision_normal; - // constraint->friction = SqrtF32(ent0->friction * ent1->friction); - constraint->friction = 0; - - // TODO: Real masses - f32 inv_m0 = 10; - f32 inv_m1 = 10; - f32 inv_i0 = 0; - f32 inv_i1 = 0; - - constraint->ent0 = ent0->key; - constraint->ent1 = ent1->key; - // constraint->static_center1 = shape1.center_of_mass; - - constraint->inv_m0 = inv_m0; - constraint->inv_m1 = inv_m1; - constraint->inv_i0 = inv_i0; - constraint->inv_i1 = inv_i1; - - // Delete old contacts that are no longer present - for (i32 contact_point_idx = 0; contact_point_idx < constraint->points_count; ++contact_point_idx) - { - P_ContactPoint *contact = &constraint->points[contact_point_idx]; - u32 id = contact->id; b32 match = 0; - for (i32 collision_point_idx = 0; collision_point_idx < collision.collision_points_count; ++collision_point_idx) + for (i64 constraint_idx = 0; constraint_idx < frame->constraints_count; ++constraint_idx) { - if (collision.collision_points[collision_point_idx].id == id) + constraint = &frame->constraints[constraint_idx]; + if (P_MatchKey(constraint->ent0, ent0->key) && P_MatchKey(constraint->ent1, ent1->key)) { match = 1; break; @@ -1633,60 +1589,107 @@ void P_StepFrame(P_Frame *frame) } if (!match) { - // Delete contact by replacing with last in array - *contact = constraint->points[constraint->points_count - 1]; - constraint->points_count -= 1; - contact_point_idx -= 1; + if (frame->constraints_count < frame->max_constraints) + { + constraint = &frame->constraints[frame->constraints_count]; + frame->constraints_count += 1; + ZeroStruct(constraint); + } } } - - // Create / update contacts from collision - for (i32 collision_point_idx = 0; collision_point_idx < collision.collision_points_count; ++collision_point_idx) + if (constraint) { - P_CollisionPoint collision_point = collision.collision_points[collision_point_idx]; + constraint->last_touched_tick = frame->tick; + constraint->normal = collision.collision_normal; + // constraint->friction = SqrtF32(ent0->friction * ent1->friction); + constraint->friction = 0; - u32 id = collision_point.id; - P_ContactPoint *contact = 0; + // TODO: Real masses + f32 inv_m0 = 10; + f32 inv_m1 = 10; + f32 inv_i0 = 0; + f32 inv_i1 = 0; + + constraint->ent0 = ent0->key; + constraint->ent1 = ent1->key; + // constraint->static_center1 = shape1.center_of_mass; + + constraint->inv_m0 = inv_m0; + constraint->inv_m1 = inv_m1; + constraint->inv_i0 = inv_i0; + constraint->inv_i1 = inv_i1; + + // Delete old contacts that are no longer present + for (i32 contact_point_idx = 0; contact_point_idx < constraint->points_count; ++contact_point_idx) { - for (i32 contact_point_idx = 0; contact_point_idx < constraint->points_count; ++contact_point_idx) + P_ContactPoint *contact = &constraint->points[contact_point_idx]; + u32 id = contact->id; + b32 match = 0; + for (i32 collision_point_idx = 0; collision_point_idx < collision.collision_points_count; ++collision_point_idx) { - P_ContactPoint *tmp = &constraint->points[contact_point_idx]; - if (tmp->id == id) + if (collision.collision_points[collision_point_idx].id == id) { - contact = tmp; + match = 1; break; } } - if (!contact) + if (!match) { - contact = &constraint->points[constraint->points_count]; - constraint->points_count += 1; - ZeroStruct(contact); + // Delete contact by replacing with last in array + *contact = constraint->points[constraint->points_count - 1]; + constraint->points_count -= 1; + contact_point_idx -= 1; } } - contact->id = id; - Vec2 vcp0 = SubVec2(collision_point.p, shape0.center_of_mass); - Vec2 vcp1 = SubVec2(collision_point.p, shape1.center_of_mass); + // Create / update contacts from collision + for (i32 collision_point_idx = 0; collision_point_idx < collision.collision_points_count; ++collision_point_idx) + { + P_CollisionPoint collision_point = collision.collision_points[collision_point_idx]; - contact->vcp0 = vcp0; - contact->vcp1 = vcp1; - contact->starting_separation = collision_point.separation; + u32 id = collision_point.id; + P_ContactPoint *contact = 0; + { + for (i32 contact_point_idx = 0; contact_point_idx < constraint->points_count; ++contact_point_idx) + { + P_ContactPoint *tmp = &constraint->points[contact_point_idx]; + if (tmp->id == id) + { + contact = tmp; + break; + } + } + if (!contact) + { + contact = &constraint->points[constraint->points_count]; + constraint->points_count += 1; + ZeroStruct(contact); + } + } + contact->id = id; - // // Debug draw - // { - // // P_Ent *ent0 = P_EntFromKey(frame, constraint->ent0); - // // P_Ent *ent1 = P_EntFromKey(frame, constraint->ent1); - // Vec2 normal = constraint->normal; - // Vec2 center0 = Zi; - // Vec2 center1 = Zi; - // if (!P_IsEntNil(ent0)) center0 = P_WorldShapeFromEnt(ent0).center_of_mass; - // if (!P_IsEntNil(ent1)) center1 = P_WorldShapeFromEnt(ent1).center_of_mass; - // Vec2 p0 = AddVec2(center0, vcp0); - // Vec2 p1 = AddVec2(center1, vcp1); - // P_DebugDrawPoint(p0, Color_Cyan); - // P_DebugDrawLine(p0, AddVec2(p0, normal), Color_White); - // } + Vec2 vcp0 = SubVec2(collision_point.p, shape0.center_of_mass); + Vec2 vcp1 = SubVec2(collision_point.p, shape1.center_of_mass); + + contact->vcp0 = vcp0; + contact->vcp1 = vcp1; + contact->starting_separation = collision_point.separation; + + // // Debug draw + // { + // // P_Ent *ent0 = P_EntFromKey(frame, constraint->ent0); + // // P_Ent *ent1 = P_EntFromKey(frame, constraint->ent1); + // Vec2 normal = constraint->normal; + // Vec2 center0 = Zi; + // Vec2 center1 = Zi; + // if (!P_IsEntNil(ent0)) center0 = P_WorldShapeFromEnt(ent0).center_of_mass; + // if (!P_IsEntNil(ent1)) center1 = P_WorldShapeFromEnt(ent1).center_of_mass; + // Vec2 p0 = AddVec2(center0, vcp0); + // Vec2 p1 = AddVec2(center1, vcp1); + // P_DebugDrawPoint(p0, Color_Cyan); + // P_DebugDrawLine(p0, AddVec2(p0, normal), Color_White); + // } + } } } } @@ -1973,7 +1976,7 @@ void P_StepFrame(P_Frame *frame) } ////////////////////////////// - //- Spawn new bullets + //- Fire bullets // TODO: Remove this @@ -1981,7 +1984,7 @@ void P_StepFrame(P_Frame *frame) P_EntList bullets_to_spawn = Zi; for (P_Ent *firer = P_FirstEnt(frame); !P_IsEntNil(firer); firer = P_NextEnt(firer)) { - if (firer->control.fire_held) + if (firer->is_guy && firer->control.fire_held) // if (firer->fire_presses) { // i64 fire_delta_ns = frame->time_ns - firer->last_fire_ns; diff --git a/src/pp/pp_sim/pp_sim_core.c b/src/pp/pp_sim/pp_sim_core.c index 7661cf11..afb26e93 100644 --- a/src/pp/pp_sim/pp_sim_core.c +++ b/src/pp/pp_sim/pp_sim_core.c @@ -623,7 +623,10 @@ void S_TickForever(WaveLaneCtx *lane) // TODO: Real reset for (P_Ent *ent = P_FirstEnt(world_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) { - ent->exists = 0; + if (!ent->is_player) + { + ent->exists = 0; + } } } break; //- Edit entity @@ -919,10 +922,13 @@ void S_TickForever(WaveLaneCtx *lane) String snapshot = Zi; snapshot.text = BB_GetWrittenRaw(&packer_bbw) + snapshot_start; snapshot.len = snapshot_end - snapshot_start; + NET_Send(net_pipe, client->net_key, snapshot, NET_SendFlag_Raw); - // FIXME: Send raw snapshots - // NET_Send(net_pipe, client->net_key, snapshot, NET_SendFlag_Raw); - NET_Send(net_pipe, client->net_key, snapshot, NET_SendFlag_None); + // Sanity check to catch whenever we end up packing too much information + // into a single raw snapshot, causing it to drop. Not an actual error, + // but signals we may have botched the packing code or need tighter + // compression + Assert(snapshot.len <= NET_PacketSize); } } delta_node = next_delta_node; diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 3462429f..66168bf0 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -2379,6 +2379,73 @@ void V_TickForever(WaveLaneCtx *lane) UI_PopCP(UI_TopCP()); } + ////////////////////////////// + //- Build scoreboard UI + + if (frame->held_buttons[Button_Tab]) + { + Struct(BoardRow) + { + BoardRow *next; + String name; + }; + i64 players_count = 0; + i64 board_rows_count = 0; + BoardRow *first_board_row = 0; + BoardRow *last_board_row = 0; + + for (P_Ent *player = P_FirstEnt(sim_world->last_frame); !P_IsEntNil(player); player = P_NextEnt(player)) + { + if (player->is_player) + { + players_count += 1; + BoardRow *row = PushStruct(frame->arena, BoardRow); + { + SllQueuePush(first_board_row, last_board_row, row); + board_rows_count += 1; + } + String name = P_StringFromEnt(player); + row->name= name; + } + } + + UI_Key board_key = UI_KeyF("scoreboard"); + + Vec4 board_bg = VEC4(0, 0, 0, 0.50); + + UI_Size board_width = UI_FNT(50, 0); + UI_Size board_height = UI_FNT(20, 0); + + Vec2 pos = VEC2(frame->ui_dims.x / 2, 50); + UI_SetNext(Anchor, UI_Region_Top); + UI_SetNext(Width, board_width); + UI_SetNext(Height, board_height); + UI_SetNext(FloatingPos, pos); + UI_SetNext(BackgroundColor, board_bg); + UI_SetNext(Flags, UI_BoxFlag_Floating); + UI_PushCP(UI_BuildColumnEx(board_key)); + { + for (BoardRow *board_row = first_board_row; board_row; board_row = board_row->next) + { + String name = board_row->name; + + UI_SetNext(Tint, 0); + UI_PushCP(UI_BuildRow()); + { + UI_SetNext(FontSize, UI_Top(FontSize) * theme.h2); + UI_BuildLabelF("Player: \"%F\"", FmtString(name)); + } + UI_PopCP(UI_TopCP()); + + if (board_row->next) + { + UI_BuildDivider(UI_PIX(1, 1), theme.col.divider, Axis_Y); + } + } + } + UI_PopCP(UI_TopCP()); + } + ////////////////////////////// //- Build console UI @@ -2656,10 +2723,6 @@ void V_TickForever(WaveLaneCtx *lane) 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; @@ -3088,10 +3151,13 @@ void V_TickForever(WaveLaneCtx *lane) String snapshot = Zi; snapshot.text = BB_GetWrittenRaw(&packer_bbw) + snapshot_start; snapshot.len = snapshot_end - snapshot_start; + NET_Send(net_pipe, frame->sim_key, snapshot, NET_SendFlag_Raw); - // FIXME: Send raw snapshots - // NET_Send(net_pipe, frame->sim_key, snapshot, NET_SendFlag_Raw); - NET_Send(net_pipe, frame->sim_key, snapshot, NET_SendFlag_None); + // Sanity check to catch whenever we end up packing too much information + // into a single raw snapshot, causing it to drop. Not an actual error, + // but signals we may have botched the packing code or need tighter + // compression + Assert(snapshot.len <= NET_PacketSize); } } delta_node = next_delta_node;