From 96b13ab2cbd0a538d4b8e6f53b130529e26a285a Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 9 Feb 2025 14:48:40 -0500 Subject: [PATCH] Animated vote screens support --- src/lua_hudlib.c | 36 +++++++++++++ src/y_inter.c | 129 ++++++++++++++++++++++++++++++++++++++++++++--- src/y_inter.h | 1 + 3 files changed, 158 insertions(+), 8 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 65c076146..a7a4e7e35 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -16,6 +16,7 @@ #include "r_local.h" #include "r_fps.h" #include "st_stuff.h" +#include "y_inter.h" #include "g_game.h" #include "i_video.h" // rendermode #include "p_local.h" // camera_t @@ -1329,6 +1330,40 @@ static int lib_hudenabled(lua_State *L) return 1; } +static int lib_hudsetvotebackground(lua_State *L) +{ + if (lua_isnoneornil(L, 1)) + { + if (luaVoteScreen) + { + free(luaVoteScreen); + } + + luaVoteScreen = NULL; + + return 0; + } + + const char *prefix = luaL_checkstring(L, 1); + + if (strlen(prefix) != 4) + { + return luaL_argerror(L, 1, "prefix should 4 characters wide"); + } + + if (!luaVoteScreen) + { + luaVoteScreen = (char*)malloc(5); + luaVoteScreen[4] = 0; + } + + strncpy(luaVoteScreen, prefix, 4); + + strupr(luaVoteScreen); + + return 0; +} + // add a HUD element for rendering extern int lib_hudadd(lua_State *L); @@ -1337,6 +1372,7 @@ static luaL_Reg lib_hud[] = { {"disable", lib_huddisable}, {"enabled", lib_hudenabled}, {"add", lib_hudadd}, + {"setVoteBackground", lib_hudsetvotebackground}, {NULL, NULL} }; diff --git a/src/y_inter.c b/src/y_inter.c index f0478449e..01f36e2f3 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -111,6 +111,19 @@ static INT32 intertic; static INT32 endtic = -1; static INT32 sorttic = -1; +patch_t *animVoteFramesPatches = NULL; +// VEXTRN - Vote (V) Extra (EXT) Race (R) Normal (N - Normal sized patch) +// VEXTBN - Vote (V) Extra (EXT) Battle (B) Normal (N - Normal sized patch) +// VEXTBW - Vote (V) Extra (EXT) Battle (B) Normal (W - Wide patch used in software) +// VEXTRW - Vote (V) Extra (EXT) Race (R) Normal (W - Wide patch used in software) +char animPrefix[] = "INTSC"; +char animWidePrefix[] = "INTSW"; +char *luaVoteScreen = NULL; + +INT32 currentAnimFrame = 0; +static INT32 foundAnimVoteFrames = 0; +static INT32 foundAnimVoteWideFrames = 0; + intertype_t intertype = int_none; intertype_t intermissiontypes[NUMGAMETYPES]; @@ -153,6 +166,7 @@ typedef struct static y_votelvlinfo levelinfo[5]; static y_voteclient voteclient; static INT32 votetic; +static INT32 lastvotetic; static INT32 voteendtic = -1; static boolean votenotyetpicked; static patch_t *cursor = NULL; @@ -344,6 +358,53 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) } } +// +// Y_AnimatedVoteScreenCheck +// +// Check if the lumps exist (checking for VEXTR(N|W)xx for race and VEXTRB(N|W)xx for battle) +static void Y_AnimatedVoteScreenCheck(void) +{ + char tmpPrefix[] = "INTS"; + boolean stopSearching = false; + + if (luaVoteScreen) + strncpy(tmpPrefix, luaVoteScreen, 4); + else + { + if(gametype == GT_BATTLE) + strcpy(tmpPrefix, "BTLS"); + } + + strncpy(animPrefix, tmpPrefix, 4); + animPrefix[4] = 'C'; + strncpy(animWidePrefix, tmpPrefix, 4); + animWidePrefix[4] = 'W'; + + foundAnimVoteFrames = 0; + foundAnimVoteWideFrames = 0; + currentAnimFrame = 0; + + INT32 i = 1; + while(!stopSearching) + { + boolean normalLumpExists = W_LumpExists(va("%sC%d", tmpPrefix, i)); + boolean wideLumpExists = W_LumpExists(va("%sW%d", tmpPrefix, i)); + + if (normalLumpExists || wideLumpExists) + { + if (normalLumpExists) + foundAnimVoteFrames++; + + if (wideLumpExists) + foundAnimVoteWideFrames++; + } + else // If we don't find at least frame 1 (e.g VEXTRN1), let's just stop looking + stopSearching = true; + + i++; + } +} + // // Y_ConsiderScreenBuffer // @@ -1086,6 +1147,37 @@ static void Y_UnloadData(void) // SRB2Kart: Voting! +// Y_DrawAnimatedVoteScreenPatch +// +// Draw animated patch based on frame counter on vote screen +// +static inline void Y_DrawAnimatedVoteScreenPatch(boolean widePatch) +{ + char tempAnimPrefix[7]; + (widePatch) ? strcpy(tempAnimPrefix, animWidePrefix) : strcpy(tempAnimPrefix, animPrefix); + INT32 tempFoundAnimVoteFrames = (widePatch) ? foundAnimVoteWideFrames : foundAnimVoteFrames; + + // Just in case someone provides LESS widescreen frames than normal frames or vice versa, reset the frame counter to 0 + if (widePatch) + { + if (currentAnimFrame > foundAnimVoteWideFrames-1) + currentAnimFrame = 0; + } + else + { + if (currentAnimFrame > foundAnimVoteFrames-1) + currentAnimFrame = 0; + } + + patch_t *background = W_CachePatchName(va("%s%d", tempAnimPrefix, currentAnimFrame + 1), PU_CACHE); + V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(background->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?) + (vid.height / vid.dupy) - SHORT(background->height), + V_SNAPTOTOP|V_SNAPTOLEFT, background); + + if (renderisnewtic && votetic % 2 == 0 && !paused) + currentAnimFrame = (currentAnimFrame + 1 > tempFoundAnimVoteFrames - 1) ? 0 : currentAnimFrame + 1; +} + // // Y_VoteDrawer // @@ -1114,14 +1206,31 @@ void Y_VoteDrawer(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx > 320) - V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(widebgpatch->width)/2), - (vid.height / vid.dupy) - SHORT(widebgpatch->height), - V_SNAPTOTOP|V_SNAPTOLEFT, widebgpatch); - else - V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(bgpatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?) - (vid.height / vid.dupy) - SHORT(bgpatch->height), - V_SNAPTOTOP|V_SNAPTOLEFT, bgpatch); + if (widebgpatch && vid.width / vid.dupx > 320) { + + if(foundAnimVoteWideFrames == 0){ + V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(widebgpatch->width)/2), + (vid.height / vid.dupy) - SHORT(widebgpatch->height), + V_SNAPTOTOP|V_SNAPTOLEFT, widebgpatch); + } else { + // patch_t *currPatch = W_CachePatchName(va("%s%d", animPrefix, currentAnimFrame+1), PU_CACHE); + // V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(currPatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?) + // (vid.height / vid.dupy) - SHORT(currPatch->height), + // V_SNAPTOTOP|V_SNAPTOLEFT, currPatch); + // if(votetic % 4 == 0 && !paused){ + // currentAnimFrame = (currentAnimFrame+1 > foundAnimVoteFrames-1) ? 0 : currentAnimFrame + 1; + // } + Y_DrawAnimatedVoteScreenPatch(true); + } + } else { + if(foundAnimVoteFrames == 0) { + V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(bgpatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?) + (vid.height / vid.dupy) - SHORT(bgpatch->height), + V_SNAPTOTOP|V_SNAPTOLEFT, bgpatch); + } else { + Y_DrawAnimatedVoteScreenPatch(false); + } + } for (i = 0; i < 4; i++) // First, we need to figure out the height of this thing... { @@ -1339,6 +1448,8 @@ void Y_VoteDrawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, va("Vote ends in %d", tickdown)); } + + lastvotetic = votetic; } // @@ -1608,6 +1719,8 @@ void Y_StartVote(void) I_Error("voteendtic is dirty"); #endif + Y_AnimatedVoteScreenCheck(); + widebgpatch = W_CachePatchName(((gametype == GT_BATTLE) ? "BATTLSCW" : "INTERSCW"), PU_STATIC); bgpatch = W_CachePatchName(((gametype == GT_BATTLE) ? "BATTLSCR" : "INTERSCR"), PU_STATIC); cursor = W_CachePatchName("M_CURSOR", PU_STATIC); diff --git a/src/y_inter.h b/src/y_inter.h index 37c863fbe..3ad092744 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -17,6 +17,7 @@ extern "C" { #endif extern boolean usebuffer; +extern char *luaVoteScreen; void Y_IntermissionDrawer(void); void Y_Ticker(void);