From 83051728f0809d066eea4593e27a6efbd05d5ea5 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 18:45:22 -0800 Subject: [PATCH 1/5] Move capsule target code out of k_hud.c, to k_hud_track.cpp --- src/CMakeLists.txt | 1 + src/k_hud.c | 295 +------------------------------------------- src/k_hud.h | 5 + src/k_hud_track.cpp | 289 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 300 insertions(+), 290 deletions(-) create mode 100644 src/k_hud_track.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce816523e..ac592f89d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -121,6 +121,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 k_grandprix.c k_boss.c k_hud.c + k_hud_track.cpp k_menufunc.c k_menudraw.c k_terrain.c diff --git a/src/k_hud.c b/src/k_hud.c index bdc14e596..5fbc5b1a3 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -174,10 +174,10 @@ static patch_t *kp_bossret[4]; static patch_t *kp_trickcool[2]; -static patch_t *kp_capsuletarget_arrow[2][2]; -static patch_t *kp_capsuletarget_icon[2]; -static patch_t *kp_capsuletarget_far[2]; -static patch_t *kp_capsuletarget_near[8]; +patch_t *kp_capsuletarget_arrow[2][2]; +patch_t *kp_capsuletarget_icon[2]; +patch_t *kp_capsuletarget_far[2]; +patch_t *kp_capsuletarget_near[8]; void K_LoadKartHUDGraphics(void) { @@ -3175,217 +3175,6 @@ static void K_DrawWeakSpot(weakspotdraw_t *ws) V_DrawFixedPatch(ws->x, ws->y, FRACUNIT, 0, kp_bossret[j+1], colormap); } -typedef struct capsuletracking_s -{ - mobj_t *mobj; - vector3_t point; - fixed_t camDist; -} capsuletracking_t; - -static void K_DrawCapsuleTracking(capsuletracking_t *caps) -{ - trackingResult_t result = {0}; - INT32 timer = 0; - - K_ObjectTracking(&result, &caps->point, false); - - if (result.onScreen == false) - { - // Off-screen, draw alongside the borders of the screen. - // Probably the most complicated thing. - - INT32 scrVal = 240; - vector2_t screenSize = {0}; - - INT32 borderSize = 7; - vector2_t borderWin = {0}; - vector2_t borderDir = {0}; - fixed_t borderLen = FRACUNIT; - - vector2_t arrowDir = {0}; - - vector2_t arrowPos = {0}; - patch_t *arrowPatch = NULL; - INT32 arrowFlags = 0; - - vector2_t capsulePos = {0}; - patch_t *capsulePatch = NULL; - - timer = (leveltime / 3); - - screenSize.x = vid.width / vid.dupx; - screenSize.y = vid.height / vid.dupy; - - if (r_splitscreen >= 2) - { - // Half-wide screens - screenSize.x >>= 1; - borderSize >>= 1; - } - - if (r_splitscreen >= 1) - { - // Half-tall screens - screenSize.y >>= 1; - } - - scrVal = max(screenSize.x, screenSize.y) - 80; - - borderWin.x = screenSize.x - borderSize; - borderWin.y = screenSize.y - borderSize; - - arrowDir.x = 0; - arrowDir.y = P_MobjFlip(caps->mobj) * FRACUNIT; - - // Simply pointing towards the result doesn't work, so inaccurate hack... - borderDir.x = FixedMul( - FixedMul( - FINESINE((-result.angle >> ANGLETOFINESHIFT) & FINEMASK), - FINECOSINE((-result.pitch >> ANGLETOFINESHIFT) & FINEMASK) - ), - result.fov - ); - - borderDir.y = FixedMul( - FINESINE((-result.pitch >> ANGLETOFINESHIFT) & FINEMASK), - result.fov - ); - - borderLen = R_PointToDist2(0, 0, borderDir.x, borderDir.y); - - if (borderLen > 0) - { - borderDir.x = FixedDiv(borderDir.x, borderLen); - borderDir.y = FixedDiv(borderDir.y, borderLen); - } - else - { - // Eh just put it at the bottom. - borderDir.x = 0; - borderDir.y = FRACUNIT; - } - - capsulePatch = kp_capsuletarget_icon[timer & 1]; - - if (abs(borderDir.x) > abs(borderDir.y)) - { - // Horizontal arrow - arrowPatch = kp_capsuletarget_arrow[1][timer & 1]; - arrowDir.y = 0; - - if (borderDir.x < 0) - { - // LEFT - arrowDir.x = -FRACUNIT; - } - else - { - // RIGHT - arrowDir.x = FRACUNIT; - } - } - else - { - // Vertical arrow - arrowPatch = kp_capsuletarget_arrow[0][timer & 1]; - arrowDir.x = 0; - - if (borderDir.y < 0) - { - // UP - arrowDir.y = -FRACUNIT; - } - else - { - // DOWN - arrowDir.y = FRACUNIT; - } - } - - arrowPos.x = (screenSize.x >> 1) + FixedMul(scrVal, borderDir.x); - arrowPos.y = (screenSize.y >> 1) + FixedMul(scrVal, borderDir.y); - - arrowPos.x = min(max(arrowPos.x, borderSize), borderWin.x) * FRACUNIT; - arrowPos.y = min(max(arrowPos.y, borderSize), borderWin.y) * FRACUNIT; - - capsulePos.x = arrowPos.x - (arrowDir.x * 12); - capsulePos.y = arrowPos.y - (arrowDir.y * 12); - - arrowPos.x -= (arrowPatch->width << FRACBITS) >> 1; - arrowPos.y -= (arrowPatch->height << FRACBITS) >> 1; - - capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; - capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; - - if (arrowDir.x < 0) - { - arrowPos.x += arrowPatch->width << FRACBITS; - arrowFlags |= V_FLIP; - } - - if (arrowDir.y < 0) - { - arrowPos.y += arrowPatch->height << FRACBITS; - arrowFlags |= V_VFLIP; - } - - V_DrawFixedPatch( - capsulePos.x, capsulePos.y, - FRACUNIT, - V_SPLITSCREEN, - capsulePatch, NULL - ); - - V_DrawFixedPatch( - arrowPos.x, arrowPos.y, - FRACUNIT, - V_SPLITSCREEN | arrowFlags, - arrowPatch, NULL - ); - } - else - { - // Draw simple overlay. - const fixed_t farDistance = 1280*mapobjectscale; - boolean useNear = (caps->camDist < farDistance); - - patch_t *capsulePatch = NULL; - vector2_t capsulePos = {0}; - - boolean visible = P_CheckSight(stplyr->mo, caps->mobj); - - if (visible == false && (leveltime & 1)) - { - // Flicker when not visible. - return; - } - - capsulePos.x = result.x; - capsulePos.y = result.y; - - if (useNear == true) - { - timer = (leveltime / 2); - capsulePatch = kp_capsuletarget_near[timer % 8]; - } - else - { - timer = (leveltime / 3); - capsulePatch = kp_capsuletarget_far[timer & 1]; - } - - capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; - capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; - - V_DrawFixedPatch( - capsulePos.x, capsulePos.y, - FRACUNIT, - V_SPLITSCREEN, - capsulePatch, NULL - ); - } -} - static void K_drawKartNameTags(void) { const fixed_t maxdistance = 8192*mapobjectscale; @@ -3487,81 +3276,7 @@ static void K_drawKartNameTags(void) if (battlecapsules == true) { -#define MAX_CAPSULE_HUD 32 - capsuletracking_t capsuleList[MAX_CAPSULE_HUD]; - size_t capsuleListLen = 0; - - mobj_t *mobj = NULL; - mobj_t *next = NULL; - - for (mobj = trackercap; mobj; mobj = next) - { - capsuletracking_t *caps = NULL; - - next = mobj->itnext; - - if (mobj->health <= 0) - { - continue; - } - - if (mobj->type != MT_BATTLECAPSULE) - { - continue; - } - - caps = &capsuleList[capsuleListLen]; - - caps->mobj = mobj; - caps->point.x = R_InterpolateFixed(mobj->old_x, mobj->x); - caps->point.y = R_InterpolateFixed(mobj->old_y, mobj->y); - caps->point.z = R_InterpolateFixed(mobj->old_z, mobj->z); - caps->point.z += (mobj->height >> 1); - caps->camDist = R_PointToDist2(c.x, c.y, caps->point.x, caps->point.y); - - capsuleListLen++; - - if (capsuleListLen >= MAX_CAPSULE_HUD) - { - break; - } - } - - if (capsuleListLen > 0) - { - // Sort by distance from camera. - if (capsuleListLen > 1) - { - for (i = 0; i < capsuleListLen-1; i++) - { - size_t swap = i; - - for (j = i + 1; j < capsuleListLen; j++) - { - capsuletracking_t *cj = &capsuleList[j]; - capsuletracking_t *cSwap = &capsuleList[swap]; - - if (cj->camDist > cSwap->camDist) - { - swap = j; - } - } - - if (swap != i) - { - capsuletracking_t temp = capsuleList[swap]; - capsuleList[swap] = capsuleList[i]; - capsuleList[i] = temp; - } - } - } - - for (i = 0; i < capsuleListLen; i++) - { - K_DrawCapsuleTracking(&capsuleList[i]); - } - } -#undef MAX_CAPSULE_HUD + K_drawTargetHUD(&c, stplyr); } for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/k_hud.h b/src/k_hud.h index 9b783f710..7d2b5354a 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -44,8 +44,13 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol); void K_DrawMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, UINT16 map, UINT8 *colormap); void K_DrawLikeMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, patch_t *patch, UINT8 *colormap); +void K_drawTargetHUD(const vector3_t *origin, player_t *player); extern patch_t *kp_facehighlight[8]; +extern patch_t *kp_capsuletarget_arrow[2][2]; +extern patch_t *kp_capsuletarget_icon[2]; +extern patch_t *kp_capsuletarget_far[2]; +extern patch_t *kp_capsuletarget_near[8]; #ifdef __cplusplus } // extern "C" diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp new file mode 100644 index 000000000..8b6c782d5 --- /dev/null +++ b/src/k_hud_track.cpp @@ -0,0 +1,289 @@ +#include +#include + +#include "k_hud.h" +#include "m_fixed.h" +#include "p_local.h" +#include "p_mobj.h" +#include "r_fps.h" +#include "r_main.h" +#include "v_video.h" + +namespace +{ + +struct capsuletracking_t +{ + mobj_t* mobj; + vector3_t point; + fixed_t camDist; +}; + +void K_DrawCapsuleTracking(capsuletracking_t* caps) +{ + trackingResult_t result = {}; + int32_t timer = 0; + + K_ObjectTracking(&result, &caps->point, false); + + if (result.onScreen == false) + { + // Off-screen, draw alongside the borders of the screen. + // Probably the most complicated thing. + + int32_t scrVal = 240; + vector2_t screenSize = {}; + + int32_t borderSize = 7; + vector2_t borderWin = {}; + vector2_t borderDir = {}; + fixed_t borderLen = FRACUNIT; + + vector2_t arrowDir = {}; + + vector2_t arrowPos = {}; + patch_t* arrowPatch = nullptr; + int32_t arrowFlags = 0; + + vector2_t capsulePos = {}; + patch_t* capsulePatch = nullptr; + + timer = (leveltime / 3); + + screenSize.x = vid.width / vid.dupx; + screenSize.y = vid.height / vid.dupy; + + if (r_splitscreen >= 2) + { + // Half-wide screens + screenSize.x >>= 1; + borderSize >>= 1; + } + + if (r_splitscreen >= 1) + { + // Half-tall screens + screenSize.y >>= 1; + } + + scrVal = std::max(screenSize.x, screenSize.y) - 80; + + borderWin.x = screenSize.x - borderSize; + borderWin.y = screenSize.y - borderSize; + + arrowDir.x = 0; + arrowDir.y = P_MobjFlip(caps->mobj) * FRACUNIT; + + // Simply pointing towards the result doesn't work, so inaccurate hack... + borderDir.x = FixedMul( + FixedMul( + FINESINE((-result.angle >> ANGLETOFINESHIFT) & FINEMASK), + FINECOSINE((-result.pitch >> ANGLETOFINESHIFT) & FINEMASK) + ), + result.fov + ); + + borderDir.y = FixedMul(FINESINE((-result.pitch >> ANGLETOFINESHIFT) & FINEMASK), result.fov); + + borderLen = R_PointToDist2(0, 0, borderDir.x, borderDir.y); + + if (borderLen > 0) + { + borderDir.x = FixedDiv(borderDir.x, borderLen); + borderDir.y = FixedDiv(borderDir.y, borderLen); + } + else + { + // Eh just put it at the bottom. + borderDir.x = 0; + borderDir.y = FRACUNIT; + } + + capsulePatch = kp_capsuletarget_icon[timer & 1]; + + if (abs(borderDir.x) > abs(borderDir.y)) + { + // Horizontal arrow + arrowPatch = kp_capsuletarget_arrow[1][timer & 1]; + arrowDir.y = 0; + + if (borderDir.x < 0) + { + // LEFT + arrowDir.x = -FRACUNIT; + } + else + { + // RIGHT + arrowDir.x = FRACUNIT; + } + } + else + { + // Vertical arrow + arrowPatch = kp_capsuletarget_arrow[0][timer & 1]; + arrowDir.x = 0; + + if (borderDir.y < 0) + { + // UP + arrowDir.y = -FRACUNIT; + } + else + { + // DOWN + arrowDir.y = FRACUNIT; + } + } + + arrowPos.x = (screenSize.x >> 1) + FixedMul(scrVal, borderDir.x); + arrowPos.y = (screenSize.y >> 1) + FixedMul(scrVal, borderDir.y); + + arrowPos.x = std::clamp(arrowPos.x, borderSize, borderWin.x) * FRACUNIT; + arrowPos.y = std::clamp(arrowPos.y, borderSize, borderWin.y) * FRACUNIT; + + capsulePos.x = arrowPos.x - (arrowDir.x * 12); + capsulePos.y = arrowPos.y - (arrowDir.y * 12); + + arrowPos.x -= (arrowPatch->width << FRACBITS) >> 1; + arrowPos.y -= (arrowPatch->height << FRACBITS) >> 1; + + capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; + capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; + + if (arrowDir.x < 0) + { + arrowPos.x += arrowPatch->width << FRACBITS; + arrowFlags |= V_FLIP; + } + + if (arrowDir.y < 0) + { + arrowPos.y += arrowPatch->height << FRACBITS; + arrowFlags |= V_VFLIP; + } + + V_DrawFixedPatch(capsulePos.x, capsulePos.y, FRACUNIT, V_SPLITSCREEN, capsulePatch, nullptr); + + V_DrawFixedPatch(arrowPos.x, arrowPos.y, FRACUNIT, V_SPLITSCREEN | arrowFlags, arrowPatch, nullptr); + } + else + { + // Draw simple overlay. + const fixed_t farDistance = 1280 * mapobjectscale; + bool useNear = (caps->camDist < farDistance); + + patch_t* capsulePatch = nullptr; + vector2_t capsulePos = {}; + + bool visible = P_CheckSight(stplyr->mo, caps->mobj); + + if (visible == false && (leveltime & 1)) + { + // Flicker when not visible. + return; + } + + capsulePos.x = result.x; + capsulePos.y = result.y; + + if (useNear == true) + { + timer = (leveltime / 2); + capsulePatch = kp_capsuletarget_near[timer % 8]; + } + else + { + timer = (leveltime / 3); + capsulePatch = kp_capsuletarget_far[timer & 1]; + } + + capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; + capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; + + V_DrawFixedPatch(capsulePos.x, capsulePos.y, FRACUNIT, V_SPLITSCREEN, capsulePatch, nullptr); + } +} + +}; // namespace + +void K_drawTargetHUD(const vector3_t* origin, player_t* player) +{ + constexpr std::size_t kMaxCapsuleHUD = 32; + + std::size_t i, j; + + capsuletracking_t capsuleList[kMaxCapsuleHUD]; + std::size_t capsuleListLen = 0; + + mobj_t* mobj = nullptr; + mobj_t* next = nullptr; + + for (mobj = trackercap; mobj; mobj = next) + { + capsuletracking_t* caps = nullptr; + + next = mobj->itnext; + + if (mobj->health <= 0) + { + continue; + } + + if (mobj->type != MT_BATTLECAPSULE) + { + continue; + } + + caps = &capsuleList[capsuleListLen]; + + caps->mobj = mobj; + caps->point.x = R_InterpolateFixed(mobj->old_x, mobj->x); + caps->point.y = R_InterpolateFixed(mobj->old_y, mobj->y); + caps->point.z = R_InterpolateFixed(mobj->old_z, mobj->z); + caps->point.z += (mobj->height >> 1); + caps->camDist = R_PointToDist2(origin->x, origin->y, caps->point.x, caps->point.y); + + capsuleListLen++; + + if (capsuleListLen >= kMaxCapsuleHUD) + { + break; + } + } + + if (capsuleListLen > 0) + { + // Sort by distance from camera. + if (capsuleListLen > 1) + { + for (i = 0; i < capsuleListLen - 1; i++) + { + std::size_t swap = i; + + for (j = i + 1; j < capsuleListLen; j++) + { + capsuletracking_t* cj = &capsuleList[j]; + capsuletracking_t* cSwap = &capsuleList[swap]; + + if (cj->camDist > cSwap->camDist) + { + swap = j; + } + } + + if (swap != i) + { + capsuletracking_t temp = capsuleList[swap]; + capsuleList[swap] = capsuleList[i]; + capsuleList[i] = temp; + } + } + } + + for (i = 0; i < capsuleListLen; i++) + { + K_DrawCapsuleTracking(&capsuleList[i]); + } + } +} From 13762ee4e16fe7955c8717d106528f5791f8718d Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 19:04:34 -0800 Subject: [PATCH 2/5] k_hud_track.cpp: "capsule" -> "track" --- src/k_hud_track.cpp | 94 ++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index 8b6c782d5..a3b0be780 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -12,19 +12,19 @@ namespace { -struct capsuletracking_t +struct TargetTracking { mobj_t* mobj; vector3_t point; fixed_t camDist; }; -void K_DrawCapsuleTracking(capsuletracking_t* caps) +void K_DrawTargetTracking(TargetTracking* target) { trackingResult_t result = {}; int32_t timer = 0; - K_ObjectTracking(&result, &caps->point, false); + K_ObjectTracking(&result, &target->point, false); if (result.onScreen == false) { @@ -45,8 +45,8 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) patch_t* arrowPatch = nullptr; int32_t arrowFlags = 0; - vector2_t capsulePos = {}; - patch_t* capsulePatch = nullptr; + vector2_t targetPos = {}; + patch_t* targetPatch = nullptr; timer = (leveltime / 3); @@ -72,7 +72,7 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) borderWin.y = screenSize.y - borderSize; arrowDir.x = 0; - arrowDir.y = P_MobjFlip(caps->mobj) * FRACUNIT; + arrowDir.y = P_MobjFlip(target->mobj) * FRACUNIT; // Simply pointing towards the result doesn't work, so inaccurate hack... borderDir.x = FixedMul( @@ -99,7 +99,7 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) borderDir.y = FRACUNIT; } - capsulePatch = kp_capsuletarget_icon[timer & 1]; + targetPatch = kp_capsuletarget_icon[timer & 1]; if (abs(borderDir.x) > abs(borderDir.y)) { @@ -142,14 +142,14 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) arrowPos.x = std::clamp(arrowPos.x, borderSize, borderWin.x) * FRACUNIT; arrowPos.y = std::clamp(arrowPos.y, borderSize, borderWin.y) * FRACUNIT; - capsulePos.x = arrowPos.x - (arrowDir.x * 12); - capsulePos.y = arrowPos.y - (arrowDir.y * 12); + targetPos.x = arrowPos.x - (arrowDir.x * 12); + targetPos.y = arrowPos.y - (arrowDir.y * 12); arrowPos.x -= (arrowPatch->width << FRACBITS) >> 1; arrowPos.y -= (arrowPatch->height << FRACBITS) >> 1; - capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; - capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; + targetPos.x -= (targetPatch->width << FRACBITS) >> 1; + targetPos.y -= (targetPatch->height << FRACBITS) >> 1; if (arrowDir.x < 0) { @@ -163,7 +163,7 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) arrowFlags |= V_VFLIP; } - V_DrawFixedPatch(capsulePos.x, capsulePos.y, FRACUNIT, V_SPLITSCREEN, capsulePatch, nullptr); + V_DrawFixedPatch(targetPos.x, targetPos.y, FRACUNIT, V_SPLITSCREEN, targetPatch, nullptr); V_DrawFixedPatch(arrowPos.x, arrowPos.y, FRACUNIT, V_SPLITSCREEN | arrowFlags, arrowPatch, nullptr); } @@ -171,12 +171,12 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) { // Draw simple overlay. const fixed_t farDistance = 1280 * mapobjectscale; - bool useNear = (caps->camDist < farDistance); + bool useNear = (target->camDist < farDistance); - patch_t* capsulePatch = nullptr; - vector2_t capsulePos = {}; + patch_t* targetPatch = nullptr; + vector2_t targetPos = {}; - bool visible = P_CheckSight(stplyr->mo, caps->mobj); + bool visible = P_CheckSight(stplyr->mo, target->mobj); if (visible == false && (leveltime & 1)) { @@ -184,24 +184,24 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) return; } - capsulePos.x = result.x; - capsulePos.y = result.y; + targetPos.x = result.x; + targetPos.y = result.y; if (useNear == true) { timer = (leveltime / 2); - capsulePatch = kp_capsuletarget_near[timer % 8]; + targetPatch = kp_capsuletarget_near[timer % 8]; } else { timer = (leveltime / 3); - capsulePatch = kp_capsuletarget_far[timer & 1]; + targetPatch = kp_capsuletarget_far[timer & 1]; } - capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; - capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; + targetPos.x -= (targetPatch->width << FRACBITS) >> 1; + targetPos.y -= (targetPatch->height << FRACBITS) >> 1; - V_DrawFixedPatch(capsulePos.x, capsulePos.y, FRACUNIT, V_SPLITSCREEN, capsulePatch, nullptr); + V_DrawFixedPatch(targetPos.x, targetPos.y, FRACUNIT, V_SPLITSCREEN, targetPatch, nullptr); } } @@ -209,19 +209,19 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) void K_drawTargetHUD(const vector3_t* origin, player_t* player) { - constexpr std::size_t kMaxCapsuleHUD = 32; + constexpr std::size_t kMaxTargetHUD = 32; std::size_t i, j; - capsuletracking_t capsuleList[kMaxCapsuleHUD]; - std::size_t capsuleListLen = 0; + TargetTracking targetList[kMaxTargetHUD]; + std::size_t targetListLen = 0; mobj_t* mobj = nullptr; mobj_t* next = nullptr; for (mobj = trackercap; mobj; mobj = next) { - capsuletracking_t* caps = nullptr; + TargetTracking* target = nullptr; next = mobj->itnext; @@ -235,36 +235,36 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player) continue; } - caps = &capsuleList[capsuleListLen]; + target = &targetList[targetListLen]; - caps->mobj = mobj; - caps->point.x = R_InterpolateFixed(mobj->old_x, mobj->x); - caps->point.y = R_InterpolateFixed(mobj->old_y, mobj->y); - caps->point.z = R_InterpolateFixed(mobj->old_z, mobj->z); - caps->point.z += (mobj->height >> 1); - caps->camDist = R_PointToDist2(origin->x, origin->y, caps->point.x, caps->point.y); + target->mobj = mobj; + target->point.x = R_InterpolateFixed(mobj->old_x, mobj->x); + target->point.y = R_InterpolateFixed(mobj->old_y, mobj->y); + target->point.z = R_InterpolateFixed(mobj->old_z, mobj->z); + target->point.z += (mobj->height >> 1); + target->camDist = R_PointToDist2(origin->x, origin->y, target->point.x, target->point.y); - capsuleListLen++; + targetListLen++; - if (capsuleListLen >= kMaxCapsuleHUD) + if (targetListLen >= kMaxTargetHUD) { break; } } - if (capsuleListLen > 0) + if (targetListLen > 0) { // Sort by distance from camera. - if (capsuleListLen > 1) + if (targetListLen > 1) { - for (i = 0; i < capsuleListLen - 1; i++) + for (i = 0; i < targetListLen - 1; i++) { std::size_t swap = i; - for (j = i + 1; j < capsuleListLen; j++) + for (j = i + 1; j < targetListLen; j++) { - capsuletracking_t* cj = &capsuleList[j]; - capsuletracking_t* cSwap = &capsuleList[swap]; + TargetTracking* cj = &targetList[j]; + TargetTracking* cSwap = &targetList[swap]; if (cj->camDist > cSwap->camDist) { @@ -274,16 +274,16 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player) if (swap != i) { - capsuletracking_t temp = capsuleList[swap]; - capsuleList[swap] = capsuleList[i]; - capsuleList[i] = temp; + TargetTracking temp = targetList[swap]; + targetList[swap] = targetList[i]; + targetList[i] = temp; } } } - for (i = 0; i < capsuleListLen; i++) + for (i = 0; i < targetListLen; i++) { - K_DrawCapsuleTracking(&capsuleList[i]); + K_DrawTargetTracking(&targetList[i]); } } } From e79ff76758bd25e03f89a8051889c183dd6993b7 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 19:51:56 -0800 Subject: [PATCH 3/5] k_hud_track.cpp: refactor to use C++ STL - Use std::vector instead of fixed size array. - Use std::sort instead of custom sorting algorithm. --- src/k_hud.c | 2 +- src/k_hud.h | 2 +- src/k_hud_track.cpp | 77 ++++++++++----------------------------------- 3 files changed, 19 insertions(+), 62 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 5fbc5b1a3..86d36051c 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -832,7 +832,7 @@ INT32 POSI2_X, POSI2_Y; INT32 TCOOL_X, TCOOL_Y; // This version of the function was prototyped in Lua by Nev3r ... a HUGE thank you goes out to them! -void K_ObjectTracking(trackingResult_t *result, vector3_t *point, boolean reverse) +void K_ObjectTracking(trackingResult_t *result, const vector3_t *point, boolean reverse) { #define NEWTAN(x) FINETANGENT(((x + ANGLE_90) >> ANGLETOFINESHIFT) & 4095) // tan function used by Lua #define NEWCOS(x) FINECOSINE((x >> ANGLETOFINESHIFT) & FINEMASK) diff --git a/src/k_hud.h b/src/k_hud.h index 7d2b5354a..00839ed97 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -34,7 +34,7 @@ struct trackingResult_t fixed_t fov; }; -void K_ObjectTracking(trackingResult_t *result, vector3_t *point, boolean reverse); +void K_ObjectTracking(trackingResult_t *result, const vector3_t *point, boolean reverse); const char *K_GetItemPatch(UINT8 item, boolean tiny); void K_LoadKartHUDGraphics(void); diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index a3b0be780..c4063cccf 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "k_hud.h" #include "m_fixed.h" @@ -19,12 +20,12 @@ struct TargetTracking fixed_t camDist; }; -void K_DrawTargetTracking(TargetTracking* target) +void K_DrawTargetTracking(const TargetTracking& target) { trackingResult_t result = {}; int32_t timer = 0; - K_ObjectTracking(&result, &target->point, false); + K_ObjectTracking(&result, &target.point, false); if (result.onScreen == false) { @@ -72,7 +73,7 @@ void K_DrawTargetTracking(TargetTracking* target) borderWin.y = screenSize.y - borderSize; arrowDir.x = 0; - arrowDir.y = P_MobjFlip(target->mobj) * FRACUNIT; + arrowDir.y = P_MobjFlip(target.mobj) * FRACUNIT; // Simply pointing towards the result doesn't work, so inaccurate hack... borderDir.x = FixedMul( @@ -171,12 +172,12 @@ void K_DrawTargetTracking(TargetTracking* target) { // Draw simple overlay. const fixed_t farDistance = 1280 * mapobjectscale; - bool useNear = (target->camDist < farDistance); + bool useNear = (target.camDist < farDistance); patch_t* targetPatch = nullptr; vector2_t targetPos = {}; - bool visible = P_CheckSight(stplyr->mo, target->mobj); + bool visible = P_CheckSight(stplyr->mo, target.mobj); if (visible == false && (leveltime & 1)) { @@ -209,20 +210,13 @@ void K_DrawTargetTracking(TargetTracking* target) void K_drawTargetHUD(const vector3_t* origin, player_t* player) { - constexpr std::size_t kMaxTargetHUD = 32; - - std::size_t i, j; - - TargetTracking targetList[kMaxTargetHUD]; - std::size_t targetListLen = 0; + std::vector targetList; mobj_t* mobj = nullptr; mobj_t* next = nullptr; for (mobj = trackercap; mobj; mobj = next) { - TargetTracking* target = nullptr; - next = mobj->itnext; if (mobj->health <= 0) @@ -235,55 +229,18 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player) continue; } - target = &targetList[targetListLen]; + vector3_t pos = { + R_InterpolateFixed(mobj->old_x, mobj->x), + R_InterpolateFixed(mobj->old_y, mobj->y), + R_InterpolateFixed(mobj->old_z, mobj->z) + (mobj->height >> 1), + }; - target->mobj = mobj; - target->point.x = R_InterpolateFixed(mobj->old_x, mobj->x); - target->point.y = R_InterpolateFixed(mobj->old_y, mobj->y); - target->point.z = R_InterpolateFixed(mobj->old_z, mobj->z); - target->point.z += (mobj->height >> 1); - target->camDist = R_PointToDist2(origin->x, origin->y, target->point.x, target->point.y); - - targetListLen++; - - if (targetListLen >= kMaxTargetHUD) - { - break; - } + targetList.push_back({mobj, pos, R_PointToDist2(origin->x, origin->y, pos.x, pos.y)}); } - if (targetListLen > 0) - { - // Sort by distance from camera. - if (targetListLen > 1) - { - for (i = 0; i < targetListLen - 1; i++) - { - std::size_t swap = i; + // Sort by distance from camera. Further trackers get + // drawn first so nearer ones draw over them. + std::sort(targetList.begin(), targetList.end(), [](const auto& a, const auto& b) { return a.camDist > b.camDist; }); - for (j = i + 1; j < targetListLen; j++) - { - TargetTracking* cj = &targetList[j]; - TargetTracking* cSwap = &targetList[swap]; - - if (cj->camDist > cSwap->camDist) - { - swap = j; - } - } - - if (swap != i) - { - TargetTracking temp = targetList[swap]; - targetList[swap] = targetList[i]; - targetList[i] = temp; - } - } - } - - for (i = 0; i < targetListLen; i++) - { - K_DrawTargetTracking(&targetList[i]); - } - } + std::for_each(targetList.cbegin(), targetList.cend(), K_DrawTargetTracking); } From 4adf585590d1af07188f4736d43be4da7225a6ed Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 20:08:00 -0800 Subject: [PATCH 4/5] Give TARGET HUD tracking to UFO Catcher --- src/k_hud.c | 5 +---- src/k_hud_track.cpp | 15 ++++++++++++++- src/p_mobj.c | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 86d36051c..942405640 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3274,10 +3274,7 @@ static void K_drawKartNameTags(void) } } - if (battlecapsules == true) - { - K_drawTargetHUD(&c, stplyr); - } + K_drawTargetHUD(&c, stplyr); for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index c4063cccf..8a04dd7ae 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -206,6 +206,19 @@ void K_DrawTargetTracking(const TargetTracking& target) } } +bool is_object_tracking_target(const mobj_t* mobj) +{ + switch (mobj->type) + { + case MT_BATTLECAPSULE: + case MT_SPECIAL_UFO: + return true; + + default: + return false; + } +} + }; // namespace void K_drawTargetHUD(const vector3_t* origin, player_t* player) @@ -224,7 +237,7 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player) continue; } - if (mobj->type != MT_BATTLECAPSULE) + if (is_object_tracking_target(mobj) == false) { continue; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 707f10a17..67c4e95d6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5247,6 +5247,7 @@ static boolean P_IsTrackerType(INT32 type) // Primarily for minimap data, handle with care case MT_SPB: case MT_BATTLECAPSULE: + case MT_SPECIAL_UFO: return true; default: From 75c9ee253e9ee2cb6c5d36417715a60ce341974d Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 21:09:32 -0800 Subject: [PATCH 5/5] k_hud_track.cpp: only draw TARGET text in 1P or 2P splitscreen --- src/k_hud.c | 8 ++++++++ src/k_hud.h | 1 + src/k_hud_track.cpp | 27 +++++++++++++++++++-------- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 942405640..4fe7f352d 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -177,6 +177,7 @@ static patch_t *kp_trickcool[2]; patch_t *kp_capsuletarget_arrow[2][2]; patch_t *kp_capsuletarget_icon[2]; patch_t *kp_capsuletarget_far[2]; +patch_t *kp_capsuletarget_far_text[2]; patch_t *kp_capsuletarget_near[8]; void K_LoadKartHUDGraphics(void) @@ -665,6 +666,13 @@ void K_LoadKartHUDGraphics(void) } } + sprintf(buffer, "HUDCAPDx"); + for (i = 0; i < 2; i++) + { + buffer[7] = '0'+i; + HU_UpdatePatch(&kp_capsuletarget_far_text[i], "%s", buffer); + } + sprintf(buffer, "HUDCAPCx"); for (i = 0; i < 2; i++) { diff --git a/src/k_hud.h b/src/k_hud.h index 00839ed97..b80760c2c 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -50,6 +50,7 @@ extern patch_t *kp_facehighlight[8]; extern patch_t *kp_capsuletarget_arrow[2][2]; extern patch_t *kp_capsuletarget_icon[2]; extern patch_t *kp_capsuletarget_far[2]; +extern patch_t *kp_capsuletarget_far_text[2]; extern patch_t *kp_capsuletarget_near[8]; #ifdef __cplusplus diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index 8a04dd7ae..beaaea31f 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -174,7 +174,6 @@ void K_DrawTargetTracking(const TargetTracking& target) const fixed_t farDistance = 1280 * mapobjectscale; bool useNear = (target.camDist < farDistance); - patch_t* targetPatch = nullptr; vector2_t targetPos = {}; bool visible = P_CheckSight(stplyr->mo, target.mobj); @@ -188,21 +187,33 @@ void K_DrawTargetTracking(const TargetTracking& target) targetPos.x = result.x; targetPos.y = result.y; + auto draw = [&](patch_t* patch) + { + V_DrawFixedPatch( + targetPos.x - ((patch->width << FRACBITS) >> 1), + targetPos.y - ((patch->height << FRACBITS) >> 1), + FRACUNIT, + V_SPLITSCREEN, + patch, + nullptr + ); + }; + if (useNear == true) { timer = (leveltime / 2); - targetPatch = kp_capsuletarget_near[timer % 8]; + draw(kp_capsuletarget_near[timer % 8]); } else { timer = (leveltime / 3); - targetPatch = kp_capsuletarget_far[timer & 1]; + draw(kp_capsuletarget_far[timer & 1]); + + if (r_splitscreen <= 1) + { + draw(kp_capsuletarget_far_text[timer & 1]); + } } - - targetPos.x -= (targetPatch->width << FRACBITS) >> 1; - targetPos.y -= (targetPatch->height << FRACBITS) >> 1; - - V_DrawFixedPatch(targetPos.x, targetPos.y, FRACUNIT, V_SPLITSCREEN, targetPatch, nullptr); } }