From 74973764e278cbeea2e50debc0941387a21e0683 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Fri, 26 Sep 2025 21:12:26 -0400 Subject: [PATCH] Update Draft and Timers to support offsets and use stplyrnum more --- src/h_timers.cpp | 54 +++++++++++++++------ src/h_timers.h | 2 + src/hu_stuff.c | 2 +- src/k_hud.c | 123 +++++++++++++++++++++++++++++++++++++---------- src/k_hud.h | 3 ++ src/lua_hudlib.c | 22 ++++++--- src/st_stuff.c | 10 ++-- src/v_video.c | 2 +- 8 files changed, 163 insertions(+), 55 deletions(-) diff --git a/src/h_timers.cpp b/src/h_timers.cpp index fb85f7f65..678ed9a2e 100644 --- a/src/h_timers.cpp +++ b/src/h_timers.cpp @@ -173,6 +173,37 @@ void K_AddItemTimerEx( addTimers.push_back(t); } +void K_getTimersDrawinfo(drawinfo_t *out) +{ + INT32 fx, fy, flags = V_HUDTRANS|V_SNAPTOBOTTOM|V_SPLITSCREEN; + + fx = 160 + cv_timers_xoffset.value; + fy = 170 + cv_timers_yoffset.value; + + if (r_splitscreen == 1) + { + flags &= ~V_SNAPTOBOTTOM; + fx = 160; + fy = 75; + } + else if (r_splitscreen > 1) + { + flags &= ~V_SNAPTOBOTTOM; + fy = 75; + fx = 80; + } + + if (r_splitscreen > 0) + { + flags &= ~V_HUDTRANS; + flags |= V_30TRANS; + } + + out->x = fx; + out->y = fy; + out->flags = flags; +} + void K_DisplayItemTimers(void) { if (!cv_itemtimers.value) return; @@ -327,25 +358,16 @@ void K_DisplayItemTimers(void) if (!modeattacking) // "HOME" style, with icons at the bottom { - INT32 itemx = 160, itemy = 170; - INT32 flags = V_SNAPTOBOTTOM|V_SPLITSCREEN; + INT32 itemx = 0, itemy = 0; + INT32 flags = 0; INT32 stepx = 25; INT32 viewnum = R_GetViewNumber(); - if (r_splitscreen == 1) - { - flags &= ~V_SNAPTOBOTTOM; - itemy = 75; - } - else if (r_splitscreen > 1) - { - flags &= ~V_SNAPTOBOTTOM; - itemy = 75; - itemx = 80; - } - - if (r_splitscreen > 0) - flags |= V_30TRANS; + drawinfo_t info; + K_getTimersDrawinfo(&info); + itemx = info.x; + itemy = info.y; + flags = info.flags; // Move it up to account for viewpoint text if (cv_showviewpointtext.value && !demo.title && !P_IsLocalPlayer(stplyr) && !camera[viewnum].freecam && !r_splitscreen) diff --git a/src/h_timers.h b/src/h_timers.h index 03de64462..4632284a5 100644 --- a/src/h_timers.h +++ b/src/h_timers.h @@ -18,6 +18,7 @@ extern "C" { #include "command.h" #include "d_player.h" +#include "k_hud.h" extern consvar_t cv_itemtimers; extern tic_t spbTimers[MAXPLAYERS]; @@ -34,6 +35,7 @@ void K_AddItemTimerEx( INT32 xoffs_small, INT32 yoffs_small, boolean counter, boolean unsorted); void K_DisplayItemTimers(void); +void K_getTimersDrawinfo(drawinfo_t *out); #ifdef __cplusplus } // extern "C" diff --git a/src/hu_stuff.c b/src/hu_stuff.c index f1acbb315..0c4e4d88b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2058,7 +2058,7 @@ static void HU_DrawDemoInfo(void) void HU_DrawSongCredits(void) { fixed_t x; - fixed_t y = (r_splitscreen ? (BASEVIDHEIGHT/2)-4 : 32) * FRACUNIT; + fixed_t y = ((r_splitscreen && G_GamestateUsesLevel()) ? (BASEVIDHEIGHT/2)-4 : 32) * FRACUNIT; INT32 snapflags = cursongcredit.snapflags; INT32 bgt; diff --git a/src/k_hud.c b/src/k_hud.c index a2439b373..0ae9532e6 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -65,6 +65,8 @@ IMPL_HUD_OFFSET(rings); // Number of rings IMPL_HUD_OFFSET(dnft); // Countdown (did not finish timer) IMPL_HUD_OFFSET(speed); // Speedometer IMPL_HUD_OFFSET(acce); // Accessibility +IMPL_HUD_OFFSET(timers); // Drafting +IMPL_HUD_OFFSET(draft); // Drafting IMPL_HUD_OFFSET(posi); // Position in race IMPL_HUD_OFFSET(face); // Mini rankings IMPL_HUD_OFFSET(stcd); // Starting countdown @@ -104,6 +106,8 @@ consvar_t cv_colorizedhudcolor = CVAR_INIT ("colorizedhudcolor", "Skin Color", C consvar_t cv_newtabranking = CVAR_INIT ("newtabranking", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_draftindicator = CVAR_INIT ("draftindicator", "On", CV_SAVE, CV_OnOff, NULL); + //{ Patch Definitions static patch_t *kp_nodraw; @@ -235,6 +239,8 @@ void K_RegisterKartHUDStuff(void) REG_HUD_OFFSET(dnft); // Countdown (did not finish timer) REG_HUD_OFFSET(speed); // Speedometer REG_HUD_OFFSET(acce); // Accessibility + REG_HUD_OFFSET(timers); // Item Timers + REG_HUD_OFFSET(draft); // Drafting REG_HUD_OFFSET(posi); // Position in race REG_HUD_OFFSET(face); // Mini rankings REG_HUD_OFFSET(stcd); // Starting countdown @@ -260,6 +266,7 @@ void K_RegisterKartHUDStuff(void) CV_RegisterVar(&cv_driftgauge); CV_RegisterVar(&cv_driftgaugeoffset); CV_RegisterVar(&cv_newtabranking); + CV_RegisterVar(&cv_draftindicator); } void K_LoadKartHUDGraphics(void) @@ -762,6 +769,7 @@ INT32 LAPS_X, LAPS_Y; // Lap Sticker INT32 RING_X, RING_Y; // Player Rings INT32 SPDM_X, SPDM_Y; // Speedometer INT32 ACCE_X, ACCE_Y; // Accessibility +INT32 DRAT_X, DRAT_Y; // Drafting INT32 POSI_X, POSI_Y; // Position Number INT32 FACE_X, FACE_Y; // Top-four Faces INT32 STCD_X, STCD_Y; // Starting countdown @@ -774,6 +782,7 @@ INT32 ITEM2_X, ITEM2_Y; INT32 LAPS2_X, LAPS2_Y; INT32 RING2_X, RING2_Y; INT32 POSI2_X, POSI2_Y; +INT32 DRAT2_X, DRAT2_Y; void K_ReloadHUDColorCvar(void) { @@ -1015,6 +1024,9 @@ static void K_initKartHUD(void) // Accessibility ACCE_X = 9 + cv_speed_xoffset.value; // 9 ACCE_Y = BASEVIDHEIGHT - 29 + cv_speed_yoffset.value; // 171 + // Drafting + DRAT_X = 172 + cv_draft_xoffset.value; // 172 + DRAT_Y = BASEVIDHEIGHT - 41 + cv_draft_yoffset.value; // 159 // Position Number POSI_X = BASEVIDWIDTH - 9 + cv_posi_xoffset.value; // 268 POSI_Y = BASEVIDHEIGHT - 9 + cv_posi_yoffset.value; // 138 @@ -1035,19 +1047,29 @@ static void K_initKartHUD(void) if (r_splitscreen) // Splitscreen { + // Lock the positions in. ITEM_X = 5; ITEM_Y = 3; + LAPS_X = 9; LAPS_Y = (BASEVIDHEIGHT/2)-24; + RING_X = 9; RING_Y = (BASEVIDHEIGHT/2)-24; + SPDM_X = 9; SPDM_Y = (BASEVIDHEIGHT/2)-24; - POSI_Y = (BASEVIDHEIGHT/2)- 2; + POSI_X = BASEVIDWIDTH; + POSI_Y = (BASEVIDHEIGHT/2)-2; + DRAT_X = 172; + DRAT_Y = (BASEVIDHEIGHT/2)-34; + + STCD_X = BASEVIDWIDTH/2; STCD_Y = BASEVIDHEIGHT/4; + MINI_X = BASEVIDWIDTH - 50; MINI_Y = (BASEVIDHEIGHT/2); if (r_splitscreen > 1) // 3P/4P Small Splitscreen @@ -1065,6 +1087,9 @@ static void K_initKartHUD(void) POSI_X = 24; POSI_Y = (BASEVIDHEIGHT/2)-26; + DRAT_X = 95; + DRAT_Y = (BASEVIDHEIGHT/2)-32; + // 2P (top right) ITEM2_X = (BASEVIDWIDTH/2)-39; ITEM2_Y = -8; @@ -1078,6 +1103,9 @@ static void K_initKartHUD(void) POSI2_X = (BASEVIDWIDTH/2)-4; POSI2_Y = (BASEVIDHEIGHT/2)-26; + DRAT2_X = 95; + DRAT2_Y = (BASEVIDHEIGHT/2)-32; + // Reminder that 3P and 4P are just 1P and 2P splitscreen'd to the bottom. STCD_X = BASEVIDWIDTH/4; @@ -1108,7 +1136,7 @@ void K_getItemBoxDrawinfo(drawinfo_t *out) } else // now we're having a fun game. { - if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... + if (stplyrnum == 0 || stplyrnum == 2) // If we are P1 or P3... { fx = ITEM_X; fy = ITEM_Y; @@ -1142,7 +1170,7 @@ void K_getLapsDrawinfo(drawinfo_t *out) } else { - if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... + if (stplyrnum == 0 || stplyrnum == 2) // If we are P1 or P3... { fx = LAPS_X; fy = LAPS_Y; @@ -1174,7 +1202,7 @@ void K_getRingsDrawinfo(drawinfo_t *out) } else { - if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... + if (stplyrnum == 0 || stplyrnum == 2) // If we are P1 or P3... { fx = RING_X; fy = RING_Y; @@ -1756,7 +1784,7 @@ static void K_DrawKartPositionNum(INT32 num) else if (r_splitscreen == 1) // for this splitscreen, we'll use case by case because it's a bit different. { fx = POSI_X; - if (stplyr == &players[displayplayers[0]]) // for player 1: display this at the top right, above the minimap. + if (stplyrnum == 0) // for player 1: display this at the top right, above the minimap. { fy = 30; fflags = V_SNAPTOTOP|V_SNAPTORIGHT|V_SPLITSCREEN; @@ -1771,7 +1799,7 @@ static void K_DrawKartPositionNum(INT32 num) } else { - if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... + if (stplyrnum == 0 || stplyrnum == 2) // If we are P1 or P3... { fx = POSI_X; fy = POSI_Y; @@ -2701,7 +2729,7 @@ static void K_drawKartAccessibilityIcons(INT32 fx) { fx = ACCE_X+43; fy = ACCE_Y; - if (!(stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]])) // If we are not P1 or P3... + if (!(stplyrnum == 0 || stplyrnum == 2)) // If we are not P1 or P3... { splitflags ^= (V_SNAPTOLEFT|V_SNAPTORIGHT); fx = (BASEVIDWIDTH/2) - (fx + 10); @@ -3950,7 +3978,7 @@ static void K_drawKartMinimap(void) // Only draw for the first player // Maybe move this somewhere else where this won't be a concern? - if (stplyr != &players[displayplayers[0]]) + if (stplyrnum != 0) return; if (minimapinfo.minimap_pic == NULL) @@ -4553,7 +4581,7 @@ static void K_drawKartFinish(void) interpx = R_InterpolateFixed(ox, x); - if (r_splitscreen && stplyr == &players[displayplayers[1]]) + if (r_splitscreen && stplyrnum == 1) interpx = -interpx; V_DrawFixedPatch(interpx + (STCD_X<spectator || !stplyr->mo || (stplyr->mo->renderflags & RF_DONTDRAW)) return; - if (stplyr == &players[displayplayers[1]] && r_splitscreen) + if (stplyrnum == 1 && r_splitscreen) { pn = pnum[1]; tn = turn[1]; dr = drift[1]; } - else if (stplyr == &players[displayplayers[2]] && r_splitscreen > 1) + else if (stplyrnum == 2 && r_splitscreen > 1) { pn = pnum[2]; tn = turn[2]; dr = drift[2]; } - else if (stplyr == &players[displayplayers[3]] && r_splitscreen > 2) + else if (stplyrnum == 3 && r_splitscreen > 2) { pn = pnum[3]; tn = turn[3]; dr = drift[3]; } else { pn = pnum[0]; tn = turn[0]; dr = drift[0]; } @@ -4831,11 +4859,11 @@ static void K_drawKartFirstPerson(void) V_DrawFixedPatch(x, y, scale, splitflags, kp_fpview[target], colmap); - if (stplyr == &players[displayplayers[1]] && r_splitscreen) + if (stplyrnum == 1 && r_splitscreen) { pnum[1] = pn; turn[1] = tn; drift[1] = dr; } - else if (stplyr == &players[displayplayers[2]] && r_splitscreen > 1) + else if (stplyrnum == 2 && r_splitscreen > 1) { pnum[2] = pn; turn[2] = tn; drift[2] = dr; } - else if (stplyr == &players[displayplayers[3]] && r_splitscreen > 2) + else if (stplyrnum == 3 && r_splitscreen > 2) { pnum[3] = pn; turn[3] = tn; drift[3] = dr; } else { pnum[0] = pn; turn[0] = tn; drift[0] = dr; } @@ -5411,7 +5439,7 @@ static void K_drawDistributionDebugger(void) boolean dontforcespb = false; boolean spbrush = false; - //if (stplyr != &players[displayplayers[0]]) // only for p1 + //if (stplyrnum != 0) // only for p1 //return; // The only code duplication from the Kart, just to avoid the actual item function from calculating pingame twice @@ -5490,7 +5518,7 @@ static void K_drawDistributionDebugger(void) static void K_drawCheckpointDebugger(void) { - if (stplyr != &players[displayplayers[0]]) // only for p1 + if (stplyrnum != 0) // only for p1 return; if (stplyr->starpostnum >= K_CheckpointThreshold(true)) @@ -5509,7 +5537,7 @@ static void K_DrawWaypointDebugger(void) if (cv_kartdebugwaypoints.value == 0) return; - if (stplyr != &players[displayplayers[0]]) // only for p1 + if (stplyrnum != 0) // only for p1 return; if (stplyr->bigwaypointgap) @@ -5527,7 +5555,7 @@ static void K_DrawClusterDebugger(void) if (cv_kartdebugcluster.value == 0) return; - if (stplyr != &players[displayplayers[0]]) // only for p1 + if (stplyrnum != 0) // only for p1 return; INT32 vflags = V_6WIDTHSPACE|V_ALLOWLOWERCASE; @@ -5545,16 +5573,61 @@ static void K_DrawClusterDebugger(void) } } +void K_getSlipstreamDrawinfo(drawinfo_t *out) +{ + INT32 fx, fy, splitflags = 0; + + if (r_splitscreen < 2) // don't change shit for THIS splitscreen. + { + fx = DRAT_X; + fy = DRAT_Y; + splitflags = V_SPLITSCREEN; + + if (r_splitscreen > 0) + splitflags |= V_30TRANS; + } + else // now we're having a fun game. + { + if (stplyrnum == 0 || stplyrnum == 2) // If we are P1 or P3... + { + fx = DRAT_X; + fy = DRAT_Y; + splitflags = V_30TRANS|V_SPLITSCREEN; + } + else // else, that means we're P2 or P4. + { + fx = DRAT2_X; + fy = DRAT2_Y; + splitflags = V_30TRANS|V_SPLITSCREEN; + } + } + + out->x = fx; + out->y = fy; + out->flags = splitflags; +} + static void K_SlipstreamIndicator(boolean tiny) { - if (!draftingactive) + if (!K_DraftingActive()) + return; + + if (!cv_draftindicator.value) return; char *fullstr = "DRAFTING"; char str[256] = {0}; SINT8 stringlen = strlen(fullstr); SINT8 len = min(stplyr->draftpower / (FRACUNIT / stringlen), stringlen); - INT32 flags = V_SPLITSCREEN|V_HUDTRANS; + INT32 flags; + INT32 fx, fy; + + drawinfo_t info; + K_getSlipstreamDrawinfo(&info); + + fx = info.x; + fy = info.y; + flags = info.flags; if (!len) return; @@ -5568,9 +5641,9 @@ static void K_SlipstreamIndicator(boolean tiny) } if (tiny) - V_DrawSmallString(174 - V_StringWidth(str, flags)/2, 159, flags, str); + V_DrawSmallString(fx - V_StringWidth(str, flags)/2, fy, flags, str); else - V_DrawThinString(174 - V_StringWidth(str, flags)/2, 159, flags, str); + V_DrawThinString(fx - V_StringWidth(str, flags)/2, fy, flags, str); } void K_drawKartHUD(void) @@ -5593,7 +5666,7 @@ void K_drawKartHUD(void) } // Draw full screen stuff that turns off the rest of the HUD - if (mapreset && stplyr == &players[displayplayers[0]]) + if (mapreset && stplyrnum == 0) { K_drawChallengerScreen(); return; @@ -5780,7 +5853,7 @@ void K_drawKartHUD(void) } K_DisplayItemTimers(); - K_SlipstreamIndicator(r_splitscreen > 0); + K_SlipstreamIndicator(r_splitscreen > 1); if (modeattacking || freecam) // everything after here is MP and debug only return; diff --git a/src/k_hud.h b/src/k_hud.h index 9266f8032..ece25745d 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -41,6 +41,8 @@ IMPL_HUD_OFFSET(rings); // Number of rings IMPL_HUD_OFFSET(dnft); // Countdown (did not finish timer) IMPL_HUD_OFFSET(speed); // Speedometer IMPL_HUD_OFFSET(acce); // Accessibility +IMPL_HUD_OFFSET(timers); // Drafting +IMPL_HUD_OFFSET(draft); // Drafting IMPL_HUD_OFFSET(posi); // Position in race IMPL_HUD_OFFSET(face); // Mini rankings IMPL_HUD_OFFSET(stcd); // Starting countdown @@ -91,6 +93,7 @@ void K_getItemBoxDrawinfo(drawinfo_t *out); void K_getLapsDrawinfo(drawinfo_t *out); void K_getRingsDrawinfo(drawinfo_t *out); void K_getMinimapDrawinfo(drawinfo_t *out); +void K_getSlipstreamDrawinfo(drawinfo_t *out); const char *K_GetItemPatch(UINT8 item, boolean tiny); void K_ReloadHUDColorCvar(void); boolean K_UseColorHud(void); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 694dd79bf..ce2ccdf3d 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -34,6 +34,7 @@ #include "lua_hook.h" #include "k_hud.h" +#include "h_timers.h" #define HUDONLY if (!hud_running) return luaL_error(L, "HUD rendering code should not be called outside of rendering hooks!"); @@ -749,7 +750,7 @@ static int libd_drawOnMinimap(lua_State *L) if (gamestate != GS_LEVEL) return 0; - if (stplyr != &players[displayplayers[0]]) + if (stplyrnum != 0) return 0; if (minimapinfo.minimap_pic == NULL) @@ -1387,7 +1388,9 @@ enum huddrawinfo { huddrawinfo_item = 0, huddrawinfo_gametypeinfo, huddrawinfo_rings, - huddrawinfo_minimap + huddrawinfo_minimap, + huddrawinfo_timers, + huddrawinfo_drafting, }; static const char *const hud_drawinfo_options[] = { @@ -1395,6 +1398,8 @@ static const char *const hud_drawinfo_options[] = { "gametypeinfo", "rings", "minimap", + "timers", + "drafting", NULL}; static int libd_getDrawInfo(lua_State *L) @@ -1404,10 +1409,12 @@ static int libd_getDrawInfo(lua_State *L) drawinfo_t info; switch(option) { - case huddrawinfo_item: K_getItemBoxDrawinfo(&info); break; - case huddrawinfo_gametypeinfo: K_getLapsDrawinfo(&info); break; - case huddrawinfo_rings: K_getRingsDrawinfo(&info); break; - case huddrawinfo_minimap: K_getMinimapDrawinfo(&info); break; + case huddrawinfo_item: K_getItemBoxDrawinfo(&info); break; + case huddrawinfo_gametypeinfo: K_getLapsDrawinfo(&info); break; + case huddrawinfo_rings: K_getRingsDrawinfo(&info); break; + case huddrawinfo_minimap: K_getMinimapDrawinfo(&info); break; + case huddrawinfo_timers: K_getSlipstreamDrawinfo(&info); break; + case huddrawinfo_drafting: K_getTimersDrawinfo(&info); break; default: return 0; // unreachable } @@ -1415,7 +1422,8 @@ static int libd_getDrawInfo(lua_State *L) lua_pushinteger(L, info.x); lua_pushinteger(L, info.y); lua_pushinteger(L, info.flags); - return 3; + lua_pushinteger(L, info.flipamount); + return 4; } // Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int diff --git a/src/st_stuff.c b/src/st_stuff.c index 7f6c7f4c1..f2ff1ded7 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -343,7 +343,7 @@ static INT32 SCY(INT32 y) if (splitscreen) { y >>= 1; - if (stplyr != &players[displayplayers[0]]) + if (stplyrnum != 0) y += vid.height / 2; } return y; @@ -359,7 +359,7 @@ static INT32 STRINGY(INT32 y) if (splitscreen) { y >>= 1; - if (stplyr != &players[displayplayers[0]]) + if (stplyrnum != 0) y += BASEVIDHEIGHT / 2; } return y; @@ -372,7 +372,7 @@ static INT32 SPLITFLAGS(INT32 f) // Pass this V_SNAPTO(TOP|BOTTOM) and it'll trim them to account for splitscreen! -Red if (splitscreen) { - if (stplyr != &players[displayplayers[0]]) + if (stplyrnum != 0) f &= ~V_SNAPTOTOP; else f &= ~V_SNAPTOBOTTOM; @@ -399,7 +399,7 @@ static INT32 SCR(INT32 r) if (splitscreen) { y >>= 1; - if (stplyr != &players[displayplayers[0]]) + if (stplyrnum != 0) y += vid.height / 2; } return FixedInt(FixedDiv(y, vid.fdupy)); @@ -842,7 +842,7 @@ static void ST_overlayDrawer(void) { char name[MAXPLAYERNAME+12]; - INT32 y = (stplyr == &players[displayplayers[0]]) ? 4 : BASEVIDHEIGHT/2-12; + INT32 y = (stplyrnum == 0) ? 4 : BASEVIDHEIGHT/2-12; sprintf(name, "VIEWPOINT: %s", player_names[stplyr-players]); V_DrawRightAlignedThinString(BASEVIDWIDTH-40, y, V_HUDTRANSHALF|V_ALLOWLOWERCASE|V_SNAPTOTOP|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN, name); } diff --git a/src/v_video.c b/src/v_video.c index 829ffc3ef..111d250fc 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -616,7 +616,7 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du if (r_splitscreen > 1) { - if (stplyr == &players[displayplayers[1]] || stplyr == &players[displayplayers[3]]) + if (stplyrnum == 1 || stplyrnum == 3) slidefromright = true; }