in-world death text

This commit is contained in:
jacob 2026-04-05 22:22:52 -05:00
parent fb1a1572e6
commit f17bdc9d76
9 changed files with 635 additions and 494 deletions

View File

@ -342,26 +342,6 @@ Vec4 SrgbFromLinear(Vec4 lin)
return result;
}
Vec4 SrgbFromHsv(f32 h, f32 s, f32 v)
{
h = ModF32(h, 360.0f);
if (h < 0)
{
h += 360.0f;
}
f32 c = v * s;
f32 x = c * (1.0f - AbsF32(ModF32(h / 60.0f, 2.0f) - 1.0f));
f32 m = v - c;
Vec4 result = VEC4(0, 0, 0, 1);
if (h < 60.0f) { result.r = c; result.g = x; result.b = 0; }
else if (h < 120.0f) { result.r = x; result.g = c; result.b = 0; }
else if (h < 180.0f) { result.r = 0; result.g = c; result.b = x; }
else if (h < 240.0f) { result.r = 0; result.g = x; result.b = c; }
else if (h < 300.0f) { result.r = x; result.g = 0; result.b = c; }
else { result.r = c; result.g = 0; result.b = x; }
return result;
}
Vec4 PremulFromLinear(Vec4 lin)
{
Vec4 result = Zi;
@ -389,6 +369,60 @@ Vec4 LerpSrgb(Vec4 a, Vec4 b, f32 t)
return result;
}
Vec4 SrgbFromHsv(Hsv hsv)
{
f32 h = ModF32(hsv.h, 360);
f32 s = hsv.s;
f32 v = hsv.v;
if (h < 0)
{
h += 360;
}
f32 c = v * s;
f32 x = c * (1 - AbsF32(ModF32(h / 60, 2) - 1));
f32 m = v - c;
Vec4 result = VEC4(0, 0, 0, 1);
if (h < 60) { result.r = c; result.g = x; result.b = 0; }
else if (h < 120) { result.r = x; result.g = c; result.b = 0; }
else if (h < 180) { result.r = 0; result.g = c; result.b = x; }
else if (h < 240) { result.r = 0; result.g = x; result.b = c; }
else if (h < 300) { result.r = x; result.g = 0; result.b = c; }
else { result.r = c; result.g = 0; result.b = x; }
return result;
}
Hsv HsvFromSrgb(Vec4 srgb)
{
f32 r = srgb.r;
f32 g = srgb.g;
f32 b = srgb.b;
f32 max = MaxF32(r, MaxF32(g, b));
f32 min = MinF32(r, MinF32(g, b));
f32 delta = max - min;
Hsv result = Zi;
{
result.v = max;
if (max <= 0) {
result.s = 0;
} else {
result.s = delta / max;
}
if (delta <= 0) {
result.h = 0;
} else if (max == r) {
result.h = 60 * ModF32((g - b) / delta, 6);
} else if (max == g) {
result.h = 60 * (((b - r) / delta) + 2);
} else {
result.h = 60 * (((r - g) / delta) + 4);
}
if (result.h < 0) {
result.h += 360;
}
}
return result;
}
////////////////////////////////////////////////////////////
//~ Vec2

View File

@ -194,6 +194,15 @@ Union(Mat4x4)
f32 e[4][4];
};
////////////////////////////////////////////////////////////
//~ Color types
#define HSV(h, s, v) ((Hsv) { (h), (s), (v) })
Struct(Hsv)
{
f32 h, s, v;
};
////////////////////////////////////////////////////////////
//~ Min / max
@ -339,13 +348,15 @@ f32 LinearFromSrgbF32(f32 srgb);
Vec4 LinearFromSrgb(Vec4 srgb);
Vec4 SrgbFromLinear(Vec4 lin);
Vec4 SrgbFromHsv(f32 h, f32 s, f32 v);
Vec4 PremulFromLinear(Vec4 lin);
Vec4 PremulFromSrgb(Vec4 srgb);
Vec4 LerpSrgb(Vec4 a, Vec4 b, f32 t);
Vec4 SrgbFromHsv(Hsv hsv);
Hsv HsvFromSrgb(Vec4 srgb);
////////////////////////////////////////////////////////////
//~ Vec2

View File

@ -260,6 +260,16 @@ P_Shape P_WorldShapeFromEnt(P_Ent *ent)
////////////////////////////////////////////////////////////
//~ Status helpers
b32 P_IsEntRolling(P_Frame *frame, P_Ent *ent)
{
b32 result = (
ent->last_roll_ns > 0 &&
(frame->time_ns - ent->last_roll_ns) > 0 &&
(frame->time_ns - ent->last_roll_ns) < P_RollTimeNs
);
return result;
}
P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent)
{
P_Anim result = Zi;
@ -368,14 +378,17 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent)
return result;
}
b32 P_IsEntRolling(P_Frame *frame, P_Ent *ent)
Vec4 P_ColorFromEnt(P_Ent *ent)
{
b32 result = (
ent->last_roll_ns > 0 &&
(frame->time_ns - ent->last_roll_ns) > 0 &&
(frame->time_ns - ent->last_roll_ns) < P_RollTimeNs
);
return result;
String ent_str = P_StringFromEnt(ent);
u64 color_seed = MixU64s(P_EntityColorBasis, HashString(ent_str));
f32 hue_offset = TweakFloat("Entity color hue offset", 135, 0, 360);
f32 h = (Norm16(color_seed >> 2) * 1) * 360 + hue_offset;
f32 s = TweakFloat("Entity color saturation", 0.7, 0, 1);
f32 v = TweakFloat("Entity color brightness", 1, 0, 1);
// f32 s = TweakFloat("Entity color saturation", 0.3, 0, 1);
// f32 v = TweakFloat("Entity color brightness", 0.6, 0, 1);
return SrgbFromHsv(HSV(h, s, v));
}
////////////////////////////////////////////////////////////

View File

@ -12,6 +12,7 @@
#define P_BulletTrailBasis 0x27c011f891c571feull
#define P_DeathBasis 0x2e3c75a3286d872aull
#define P_KillfeedBasis 0xd1f84bd6f7c3cf1eull
#define P_EntityColorBasis 0x3d2ddd9778146eccull
Struct(P_EntKey)
{
@ -190,8 +191,6 @@ Struct(P_NetworkedEntState)
b32 is_player;
P_EntKey guy;
f32 ping;
u64 kills;
u64 deaths;
@ -715,8 +714,9 @@ P_Shape P_WorldShapeFromEnt(P_Ent *ent);
////////////////////////////////////////////////////////////
//~ Status helpers
P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent);
b32 P_IsEntRolling(P_Frame *frame, P_Ent *ent);
P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent);
Vec4 P_ColorFromEnt(P_Ent *ent);
////////////////////////////////////////////////////////////
//~ Collision

View File

@ -12,7 +12,6 @@ PERSIST Readonly String P_KillTerms[] = {
CompLit("terminated"),
CompLit("demoted"),
CompLit("restructured"),
CompLit("shredded"),
CompLit("decommissioned"),
CompLit("finalized"),
CompLit("offboarded"),

File diff suppressed because it is too large Load Diff

View File

@ -156,13 +156,25 @@ Global Readonly V_CmdDesc V_cmd_descs[V_CmdKind_COUNT] = {
////////////////////////////////////////////////////////////
//~ Notification types
Enum(V_NotifFlag)
{
V_NotifFlag_None,
V_NotifFlag_Kill = (1 << 0),
};
Struct(V_Notif)
{
V_Notif *next;
V_NotifFlag flags;
String msg;
P_EntKey killer;
P_EntKey victim;
DateTime datetime;
i64 time_ns;
i64 seq;
String msg;
};
////////////////////////////////////////////////////////////
@ -245,7 +257,6 @@ Struct(V_Palette)
////////////////////////////////////////////////////////////
//~ Profiler types
// #define V_CollapsedZoneBasis 0x4a06f782d21f18af
#define V_MinChunkCapacity 1
Struct(V_Zone)
@ -545,7 +556,7 @@ void V_PushWidgetThemeStyles(V_WidgetTheme theme);
////////////////////////////////////////////////////////////
//~ Notification helpers
void V_PushNotif(String msg);
V_Notif *V_PushNotif(String msg);
////////////////////////////////////////////////////////////
//~ Vis tick

View File

@ -621,6 +621,10 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
if (prev_frame->boxes_pre != 0)
{
ControllerEventsArray controller_events = frame->window_frame.controller_events;
u64 boxes_pre_count = prev_frame->boxes_pre_count;
u64 boxes_post_count = prev_frame->boxes_post_count;
UI_Box **boxes_pre = prev_frame->boxes_pre;
UI_Box **boxes_post = prev_frame->boxes_post;
//- Locate boxes
UI_Box *prev_top_active_box = UI_BoxFromKey(prev_frame->top_active_box);
@ -639,9 +643,9 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
}
//- Locate hovered box
for (u64 pre_index = UI.boxes_count; pre_index-- > 0;)
for (u64 pre_idx = boxes_pre_count; pre_idx-- > 0;)
{
UI_Box *box = prev_frame->boxes_pre[pre_index];
UI_Box *box = boxes_pre[pre_idx];
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_CheckCursorHover);
//- Reset state
{
@ -830,9 +834,9 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
{
f32 lower_target = TweakFloat("UI lower blend target", -0.05, -1, 0);
f32 upper_target = TweakFloat("UI upper blend target", 1.05, 1, 10);
for (u64 pre_index = UI.boxes_count; pre_index-- > 0;)
for (u64 pre_idx = boxes_pre_count; pre_idx-- > 0;)
{
UI_Box *box = prev_frame->boxes_pre[pre_index];
UI_Box *box = boxes_pre[pre_idx];
UI_Box *parent = box->parent;
UI_Feedback *feedback = &box->feedback;
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_BuildFeedback);
@ -1438,64 +1442,66 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
//////////////////////////////
//- Layout
//- Layout prepass
u64 boxes_count = UI.boxes_count;
UI_Box **boxes_pre = PushStructsNoZero(frame->arena, UI_Box *, boxes_count);
UI_Box **boxes_post = PushStructsNoZero(frame->arena, UI_Box *, boxes_count);
frame->boxes_pre = boxes_pre;
frame->boxes_post = boxes_post;
ProfZoneDF("Layout UI")
//- Prepare layout data
ProfZoneDF("Layout prepass")
{
//- Prepare layout data
ProfZoneDF("Layout prepass")
frame->boxes_pre_count = 0;
frame->boxes_post_count = 0;
frame->boxes_pre = PushStructsNoZero(frame->arena, UI_Box *, UI.boxes_count);
frame->boxes_post = PushStructsNoZero(frame->arena, UI_Box *, UI.boxes_count);
for (UI_BoxIterResult ir = UI_FirstBox(scratch.arena, &box_iter, UI_RootKey); ir.box; ir = UI_NextBox(scratch.arena, &box_iter))
{
u64 pre_index = 0;
u64 post_index = 0;
for (UI_BoxIterResult ir = UI_FirstBox(scratch.arena, &box_iter, UI_RootKey); ir.box; ir = UI_NextBox(scratch.arena, &box_iter))
UI_Box *box = ir.box;
if (ir.pre)
{
UI_Box *box = ir.box;
if (ir.pre)
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_PrepLayout);
box->pre_idx = frame->boxes_pre_count;
frame->boxes_pre[box->pre_idx] = box;
frame->boxes_pre_count += 1;
// Reset layout data
box->cursor = 0;
box->final_children_size_accum = VEC2(0, 0);
box->solved_dims = VEC2(0, 0);
// Solve scale
{
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_PrepLayout);
box->pre_index = pre_index;
boxes_pre[pre_index] = box;
pre_index += 1;
// Reset layout data
box->cursor = 0;
box->final_children_size_accum = VEC2(0, 0);
box->solved_dims = VEC2(0, 0);
// Solve scale & opacity
UI_Box *parent = box->parent;
box->solved_scale = box->desc.scale;
if (parent)
{
UI_Box *parent = box->parent;
box->solved_opacity = box->desc.opacity;
box->solved_scale = box->desc.scale;
if (parent)
{
box->solved_opacity = parent->solved_opacity * box->solved_opacity;
box->solved_scale = MulVec2Vec2(parent->solved_scale, box->solved_scale);
}
box->solved_scale = MulVec2Vec2(parent->solved_scale, box->solved_scale);
}
}
else
{
box->post_index = post_index;
boxes_post[post_index] = box;
post_index += 1;
}
}
Assert(pre_index == boxes_count);
Assert(post_index == boxes_count);
else
{
box->post_idx = frame->boxes_post_count;
frame->boxes_post[box->post_idx] = box;
frame->boxes_post_count += 1;
}
}
Assert(frame->boxes_pre_count == UI.boxes_count);
Assert(frame->boxes_post_count == UI.boxes_count);
}
u64 boxes_pre_count = frame->boxes_pre_count;
u64 boxes_post_count = frame->boxes_post_count;
UI_Box **boxes_pre = frame->boxes_pre;
UI_Box **boxes_post = frame->boxes_post;
//////////////////////////////
//- Layout
ProfZoneDF("Layout UI")
{
//- Solve independent sizes
ProfZoneDF("Solve independent sizes")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
for (u64 pre_idx = 0; pre_idx < boxes_pre_count; ++pre_idx)
{
UI_Box *box = boxes_pre[pre_index];
UI_Box *box = boxes_pre[pre_idx];
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_IndependentSolve);
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
@ -1550,9 +1556,9 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//- Solve upwards-dependent sizes along layout axis
ProfZoneDF("Solve upwards-dependent sizes (along layout-axis)")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
for (u64 pre_idx = 0; pre_idx < boxes_pre_count; ++pre_idx)
{
UI_Box *box = boxes_pre[pre_index];
UI_Box *box = boxes_pre[pre_idx];
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_UpwardsDependentSolveLayoutAxis);
if (box->parent)
{
@ -1588,9 +1594,9 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//- Solve downwards-dependent sizes
ProfZoneDF("Solve downwards-dependent sizes")
for (u64 post_index = 0; post_index < boxes_count; ++post_index)
for (u64 post_idx = 0; post_idx < boxes_post_count; ++post_idx)
{
UI_Box *box = boxes_post[post_index];
UI_Box *box = boxes_post[post_idx];
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_DownwardsDependentSolve);
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
@ -1621,9 +1627,9 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//- Solve upwards-dependent sizes along non-layout axis
ProfZoneDF("Solve upwards-dependent sizes (along non-layout-axis)")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
for (u64 pre_idx = 0; pre_idx < boxes_pre_count; ++pre_idx)
{
UI_Box *box = boxes_pre[pre_index];
UI_Box *box = boxes_pre[pre_idx];
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_UpwardsDependentSolveNonLayoutAxis);
if (box->parent)
{
@ -1638,9 +1644,9 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//- Solve violations
ProfZoneDF("Solve violations")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
for (u64 pre_idx = 0; pre_idx < boxes_pre_count; ++pre_idx)
{
UI_Box *box = boxes_pre[pre_index];
UI_Box *box = boxes_pre[pre_idx];
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_SolveViolations);
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
@ -1722,9 +1728,9 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//- Solve final positions
ProfZoneDF("Solve final screen positions")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
for (u64 pre_idx = 0; pre_idx < boxes_pre_count; ++pre_idx)
{
UI_Box *box = boxes_pre[pre_index];
UI_Box *box = boxes_pre[pre_idx];
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_FinalSolve);
UI_Box *parent = box->parent;
@ -1962,17 +1968,16 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//- Build render data
// Build GPU rect data
ProfZoneDF("Build GPU rects")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
for (u64 pre_idx = 0; pre_idx < boxes_pre_count; ++pre_idx)
{
UI_Box *box = boxes_pre[pre_index];
UI_Box *box = boxes_pre[pre_idx];
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_BuildGpuData);
GC_Run raw_run_unscaled = box->glyph_run;
GC_Run raw_run = UI_ScaleRun(frame->arena, raw_run_unscaled, box->solved_scale);
Vec4 final_tint_lin = LinearFromSrgb(box->desc.tint);
final_tint_lin.a *= box->solved_opacity;
final_tint_lin.a *= box->desc.opacity;
Vec4 final_border_color_lin = LinearFromSrgb(box->desc.border_color);
@ -2011,7 +2016,6 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
UI_AxisRegion y_alignment = child_alignment.v[Axis_Y];
// Box rect
ProfZoneDF("GPU box rect")
{
UI_GpuRect *rect = PushStruct(frame->rects_arena, UI_GpuRect);
rect->bounds = box->screen_rect;
@ -2044,7 +2048,6 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
// Text rects
if (should_upload_text || AnyBit(frame->frame_flags, UI_FrameFlag_Debug))
ProfZoneDF("GPU text rects")
{
f32 max_baseline_length = CeilF32(DimsFromRng2(box->screen_rect).x);
b32 should_truncate = FloorF32(raw_run.baseline_length) > max_baseline_length && !AnyBit(box->desc.flags, UI_BoxFlag_DontTruncateText);

View File

@ -374,12 +374,9 @@ Struct(UI_Box)
GC_Run glyph_run;
SPR_Sprite sprite;
//- Pre-layout data
u64 pre_index;
u64 post_index;
//- Layout data
f32 solved_opacity;
u64 pre_idx;
u64 post_idx;
Vec2 solved_scale;
Rng2 solved_scissor;
Vec2 final_children_size_accum;
@ -476,6 +473,8 @@ Struct(UI_Frame)
UI_StyleNode *first_free_style_node;
// Layout
u64 boxes_pre_count;
u64 boxes_post_count;
UI_Box **boxes_pre;
UI_Box **boxes_post;
};