From 8e94a8c9fd09ce9841eb2cee7b6a1cad2766c5b8 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Thu, 26 Jun 2025 11:56:23 -0400 Subject: [PATCH] Vote screen visual refactor port from saturn Thanks to Alug as per usual --- src/lua_hudlib.c | 20 +--- src/p_setup.c | 168 +++++++++++++++------------ src/p_setup.h | 5 - src/y_inter.c | 297 +++++++++++++++++++++++++---------------------- src/y_inter.h | 34 +++++- 5 files changed, 288 insertions(+), 236 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index c71f7f629..d46da6d36 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -1532,15 +1532,10 @@ static int lib_hudenabled(lua_State *L) static int lib_hudsetvotebackground(lua_State *L) { + memset(VoteScreen.luaPrefix, 0, sizeof(VoteScreen.luaPrefix)); + if (lua_isnoneornil(L, 1)) { - if (luaVoteScreen) - { - free(luaVoteScreen); - } - - luaVoteScreen = NULL; - return 0; } @@ -1551,15 +1546,8 @@ static int lib_hudsetvotebackground(lua_State *L) 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); + strncpy(VoteScreen.luaPrefix, prefix, 4); + strupr(VoteScreen.luaPrefix); return 0; } diff --git a/src/p_setup.c b/src/p_setup.c index c82da3227..8b27500eb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -70,6 +70,8 @@ #include "deh_tables.h" +#include "y_inter.h" + // for MapLoad hook #include "lua_script.h" #include "lua_hook.h" @@ -9246,11 +9248,92 @@ boolean P_AddWadFile(const char *wadfilename, wadcompat_t compat) return true; } -// check for replacement votescreen backgrounds -boolean wideracereplaced = false; -boolean racereplaced = false; -boolean widebattlereplaced = false; -boolean battlereplaced = false; +static size_t sreplaces = 0, mreplaces = 0, digmreplaces = 0; + + +// +// search for sound replacements +// +static boolean P_CheckSoundReplacements(char *name, size_t i) +{ + if (name[0] == 'D') + { + if (name[1] == 'S') + { + for (i = 1; i < NUMSFX; i++) + { + if (S_sfx[i].name && !strnicmp(S_sfx[i].name, name + 2, 6)) + { + // the sound will be reloaded when needed, + // since sfx->data will be NULL + CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name); + + I_FreeSfx(&S_sfx[i]); + + // Re-cache it + //if (S_PrecacheSound()) + //S_sfx[j].data = I_GetSfx(&S_sfx[j]); + + sreplaces++; + return true; + } + } + } + else if (name[1] == '_') + { + CONS_Debug(DBG_SETUP, "Music %.8s ignored\n", name); + mreplaces++; + return true; + } + } + else if (name[0] == 'O' && name[1] == '_') + { + CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); + digmreplaces++; + return true; + } + return false; +} + +// +// check for non Lua votescreen replacements +// +static boolean P_CheckVoteReplacements(char *name) +{ + // widescreen patch Race + if (!VoteScreen.replaced.widerace && !memcmp(name, "INTERSCW", 8)) + { + VoteScreen.replaced.widerace = true; + return false; + } + + if (!VoteScreen.replaced.race && !memcmp(name, "INTERSCR", 8)) + { + VoteScreen.replaced.race = true; + return false; + } + + // widescreen patch Battle + if (!VoteScreen.replaced.widebattle && !memcmp(name, "BATTLSCW", 8)) + { + VoteScreen.replaced.widebattle = true; + return false; + } + + if (!VoteScreen.replaced.battle && !memcmp(name, "BATTLSCR", 8)) + { + VoteScreen.replaced.battle = true; + return false; + } + + if (VoteScreen.replaced.widerace && VoteScreen.replaced.race + && VoteScreen.replaced.widebattle && VoteScreen.replaced.battle) + { + return true; + } + + return false; +} // // Add a WAD file and do the per-WAD setup stages. @@ -9258,11 +9341,14 @@ boolean battlereplaced = false; // UINT16 P_PartialAddWadFile(const char *wadfilename, wadcompat_t compat) { - size_t i, j, sreplaces = 0, mreplaces = 0, digmreplaces = 0; + size_t i; UINT16 numlumps, wadnum; char *name; + static boolean allvotereplaced = false; lumpinfo_t *lumpinfo; + sreplaces = mreplaces = digmreplaces = 0; + // Vars to help us with the position start and amount of each resource type. // Useful for PK3s since they use folders. // WADs use markers for some resources, but others such as sounds are checked lump-by-lump anyway. @@ -9336,36 +9422,12 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, wadcompat_t compat) for (i = 0; i < numlumps; i++, lumpinfo++) { name = lumpinfo->name; - if (name[0] == 'D') - { - if (name[1] == 'S') - { - for (j = 1; j < NUMSFX; j++) - { - if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6)) - { - // the sound will be reloaded when needed, - // since sfx->data will be NULL - CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name); - I_FreeSfx(&S_sfx[j]); + if (P_CheckSoundReplacements(name, i)); + continue; - sreplaces++; - break; // there shouldn't be two sounds with the same name, so stop looking - } - } - } - else if (name[1] == '_') - { - CONS_Debug(DBG_SETUP, "Music %.8s ignored\n", name); - mreplaces++; - } - } - else if (name[0] == 'O' && name[1] == '_') - { - CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); - digmreplaces++; - } + if (!allvotereplaced && P_CheckVoteReplacements(name)) + allvotereplaced = true; } break; } @@ -9417,44 +9479,6 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, wadcompat_t compat) // R_LoadSpriteInfoLumps(wadnum, numlumps); - // - // check for votescreen replacements - // - if (!wideracereplaced && !racereplaced && !widebattlereplaced && !battlereplaced) - { - lumpinfo = wadfiles[wadnum]->lumpinfo; - for (i = 0; i < numlumps; i++, lumpinfo++) - { - name = lumpinfo->name; - - // widescreen patch Race - if (!wideracereplaced && !strncmp(name, "INTERSCW", 8)) - { - wideracereplaced = true; - continue; - } - - if (!racereplaced && !strncmp(name, "INTERSCR", 8)) - { - racereplaced = true; - continue; - } - - // widescreen patch Battle - if (!widebattlereplaced && !strncmp(name, "BATTLSCW", 8)) - { - widebattlereplaced = true; - continue; - } - - if (!battlereplaced && !strncmp(name, "BATTLSCR", 8)) - { - battlereplaced = true; - continue; - } - } - } - refreshdirmenu &= ~REFRESHDIR_GAMEDATA; // Under usual circumstances we'd wait for REFRESHDIR_ flags to disappear the next frame, but this one's a bit too dangerous for that... partadd_stage = 0; return wadnum; diff --git a/src/p_setup.h b/src/p_setup.h index b207709f2..c7c438d3d 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -87,11 +87,6 @@ void HWR_LoadLevel(void); #endif boolean P_AddWadFile(const char *wadfilename, wadcompat_t compat); -extern boolean wideracereplaced; -extern boolean racereplaced; -extern boolean widebattlereplaced; -extern boolean battlereplaced; - #define MAPRET_ADDED (1) #define MAPRET_CURRENTREPLACED (1<<1) UINT8 P_InitMapData(boolean existingmapheaders); diff --git a/src/y_inter.c b/src/y_inter.c index 0310b0fbe..38e848f64 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -84,11 +84,10 @@ typedef struct static y_data data; // graphics -static patch_t *bgpatch = NULL; // INTERSCR -static patch_t *widebgpatch = NULL; static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK static patch_t *interpic = NULL; // custom picture defined in map header static boolean usetile; + static INT32 timer; typedef struct @@ -111,19 +110,6 @@ 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]; @@ -163,6 +149,9 @@ typedef struct boolean loaded; } y_voteclient; +// votescreen stuff +votescreen_t VoteScreen = {0}; + static y_votelvlinfo levelinfo[13]; static y_voteclient voteclient; static INT32 votetic; @@ -172,12 +161,6 @@ static SINT8 votemax = 3; static INT32 voterowmem = 0; static boolean rowchange = false; static boolean votenotyetpicked; -static patch_t *cursor = NULL; -static patch_t *cursor1 = NULL; -static patch_t *cursor2 = NULL; -static patch_t *cursor3 = NULL; -static patch_t *cursor4 = NULL; -static patch_t *rubyicon = NULL; static void Y_UnloadVoteData(void); @@ -360,48 +343,6 @@ 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"; - - 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 = foundAnimVoteWideFrames = 0; - currentAnimFrame = 0; - - INT32 i = 1; - for (;;) - { - 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 - break; - - i++; - } -} - // // Y_ConsiderScreenBuffer // @@ -521,11 +462,11 @@ void Y_IntermissionDrawer(void) else if (rendermode != render_soft && usebuffer) HWR_DrawIntermissionBG(); #endif - else if (bgpatch) + else if (VoteScreen.bgpatch) { fixed_t hs = vid.width * FRACUNIT / BASEVIDWIDTH; fixed_t vs = vid.height * FRACUNIT / BASEVIDHEIGHT; - V_DrawStretchyFixedPatch(0, 0, hs, vs, V_NOSCALEPATCH, bgpatch, NULL); + V_DrawStretchyFixedPatch(0, 0, hs, vs, V_NOSCALEPATCH, VoteScreen.bgpatch, NULL); } } else if (bgtile) @@ -1086,7 +1027,8 @@ void Y_EndIntermission(void) K_RetireBots(); } - Y_UnloadData(); + if (!dedicated) + Y_UnloadData(); endtic = -1; sorttic = -1; @@ -1105,7 +1047,7 @@ static void Y_FollowIntermission(void) G_AfterIntermission(); } -#define UNLOAD(x) if (x) {Patch_Free(x);} x = NULL; +#define UNLOAD(x) {if ((x) != NULL) {Patch_Free(x);} x = NULL;} #define CLEANUP(x) x = NULL; // @@ -1113,21 +1055,65 @@ static void Y_FollowIntermission(void) // static void Y_UnloadData(void) { - // In hardware mode, don't Z_ChangeTag a pointer returned by W_CachePatchName(). - // It doesn't work and is unnecessary. - if (rendermode != render_soft) - return; - // unload the background patches - UNLOAD(bgpatch); - UNLOAD(widebgpatch); + UNLOAD(VoteScreen.bgpatch); + UNLOAD(VoteScreen.widebgpatch); UNLOAD(bgtile); UNLOAD(interpic); } // SRB2Kart: Voting! -static void Y_DrawVoteBackground(patch_t *patch) +// +// Y_VoteScreenCheck +// +static void Y_VoteScreenCheck(void) +{ + strcpy(VoteScreen.Prefix, "INTS"); + + if (VoteScreen.luaPrefix[0] != 0) + strlcpy(VoteScreen.Prefix, VoteScreen.luaPrefix, sizeof(VoteScreen.Prefix)); + else if (gametype == GT_BATTLE) + strcpy(VoteScreen.Prefix, "BTLS"); + + VoteScreen.foundLuaVoteFrames = VoteScreen.foundLuaVoteWideFrames = 0; + VoteScreen.currentAnimFrame = 0; + + INT32 i = 1; + + // check for lua vote background replacements + for (;;) + { + // Check if the lumps exist (checking for VEXTR(N|W)xx for race and VEXTRB(N|W)xx for battle) + boolean normalLumpExists = W_LumpExists(va("%sC%d", VoteScreen.Prefix, i)); + boolean wideLumpExists = W_LumpExists(va("%sW%d", VoteScreen.Prefix, i)); + + if (normalLumpExists || wideLumpExists) + { + if (normalLumpExists) + VoteScreen.foundLuaVoteFrames++; + + if (wideLumpExists) + VoteScreen.foundLuaVoteWideFrames++; + } + else // If we don't find at least frame 1 (e.g VEXTRN1), let's just stop looking + break; + + i++; + } + + // non lua vote background handling + boolean prefbattletype = ((votelevels[0][1] & ~0x80) == GT_BATTLE); + VoteScreen.widebgpatch = W_CachePatchName((prefbattletype ? "BATTLSCW" : "INTERSCW"), PU_PATCH); + VoteScreen.bgpatch = W_CachePatchName((prefbattletype ? "BATTLSCR" : "INTERSCR"), PU_PATCH); +} + +// +// Y_VoteBackgroundDrawer +// +// Determines which patch drawer to use for scaling +// +static void Y_VoteBackgroundDrawer(patch_t *patch) { switch (cv_votebgscaling.value) { @@ -1149,31 +1135,75 @@ static void Y_DrawVoteBackground(patch_t *patch) } } -// Y_DrawAnimatedVoteScreenPatch // -// Draw animated patch based on frame counter on vote screen +// Y_DrawLuaVoteScreenPatch // -static void Y_DrawAnimatedVoteScreenPatch(boolean widePatch) +// Handles votebackgrounds set by "setVoteBackground" +// Aswell as animated patches +// +static void Y_DrawLuaVoteScreenPatch(boolean widePatch) { INT32 nextframe = 0; patch_t *votebg = NULL; - char tempAnimPrefix[7]; - const INT32 tempFoundAnimVoteFrames = ((widePatch ? foundAnimVoteWideFrames : foundAnimVoteFrames) - 1); + char tempPrefix[6]; + const INT32 tempfoundAnimLuaVoteFrames = ((widePatch ? VoteScreen.foundLuaVoteWideFrames : VoteScreen.foundLuaVoteFrames) - 1); - strcpy(tempAnimPrefix, (widePatch ? animWidePrefix : animPrefix)); + strcpy(tempPrefix, va("%s%s", VoteScreen.Prefix, (widePatch ? "W" : "C"))); + + // Draw non animated patch + if (!tempfoundAnimLuaVoteFrames) + { + votebg = W_CachePatchName(va("%s1", tempPrefix), PU_PATCH); + Y_VoteBackgroundDrawer(votebg); + return; + } + + // Draw animated patch based on frame counter on vote screen // Just in case someone provides LESS widescreen frames than normal frames or vice versa, reset the frame counter to 0 - if (currentAnimFrame > tempFoundAnimVoteFrames) - currentAnimFrame = 0; + if (VoteScreen.currentAnimFrame > tempfoundAnimLuaVoteFrames) + VoteScreen.currentAnimFrame = 0; - nextframe = (currentAnimFrame + 1); + nextframe = (VoteScreen.currentAnimFrame + 1); - votebg = W_CachePatchName(va("%s%d", (widePatch ? animWidePrefix : animPrefix), nextframe), PU_PATCH); + votebg = W_CachePatchName(va("%s%d", tempPrefix, nextframe), PU_PATCH); - Y_DrawVoteBackground(votebg); + Y_VoteBackgroundDrawer(votebg); if (renderisnewtic && (votetic % 2 == 0) && !paused) - currentAnimFrame = (nextframe > tempFoundAnimVoteFrames) ? 0 : nextframe; + VoteScreen.currentAnimFrame = (nextframe > tempfoundAnimLuaVoteFrames) ? 0 : nextframe; +} + +// +// Y_DrawVoteScreenPatch +// + +static void Y_DrawVoteScreenPatch(void) +{ + patch_t *votebg = NULL; + const boolean widescreen = (vid.width / vid.dupx > 320); + + if (VoteScreen.foundLuaVoteWideFrames || VoteScreen.foundLuaVoteFrames) + { + Y_DrawLuaVoteScreenPatch(((widescreen && VoteScreen.foundLuaVoteWideFrames) || !VoteScreen.foundLuaVoteFrames)); + return; + } + + // non widescreen patch + votebg = VoteScreen.bgpatch; + + UINT8 prefgametype = (votelevels[0][1] & ~0x80); + const boolean widebgreplaced = (prefgametype == GT_BATTLE) ? VoteScreen.replaced.widebattle : VoteScreen.replaced.widerace; + const boolean bgreplaced = (prefgametype == GT_BATTLE) ? VoteScreen.replaced.battle : VoteScreen.replaced.race; + + // we check a bunch of stuff to always have a "valid" fallback + if ((widescreen && (widebgreplaced || !bgreplaced)) + || (!widescreen && (widebgreplaced && !bgreplaced))) + { + votebg = VoteScreen.widebgpatch; // widescreen patch + } + + Y_VoteBackgroundDrawer(votebg); } static fixed_t Y_CalculatePicScale(fixed_t picscale, INT32 hypoti) @@ -1192,32 +1222,6 @@ static fixed_t Y_CalculatePicScale(fixed_t picscale, INT32 hypoti) return picscale; } -static void Y_DrawVoteScreenPatch(void) -{ - patch_t *votebg = NULL; - const boolean widescreen = (vid.width / vid.dupx > 320); - - if (foundAnimVoteWideFrames || foundAnimVoteFrames) - { - Y_DrawAnimatedVoteScreenPatch((foundAnimVoteWideFrames && widescreen)); - return; - } - - votebg = bgpatch; // non widescreen patch - - UINT8 prefgametype = (votelevels[0][1] & ~0x80); - const boolean widebgreplaced = (prefgametype == GT_BATTLE) ? widebattlereplaced : wideracereplaced; - const boolean bgreplaced = (prefgametype == GT_BATTLE) ? battlereplaced : racereplaced; - - if ((widescreen && (widebgreplaced || !bgreplaced)) - || (!widescreen && (widebgreplaced && !bgreplaced))) - { - votebg = widebgpatch; - } - - Y_DrawVoteBackground(votebg); -} - // // Y_VoteDrawer // @@ -1351,7 +1355,7 @@ void Y_VoteDrawer(void) if (!splitscreen) { - thiscurs = cursor; + thiscurs = VoteScreen.cursor[0]; p = consoleplayer; color = levelinfo[i].gtc; colormap = NULL; @@ -1361,19 +1365,19 @@ void Y_VoteDrawer(void) switch (j) { case 1: - thiscurs = cursor2; + thiscurs = VoteScreen.cursor[2]; p = g_localplayers[1]; break; case 2: - thiscurs = cursor3; + thiscurs = VoteScreen.cursor[3]; p = g_localplayers[2]; break; case 3: - thiscurs = cursor4; + thiscurs = VoteScreen.cursor[4]; p = g_localplayers[3]; break; default: - thiscurs = cursor1; + thiscurs = VoteScreen.cursor[1]; p = g_localplayers[0]; break; } @@ -1401,7 +1405,7 @@ void Y_VoteDrawer(void) else { V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<width, scale))< 1) ? (cv_votemaxrows.value - 1) : 0); - boolean battlemode = ((votelevels[0][1] & ~VOTEMODIFIER_ENCORE) == GT_BATTLE); // todo gametyperules votemax = cv_votemaxrows.value; // can we please avoid SIGSEGVs voterowmem = cv_votemaxrows.value; // this is just for the notif system @@ -1868,16 +1889,8 @@ void Y_StartVote(void) I_Error("voteendtic is dirty"); #endif - Y_AnimatedVoteScreenCheck(); - - widebgpatch = W_CachePatchName((battlemode ? "BATTLSCW" : "INTERSCW"), PU_STATIC); - bgpatch = W_CachePatchName((battlemode ? "BATTLSCR" : "INTERSCR"), PU_STATIC); - cursor = W_CachePatchName("M_CURSOR", PU_STATIC); - cursor1 = W_CachePatchName("P1CURSOR", PU_STATIC); - cursor2 = W_CachePatchName("P2CURSOR", PU_STATIC); - cursor3 = W_CachePatchName("P3CURSOR", PU_STATIC); - cursor4 = W_CachePatchName("P4CURSOR", PU_STATIC); - rubyicon = W_CachePatchName("RUBYICON", PU_STATIC); + // cache vote patches + Y_InitVoteDrawing(); timer = cv_votetime.value*TICRATE; pickedvote = -1; @@ -1966,17 +1979,17 @@ static void Y_UnloadVoteData(void) { voteclient.loaded = false; - if (rendermode != render_soft) + if (dedicated) return; - UNLOAD(widebgpatch); - UNLOAD(bgpatch); - UNLOAD(cursor); - UNLOAD(cursor1); - UNLOAD(cursor2); - UNLOAD(cursor3); - UNLOAD(cursor4); - UNLOAD(rubyicon); + UNLOAD(VoteScreen.widebgpatch); + UNLOAD(VoteScreen.bgpatch); + UNLOAD(VoteScreen.cursor[0]); + UNLOAD(VoteScreen.cursor[1]); + UNLOAD(VoteScreen.cursor[2]); + UNLOAD(VoteScreen.cursor[3]); + UNLOAD(VoteScreen.cursor[4]); + UNLOAD(VoteScreen.rubyicon); } // diff --git a/src/y_inter.h b/src/y_inter.h index 3ad092744..aebf75d45 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -17,7 +17,6 @@ extern "C" { #endif extern boolean usebuffer; -extern char *luaVoteScreen; void Y_IntermissionDrawer(void); void Y_Ticker(void); @@ -47,6 +46,39 @@ typedef enum extern intertype_t intertype; extern intertype_t intermissiontypes[NUMGAMETYPES]; +// Votescreen stuff +typedef struct +{ + boolean race; // non lua race patch replaced + boolean widerace; // non lua widescreen race patch replaced + boolean battle; // non lua battle patch replaced + boolean widebattle; // non lua widescreen battle patch replaced +} votereplace_t; + +// VEXTRN - Vote (V) Extra (EXT) Race (R) Normal (N - Normal sized patch) +// VEXTRW - Vote (V) Extra (EXT) Race (R) Normal (W - Wide patch) +// VEXTBN - Vote (V) Extra (EXT) Battle (B) Normal (N - Normal sized patch) +// VEXTBW - Vote (V) Extra (EXT) Battle (B) Normal (W - Wide patch) +typedef struct +{ + char Prefix[5]; // Race = INTSX, Battle = BTLSX + char luaPrefix[5]; // prefix for lua votescreens + + INT32 currentAnimFrame; // current animated background frame + + INT32 foundLuaVoteFrames; // normal lua patch frames + INT32 foundLuaVoteWideFrames; // widescreen lua patch frames + + votereplace_t replaced; // checks which non lua patch has been replaced + + patch_t *bgpatch; // votebackground patch + patch_t *widebgpatch; // wide votebackground patch + + patch_t *cursor[5]; // cursor patches + patch_t *rubyicon; // encore ruby patch +} votescreen_t; +extern votescreen_t VoteScreen; + #ifdef __cplusplus } // extern "C" #endif