HUD tracking: cull nametags

- Background overlapping nametags become 60% transparent
- Culling is performed separately from other HUD trackers
This commit is contained in:
James R 2024-01-25 22:02:28 -08:00
parent 5ef2df577a
commit 23aef8f673
3 changed files with 47 additions and 25 deletions

View file

@ -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); 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) 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) 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 */ /* spacing closer with the last two looks a better most of the time */
K_DrawTypingDot(x + 3*FRACUNIT, y, 15, p); K_DrawTypingDot(x + 3*FRACUNIT, y, 15, p, flags);
K_DrawTypingDot(x + 6*FRACUNIT - FRACUNIT/3, y, 31, p); K_DrawTypingDot(x + 6*FRACUNIT - FRACUNIT/3, y, 31, p, flags);
K_DrawTypingDot(x + 9*FRACUNIT - FRACUNIT/3, y, 47, p); 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 clr = skincolors[p->skincolor].chatcolor;
const INT32 namelen = V_ThinStringWidth(player_names[p - players], 0); 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. // 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, 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); V_DrawFill(barx, bary + vid.dupy, barw, vid.dupy, (colormap ? colormap[0] : 0)|V_NOSCALESTART|flags);
// END DRAWFILL DUMBNESS // END DRAWFILL DUMBNESS
// Draw the stem // 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 // 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) playertagtype_t K_WhichPlayerTag(player_t *p)
@ -3776,7 +3776,7 @@ playertagtype_t K_WhichPlayerTag(player_t *p)
return PLAYERTAG_NONE; 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) switch (type)
{ {
@ -3789,8 +3789,8 @@ void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type)
break; break;
case PLAYERTAG_NAME: case PLAYERTAG_NAME:
K_DrawNameTagForPlayer(x, y, p); K_DrawNameTagForPlayer(x, y, p, flags);
K_DrawTypingNotifier(x, y, p); K_DrawTypingNotifier(x, y, p, flags);
break; break;
default: default:

View file

@ -109,7 +109,7 @@ typedef enum
playertagtype_t; playertagtype_t;
playertagtype_t K_WhichPlayerTag(player_t *p); 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 #ifdef __cplusplus
} // extern "C" } // extern "C"

View file

@ -360,7 +360,7 @@ void K_DrawTargetTracking(const TargetTracking& target)
{ {
if (target.nametag != PLAYERTAG_NONE) 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; return;
} }
@ -582,7 +582,7 @@ void K_CullTargetList(std::vector<TargetTracking>& targetList)
constexpr int kBlockHeight = 10; constexpr int kBlockHeight = 10;
constexpr int kXBlocks = BASEVIDWIDTH / kBlockWidth; constexpr int kXBlocks = BASEVIDWIDTH / kBlockWidth;
constexpr int kYBlocks = BASEVIDHEIGHT / kBlockHeight; 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 constexpr fixed_t kTrackerRadius = 30*FRACUNIT/2; // just an approximation of common HUD tracker
@ -598,15 +598,37 @@ void K_CullTargetList(std::vector<TargetTracking>& targetList)
return; 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; 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); x1 = std::max(x1 / kBlockWidth / FRACUNIT, 0);
fixed_t x2 = std::min(((tr.result.x + kTrackerRadius) / kBlockWidth) / FRACUNIT, kXBlocks - 1); x2 = std::min(x2 / kBlockWidth / FRACUNIT, kXBlocks - 1);
fixed_t y1 = std::max(((tr.result.y - kTrackerRadius) / kBlockHeight) / FRACUNIT, 0); y1 = std::max(y1 / kBlockHeight / FRACUNIT, 0);
fixed_t y2 = std::min(((tr.result.y + kTrackerRadius) / kBlockHeight) / FRACUNIT, kYBlocks - 1); y2 = std::min(y2 / kBlockHeight / FRACUNIT, kYBlocks - 1);
bool allMine = true; bool allMine = true;
@ -614,13 +636,13 @@ void K_CullTargetList(std::vector<TargetTracking>& targetList)
{ {
for (fixed_t y = y1; y <= y2; ++y) for (fixed_t y = y1; y <= y2; ++y)
{ {
if (map[x][y]) if (map[x][y] & bit)
{ {
allMine = false; allMine = false;
} }
else else
{ {
map[x][y] = true; map[x][y] |= bit;
if (cv_debughudtracker.value) if (cv_debughudtracker.value)
{ {