From 23aef8f67321c8fe4a264f2c920468f90fb4f7da Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 25 Jan 2024 22:02:28 -0800 Subject: [PATCH] HUD tracking: cull nametags - Background overlapping nametags become 60% transparent - Culling is performed separately from other HUD trackers --- src/k_hud.cpp | 30 +++++++++++++++--------------- src/k_hud.h | 2 +- src/k_hud_track.cpp | 40 +++++++++++++++++++++++++++++++--------- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/k_hud.cpp b/src/k_hud.cpp index cf82dfb2e..56c2f071f 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -3674,28 +3674,28 @@ static void K_DrawRivalTagForPlayer(fixed_t x, fixed_t y) V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_rival[blink], NULL); } -static void K_DrawTypingDot(fixed_t x, fixed_t y, UINT8 duration, player_t *p) +static void K_DrawTypingDot(fixed_t x, fixed_t y, UINT8 duration, player_t *p, INT32 flags) { if (p->typing_duration > duration) { - V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_typdot, NULL); + V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN|flags, kp_typdot, NULL); } } -static void K_DrawTypingNotifier(fixed_t x, fixed_t y, player_t *p) +static void K_DrawTypingNotifier(fixed_t x, fixed_t y, player_t *p, INT32 flags) { if (p->cmd.flags & TICCMD_TYPING) { - V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_talk, NULL); + V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN|flags, kp_talk, NULL); /* spacing closer with the last two looks a better most of the time */ - K_DrawTypingDot(x + 3*FRACUNIT, y, 15, p); - K_DrawTypingDot(x + 6*FRACUNIT - FRACUNIT/3, y, 31, p); - K_DrawTypingDot(x + 9*FRACUNIT - FRACUNIT/3, y, 47, p); + K_DrawTypingDot(x + 3*FRACUNIT, y, 15, p, flags); + K_DrawTypingDot(x + 6*FRACUNIT - FRACUNIT/3, y, 31, p, flags); + K_DrawTypingDot(x + 9*FRACUNIT - FRACUNIT/3, y, 47, p, flags); } } -static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p) +static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p, INT32 flags) { const INT32 clr = skincolors[p->skincolor].chatcolor; const INT32 namelen = V_ThinStringWidth(player_names[p - players], 0); @@ -3738,15 +3738,15 @@ static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p) } // Lat: 10/06/2020: colormap can be NULL on the frame you join a game, just arbitrarily use palette indexes 31 and 0 instead of whatever the colormap would give us instead to avoid crashes. - V_DrawFill(barx, bary, barw, (3 * vid.dupy), (colormap ? colormap[31] : 31)|V_NOSCALESTART); - V_DrawFill(barx, bary + vid.dupy, barw, vid.dupy, (colormap ? colormap[0] : 0)|V_NOSCALESTART); + V_DrawFill(barx, bary, barw, (3 * vid.dupy), (colormap ? colormap[31] : 31)|V_NOSCALESTART|flags); + V_DrawFill(barx, bary + vid.dupy, barw, vid.dupy, (colormap ? colormap[0] : 0)|V_NOSCALESTART|flags); // END DRAWFILL DUMBNESS // Draw the stem - V_DrawFixedPatch(x, y, FRACUNIT, 0, kp_nametagstem, colormap); + V_DrawFixedPatch(x, y, FRACUNIT, flags, kp_nametagstem, colormap); // Draw the name itself - V_DrawThinStringAtFixed(x + (5*FRACUNIT), y - (26*FRACUNIT), clr, player_names[p - players]); + V_DrawThinStringAtFixed(x + (5*FRACUNIT), y - (26*FRACUNIT), clr|flags, player_names[p - players]); } playertagtype_t K_WhichPlayerTag(player_t *p) @@ -3776,7 +3776,7 @@ playertagtype_t K_WhichPlayerTag(player_t *p) return PLAYERTAG_NONE; } -void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type) +void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type, INT32 flags) { switch (type) { @@ -3789,8 +3789,8 @@ void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type) break; case PLAYERTAG_NAME: - K_DrawNameTagForPlayer(x, y, p); - K_DrawTypingNotifier(x, y, p); + K_DrawNameTagForPlayer(x, y, p, flags); + K_DrawTypingNotifier(x, y, p, flags); break; default: diff --git a/src/k_hud.h b/src/k_hud.h index 9381beefc..95fd79931 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -109,7 +109,7 @@ typedef enum playertagtype_t; playertagtype_t K_WhichPlayerTag(player_t *p); -void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type); +void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type, INT32 flags); #ifdef __cplusplus } // extern "C" diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index a21e339be..13ea5b058 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -360,7 +360,7 @@ void K_DrawTargetTracking(const TargetTracking& target) { if (target.nametag != PLAYERTAG_NONE) { - K_DrawPlayerTag(target.result.x, target.result.y, target.mobj->player, target.nametag); + K_DrawPlayerTag(target.result.x, target.result.y, target.mobj->player, target.nametag, target.foreground ? 0 : V_60TRANS); return; } @@ -582,7 +582,7 @@ void K_CullTargetList(std::vector& targetList) constexpr int kBlockHeight = 10; constexpr int kXBlocks = BASEVIDWIDTH / kBlockWidth; constexpr int kYBlocks = BASEVIDHEIGHT / kBlockHeight; - bool map[kXBlocks][kYBlocks] = {}; + UINT8 map[kXBlocks][kYBlocks] = {}; constexpr fixed_t kTrackerRadius = 30*FRACUNIT/2; // just an approximation of common HUD tracker @@ -598,15 +598,37 @@ void K_CullTargetList(std::vector& targetList) return; } - if (tr.nametag != PLAYERTAG_NONE) + fixed_t x1, x2, y1, y2; + UINT8 bit = 1; + + // TODO: there should be some generic system + // instead of this special case. + if (tr.nametag == PLAYERTAG_NAME) + { + const player_t* p = tr.mobj->player; + + x1 = tr.result.x; + x2 = tr.result.x + ((6 + V_ThinStringWidth(player_names[p - players], 0)) * FRACUNIT); + y1 = tr.result.y - (30 * FRACUNIT); + y2 = tr.result.y - (4 * FRACUNIT); + bit = 2; // nametags will cull on a separate plane + } + else if (tr.nametag != PLAYERTAG_NONE) { return; } + else + { + x1 = tr.result.x - kTrackerRadius; + x2 = tr.result.x + kTrackerRadius; + y1 = tr.result.y - kTrackerRadius; + y2 = tr.result.y + kTrackerRadius; + } - fixed_t x1 = std::max(((tr.result.x - kTrackerRadius) / kBlockWidth) / FRACUNIT, 0); - fixed_t x2 = std::min(((tr.result.x + kTrackerRadius) / kBlockWidth) / FRACUNIT, kXBlocks - 1); - fixed_t y1 = std::max(((tr.result.y - kTrackerRadius) / kBlockHeight) / FRACUNIT, 0); - fixed_t y2 = std::min(((tr.result.y + kTrackerRadius) / kBlockHeight) / FRACUNIT, kYBlocks - 1); + x1 = std::max(x1 / kBlockWidth / FRACUNIT, 0); + x2 = std::min(x2 / kBlockWidth / FRACUNIT, kXBlocks - 1); + y1 = std::max(y1 / kBlockHeight / FRACUNIT, 0); + y2 = std::min(y2 / kBlockHeight / FRACUNIT, kYBlocks - 1); bool allMine = true; @@ -614,13 +636,13 @@ void K_CullTargetList(std::vector& targetList) { for (fixed_t y = y1; y <= y2; ++y) { - if (map[x][y]) + if (map[x][y] & bit) { allMine = false; } else { - map[x][y] = true; + map[x][y] |= bit; if (cv_debughudtracker.value) {