Merge pull request '[FEAT] High Player Count Support' (#169) from 32p into blankart-dev

Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/169
This commit is contained in:
NepDisk 2025-10-18 21:11:21 +02:00
commit 5ef24abba4
12 changed files with 177 additions and 94 deletions

View file

@ -85,6 +85,8 @@
#define MAX_REASONLENGTH 30
#define FORCECLOSE 0x8000
I_StaticAssert(sizeof(doomdata_t) < MAXPACKETLENGTH); // can't send a packet larger than the max packet length!
boolean server = true; // true or false but !server == client
#define client (!server)
boolean nodownload = false;
@ -93,7 +95,7 @@ INT32 serverplayer = 0;
char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support)
UINT8 playerconsole[MAXPLAYERS];
plrinfo playerinfo[MAXPLAYERS];
plrinfo playerinfo[MAXPLAYERINFO];
// Server specific vars
UINT8 playernode[MAXPLAYERS];
@ -1067,7 +1069,7 @@ static void SV_SendPlayerInfo(INT32 node)
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
netbuffer->packettype = PT_PLAYERINFO;
for (i = 0; i < MSCOMPAT_MAXPLAYERS; i++)
for (i = 0; i < MAXPLAYERINFO; i++)
{
if (i >= MAXPLAYERS || playernode[i] == UINT8_MAX || !playeringame[i])
{
@ -1081,10 +1083,6 @@ static void SV_SendPlayerInfo(INT32 node)
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
//fetch IP address
//No, don't do that, you fuckface.
memset(netbuffer->u.playerinfo[i].address, 0, 4);
if (G_GametypeHasTeams())
{
if (!players[i].ctfteam)
@ -1108,7 +1106,7 @@ static void SV_SendPlayerInfo(INT32 node)
netbuffer->u.playerinfo[i].data = 0; //players[i].skincolor;
}
HSendPacket(node, false, 0, sizeof(plrinfo) * MSCOMPAT_MAXPLAYERS);
HSendPacket(node, false, 0, sizeof(plrinfo) * MAXPLAYERINFO);
}
/** Sends a PT_SERVERCFG packet
@ -4495,7 +4493,7 @@ static void HandlePlayerInfo(SINT8 node)
{
(void)node;
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
for (INT32 i = 0; i < MAXPLAYERS; i++)
for (INT32 i = 0; i < MAXPLAYERINFO; i++)
{
playerinfo[i] = netbuffer->u.playerinfo[i];
}

View file

@ -327,7 +327,6 @@ struct plrinfo
{
UINT8 num;
char name[MAXPLAYERNAME+1];
UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH
UINT8 team;
UINT16 skin;
UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused.
@ -335,17 +334,6 @@ struct plrinfo
UINT16 timeinserver; // In seconds.
} ATTRPACK;
// Shortest player information for join during intermission.
struct plrconfig
{
char name[MAXPLAYERNAME+1];
UINT16 skin;
UINT16 color;
UINT32 pflags;
UINT32 score;
UINT8 ctfteam;
} ATTRPACK;
struct filesneededconfig_pak
{
INT32 first;
@ -392,8 +380,7 @@ struct doomdata_t
serverinfoupdate_pak serverinfoupdate;
askinfo_pak askinfo;
msaskinfo_pak msaskinfo;
plrinfo playerinfo[MSCOMPAT_MAXPLAYERS];
plrconfig playerconfig[MAXPLAYERS];
plrinfo playerinfo[MAXPLAYERINFO];
INT32 filesneedednum;
filesneededconfig_pak filesneededcfg;
netinfo_pak netinfo;
@ -580,7 +567,7 @@ extern char motd[254], server_context[8];
extern UINT8 playernode[MAXPLAYERS];
/* consoleplayer of this player (splitscreen) */
extern UINT8 playerconsole[MAXPLAYERS];
extern plrinfo playerinfo[MAXPLAYERS];
extern plrinfo playerinfo[MAXPLAYERINFO];
extern SINT8 joinnode;
#define SERVMUS_1 "SRVMS1"

View file

@ -91,7 +91,7 @@ extern "C" {
// Special Hashing.
//#define NOFILEHASH
//#define NOVERIFYIWADS
#define NOVERIFYIWADS
// Uncheck this to compile debugging code
//#define RANGECHECK
@ -189,8 +189,7 @@ extern char logfilename[1024];
// The maximum number of players, multiplayer/networking.
// NOTE: it needs more than this to increase the number of players...
#define MAXPLAYERS 16
#define PLAYERSMASK (MAXPLAYERS-1)
#define MAXPLAYERS 32 // 32 + host slot
#define MAXPLAYERNAME 21
#define MAXSPLITSCREENPLAYERS 4 // Max number of players on a single computer
#define MAXGAMEPADS (MAXSPLITSCREENPLAYERS * 2) // Number of gamepads we'll be allowing
@ -202,12 +201,14 @@ extern char logfilename[1024];
#define MAXCOLORNAME 32
#define NUMCOLORFREESLOTS 32768
#define MAXGPPLAYERS 16 // max players in Grand Prix only
// surely nobody's gonna change the palette a second time :Clueless:
#define FADECOLOR 0 // 120
#define ENCOREFADECOLOR 209 // 122
// Master Server compatibility ONLY
#define MSCOMPAT_MAXPLAYERS (32)
// the highest number of playerinfo entries we can fit into a single packet
#define MAXPLAYERINFO 32
// State updates, number of tics / second.
// NOTE: used to setup the timer rate, see I_StartupTimer().

View file

@ -3079,9 +3079,13 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
// Just spawn there.
//return playerstarts[0];
if (doprints)
CONS_Alert(CONS_WARNING, M_GetText("Could not spawn at any Race starts!\n"));
return NULL;
//this section courtesy of fickle - v1.1 battle royale
// screw collision chex
return playerstarts[pos % numcoopstarts];
// if (doprints)
// CONS_Alert(CONS_WARNING, M_GetText("Could not spawn at any Race starts!\n"));
// return NULL;
}
if (modeattacking != ATTACKING_ITEMBREAK)

View file

@ -22,10 +22,10 @@
/// \def MAXPACKETLENGTH
/// For use in a LAN
#define MAXPACKETLENGTH 1450
#define MAXPACKETLENGTH 2048
/// \def INETPACKETLENGTH
/// For use on the internet
#define INETPACKETLENGTH 1024
#define INETPACKETLENGTH 1450
#define NO_BAN_TIME (time_t)(-1)

View file

@ -104,7 +104,7 @@ UINT8 K_GetGPPlayerCount(UINT8 humans)
// 3P -> 12 total
// 4P -> 16 total
return max(min(humans * 4, MAXPLAYERS), 8);
return max(min(humans * 4, MAXGPPLAYERS), 8);
}
/*--------------------------------------------------
@ -117,7 +117,7 @@ void K_InitGrandPrixBots(void)
const UINT16 defaultbotskin = K_BotDefaultSkin();
const UINT8 startingdifficulty = K_BotStartingDifficulty(grandprixinfo.gamespeed);
UINT8 difficultylevels[MAXPLAYERS];
UINT8 difficultylevels[MAXGPPLAYERS];
UINT8 playercount = 8;
UINT8 wantedbots = 0;
@ -128,13 +128,13 @@ void K_InitGrandPrixBots(void)
UINT16 usableskins, skincount = numskins;
UINT16 grabskins[MAXSKINS+1];
UINT16 botskinlist[MAXPLAYERS];
UINT16 botskinlist[MAXGPPLAYERS];
UINT16 botskinlistpos = 0;
UINT8 newplayernum = 0;
UINT16 i, j;
memset(competitors, MAXPLAYERS, sizeof (competitors));
memset(competitors, MAXGPPLAYERS, sizeof (competitors));
memset(botskinlist, defaultbotskin, sizeof (botskinlist));
// Init usable bot skins list
@ -144,7 +144,7 @@ void K_InitGrandPrixBots(void)
}
grabskins[usableskins] = MAXSKINS;
#if MAXPLAYERS != 16
#if MAXGPPLAYERS != 16
I_Error("GP bot difficulty levels need rebalanced for the new player count!\n");
#endif
@ -178,7 +178,7 @@ void K_InitGrandPrixBots(void)
{
if (playeringame[i])
{
if (players[i].bot == true)
if (players[i].bot == true || i > MAXGPPLAYERS)
{
// Remove existing bots.
CL_RemovePlayer(i, KR_LEAVE);
@ -298,7 +298,7 @@ static INT16 K_RivalScore(player_t *bot)
roundsleft = grandprixinfo.cup->numlevels - grandprixinfo.roundnum;
}
for (i = 0; i < MAXPLAYERS; i++)
for (i = 0; i < MAXGPPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
{
@ -335,7 +335,7 @@ void K_UpdateGrandPrixBots(void)
UINT16 newrivalscore = 0;
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
for (i = 0; i < MAXGPPLAYERS; i++)
{
if (!playeringame[i] || !players[i].bot)
{
@ -346,7 +346,7 @@ void K_UpdateGrandPrixBots(void)
}
// Find the rival.
for (i = 0; i < MAXPLAYERS; i++)
for (i = 0; i < MAXGPPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator || !players[i].bot)
{
@ -382,7 +382,7 @@ void K_UpdateGrandPrixBots(void)
}
// Find the bot with the best average of score & difficulty.
for (i = 0; i < MAXPLAYERS; i++)
for (i = 0; i < MAXGPPLAYERS; i++)
{
UINT16 ns = 0;
@ -440,7 +440,7 @@ static UINT8 K_BotExpectedStanding(player_t *bot)
UINT8 pos = 1;
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
for (i = 0; i < MAXGPPLAYERS; i++)
{
if (i == (bot - players))
{

View file

@ -2176,10 +2176,12 @@ static boolean K_drawKartPositionFaces(void)
else
{
INT32 pos = players[rankplayer[i]].position;
if (pos < 0 || pos > MAXPLAYERS)
pos = 0;
// Draws the little number over the face
V_DrawScaledPatch(FACE_X-5, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_facenum[pos]);
if (pos < 0 || pos > 16)
V_DrawPingNum(FACE_X+2, Y+10, V_HUDTRANS|V_SNAPTOLEFT, pos, NULL);
else
V_DrawScaledPatch(FACE_X-5, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_facenum[pos]);
}
Y -= 18;
@ -2378,7 +2380,10 @@ INT32 K_DrawNeoTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines
hightlightcolor = skincolors[players[tab[i].num].mo->color].chatcolor;
}
V_DrawScaledPatch(x-5, y+1, 0, kp_facenum[pos]);
if (pos < 0 || pos > 16)
V_DrawPingNum(x+2, y+1, 0, pos, NULL);
else
V_DrawScaledPatch(x-5, y+1, 0, kp_facenum[pos]);
x2 = netgame ? x + (BASEVIDWIDTH/20) : x;
y2 = y;

View file

@ -8790,7 +8790,7 @@ void MD_DrawViewServer(void)
if (playeramount > 0)
{
for (i = 0; i < MAXPLAYERS; i++)
for (i = 0; i < MAXPLAYERINFO; i++)
{
if (playerinfo[i].num < 255)
{

View file

@ -449,9 +449,9 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
actor->lastlook %= MAXPLAYERS;
stop = (actor->lastlook - 1) & PLAYERSMASK;
stop = (actor->lastlook - 1) % MAXPLAYERS;
for (; ; actor->lastlook = (actor->lastlook + 1) & PLAYERSMASK)
for (; ; actor->lastlook = (actor->lastlook + 1) % MAXPLAYERS)
{
// done looking
if (actor->lastlook == stop)

View file

@ -4296,9 +4296,9 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest)
// first time init, this allow minimum lastlook changes
if (actor->lastlook < 0)
actor->lastlook = P_RandomByte();
actor->lastlook &= PLAYERSMASK;
actor->lastlook %= MAXPLAYERS;
for( ; ; actor->lastlook = (actor->lastlook+1) & PLAYERSMASK)
for( ; ; actor->lastlook = (actor->lastlook+1) % MAXPLAYERS)
{
// save the first look so we stop next time.
if (stop < 0)
@ -12751,9 +12751,9 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
{
#if MAXPLAYERS > 32
You should think about modifying the deathmatch starts to take full advantage of this!
#endif
// #if MAXPLAYERS > 32
// You should think about modifying the deathmatch starts to take full advantage of this!
// #endif
if (mthing->type <= MAXPLAYERS) // Player starts
{
// save spots for respawning in network games
@ -12804,11 +12804,11 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
{
return true; // These are handled elsewhere.
}
else if (mthing->type > MAXPLAYERS && mthing->type <= 32) // be wary of playerstarts size! playerstarts[MAXPLAYERS]
{
CONS_Alert(CONS_WARNING, "Excess player start detected %d\n", mthing->type);
return true;
}
// else if (mthing->type > MAXPLAYERS && mthing->type <= 32) // be wary of playerstarts size! playerstarts[MAXPLAYERS]
// {
// CONS_Alert(CONS_WARNING, "Excess player start detected %d\n", mthing->type);
// return true;
// }
return false;
}

View file

@ -66,7 +66,6 @@ TYPEDEF (serverinfoupdate_pak);
TYPEDEF (askinfo_pak);
TYPEDEF (msaskinfo_pak);
TYPEDEF (plrinfo);
TYPEDEF (plrconfig);
TYPEDEF (filesneededconfig_pak);
TYPEDEF (doomdata_t);
TYPEDEF (serverelem_t);

View file

@ -459,6 +459,10 @@ void Y_IntermissionDrawer(void)
INT32 y = 41, gutter = ((data.numplayers > NUMFORNEWCOLUMN) ? 0 : (BASEVIDWIDTH/2));
INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2;
const char *timeheader;
boolean manyplayers16 = (data.numplayers > NUMFORNEWCOLUMN*2);
boolean manyplayers8 = (data.numplayers > NUMFORNEWCOLUMN);
int y2;
if (data.rankingsmode)
@ -492,7 +496,17 @@ void Y_IntermissionDrawer(void)
if (data.encore)
V_DrawCenteredString(-4 + x + BASEVIDWIDTH/2, 12-8, hilicol, "ENCORE MODE");
if (data.numplayers > NUMFORNEWCOLUMN)
if (manyplayers16)
{
V_DrawFill(x+101, 24, 1, 158, 0);
V_DrawFill(x+207, 24, 1, 158, 0);
V_DrawFill((x-3) - duptweak, 182, dupadjust-2, 1, 0);
V_DrawRightAlignedString(x+152, 24, hilicol, timeheader);
y = 37;
}
else if (manyplayers8)
{
V_DrawFill(x+156, 24, 1, 158, 0);
V_DrawFill((x-3) - duptweak, 182, dupadjust-2, 1, 0);
@ -502,11 +516,13 @@ void Y_IntermissionDrawer(void)
V_DrawRightAlignedString(x+152, 24, hilicol, timeheader);
}
V_DrawCenteredString(x+6, 24, hilicol, "#");
V_DrawString(x+36, 24, hilicol, "NAME");
V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+152, 24, hilicol, timeheader);
else
{
V_DrawCenteredString(x+6, 24, hilicol, "#");
V_DrawString(x+36, 24, hilicol, "NAME");
V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+152, 24, hilicol, timeheader);
}
for (i = 0; i < data.numplayers; i++)
{
@ -520,17 +536,29 @@ void Y_IntermissionDrawer(void)
if (dojitter)
y--;
V_DrawCenteredString(x+6, y, 0, va("%d", data.pos[i]));
if (manyplayers16)
V_DrawPingNum(x+6, y+2, 0, data.pos[i], NULL);
else
V_DrawCenteredString(x+6, y, 0, va("%d", data.pos[i]));
if (data.color[i])
{
UINT8 *colormap = R_GetTranslationColormap(*data.character[i], *data.color[i], GTC_CACHE);
patch_t *facerank = faceprefix[*data.character[i]][FACE_RANK];
V_DrawMappedPatch(x+16+facerank->leftoffset, y-4+facerank->topoffset, 0, facerank, colormap);
if (manyplayers16)
{
// fixed_t scale = K_UseHighResPortraits() ? FRACUNIT/4 : FRACUNIT/2;
fixed_t scale = FRACUNIT/2;
V_DrawFixedPatch((x+8)<<FRACBITS, (y+1)<<FRACBITS, scale, 0, facerank, colormap);
}
else
{
V_DrawMappedPatch(x+16+facerank->leftoffset, y-4+facerank->topoffset, 0, facerank, colormap);
}
}
if (data.num[i] == whiteplayer)
if (data.num[i] == whiteplayer && data.numplayers <= NUMFORNEWCOLUMN*2)
{
UINT8 cursorframe = (intertic / 4) % 8;
patch_t *highlight = W_CachePatchName(va("K_CHILI%d", cursorframe+1), PU_CACHE);
@ -540,14 +568,25 @@ void Y_IntermissionDrawer(void)
if ((players[data.num[i]].pflags & PF_NOCONTEST) && players[data.num[i]].bot)
{
// RETIRED!!
V_DrawScaledPatch(x+12, y-7, 0, W_CachePatchName("K_NOBLNS", PU_CACHE));
patch_t *retire = W_CachePatchName("K_NOBLNS", PU_CACHE);
if (manyplayers16)
{
fixed_t scale = FRACUNIT/2;
V_DrawFixedPatch(x+6, y-3, scale, 0, retire, NULL);
}
else
{
V_DrawScaledPatch(x+12, y-7, 0, retire);
}
}
STRBUFCPY(strtime, data.name[i]);
y2 = y;
if (data.numplayers > NUMFORNEWCOLUMN)
if (manyplayers16)
V_DrawThinString(x+18, y, hilicol|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
else if (manyplayers8)
V_DrawThinString(x+36, y2-1, ((data.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
else
V_DrawString(x+36, y2, ((data.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime);
@ -571,7 +610,9 @@ void Y_IntermissionDrawer(void)
else
snprintf(strtime, sizeof strtime, "(%d)", data.increase[data.num[i]]);
if (data.numplayers > NUMFORNEWCOLUMN)
if (manyplayers16)
V_DrawRightAlignedThinString(x+83+gutter, y, V_6WIDTHSPACE, strtime);
else if (manyplayers8)
V_DrawRightAlignedThinString(x+133+gutter, y-1, V_6WIDTHSPACE, strtime);
else
V_DrawRightAlignedString(x+118+gutter, y, 0, strtime);
@ -580,7 +621,9 @@ void Y_IntermissionDrawer(void)
snprintf(strtime, sizeof strtime, "%d", data.val[i]);
}
if (data.numplayers > NUMFORNEWCOLUMN)
if (manyplayers16)
V_DrawRightAlignedThinString(x+100+gutter, y, V_6WIDTHSPACE, strtime);
else if (manyplayers8)
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
else
V_DrawRightAlignedString(x+152+gutter, y, 0, strtime);
@ -588,7 +631,7 @@ void Y_IntermissionDrawer(void)
else
{
if (data.val[i] == (UINT32_MAX-1))
V_DrawRightAlignedThinString(x+152+gutter, y-1, (data.numplayers > NUMFORNEWCOLUMN ? V_6WIDTHSPACE : 0), "NO CONTEST.");
V_DrawRightAlignedThinString(x+(manyplayers16 ? 100 : 152)+gutter, y-1, (manyplayers8 ? V_6WIDTHSPACE : 0), "NO CONTEST.");
else
{
if (intertype == int_race || intertype == int_battletime)
@ -597,14 +640,18 @@ void Y_IntermissionDrawer(void)
G_TicsToSeconds(data.val[i]), G_TicsToCentiseconds(data.val[i]));
strtime[sizeof strtime - 1] = '\0';
if (data.numplayers > NUMFORNEWCOLUMN)
if (manyplayers16)
V_DrawRightAlignedThinString(x+100+gutter, y, V_6WIDTHSPACE, strtime);
else if (manyplayers8)
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
else
V_DrawRightAlignedString(x+152+gutter, y, 0, strtime);
}
else
{
if (data.numplayers > NUMFORNEWCOLUMN)
if (manyplayers16)
V_DrawRightAlignedThinString(x+100+gutter, y, V_6WIDTHSPACE, va("%i", data.val[i]));
else if (manyplayers8)
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, va("%i", data.val[i]));
else
V_DrawRightAlignedString(x+152+gutter, y, 0, va("%i", data.val[i]));
@ -618,13 +665,27 @@ void Y_IntermissionDrawer(void)
else
data.num[i] = MAXPLAYERS; // this should be the only field setting in this function
y += 18;
if (i == NUMFORNEWCOLUMN-1)
if (manyplayers16)
{
y = 41;
x += BASEVIDWIDTH/2;
y += 10;
if (i % 14 == 13)
{
y = 37;
x += BASEVIDWIDTH/3;
}
}
else
{
y += 18;
if (i == NUMFORNEWCOLUMN-1)
{
y = 41;
x += BASEVIDWIDTH/2;
}
}
#undef NUMFORNEWCOLUMN
}
}
@ -1172,7 +1233,7 @@ static fixed_t Y_CalculatePicScale(fixed_t picscale, INT32 hypoti)
//
void Y_VoteDrawer(void)
{
INT32 rowval, i, lvls, x, picdiff, y = 0, height = 0;
INT32 rowval, i, px, lvls, x, picdiff, y = 0, height = 0;
UINT8 selected[12];
fixed_t rubyheight = 0;
fixed_t scale;
@ -1186,6 +1247,9 @@ void Y_VoteDrawer(void)
fixed_t hypotf = 0;
INT32 hypoti = 0;
INT32 numplayers = 0;
boolean highplayers = false;
// get the hypotenuse
hypoti = (vidx*vidx) + (vidy*vidy);
hypotf = FixedSqrt(hypoti);
@ -1429,8 +1493,25 @@ void Y_VoteDrawer(void)
x = 20;
y = 10;
for (px = 0; px < MAXPLAYERS; px++)
{
if (playeringame[px])
{
numplayers++;
}
}
highplayers = numplayers > 16;
for (i = 0; i < MAXPLAYERS; i++)
{
INT32 bigaddx = 60; INT32 bigaddy = 30;
INT32 smalladdx = 42; INT32 smalladdy = 18;
INT32 smallfaceheight = 0; INT32 bigfaceheight = 9;
INT32 smallrectheight = 18; INT32 bigrectheight = 27;
INT32 smallrubyoffset = 4<<FRACBITS;
INT32 smallpicoffset = 4<<FRACBITS;
if (dedicated && i == 0) // While leaving blank spots for non-existent players is largely intentional, the first spot *always* being blank looks a tad silly :V
continue;
@ -1445,19 +1526,27 @@ void Y_VoteDrawer(void)
if (!timer && i == voteclient.ranim)
{
V_DrawScaledPatch(x-18, y+9, V_SNAPTOLEFT, VoteScreen.cursor[0]);
V_DrawScaledPatch(x-18, y+(highplayers ? 2 : bigfaceheight), V_SNAPTOLEFT, VoteScreen.cursor[0]);
if (voteendtic != -1 && !(votetic % 4))
V_DrawFill(x-1, y-1, 42, 27, 0|V_SNAPTOLEFT);
V_DrawFill(x-1, y-1, 42, (highplayers ? smallrectheight : bigrectheight), 0|V_SNAPTOLEFT);
else
V_DrawFill(x-1, y-1, 42, 27, levelinfo[votes[i]].gtc|V_SNAPTOLEFT);
V_DrawFill(x-1, y-1, 42, (highplayers ? smallrectheight : bigrectheight), levelinfo[votes[i]].gtc|V_SNAPTOLEFT);
}
if (highplayers)
{
V_SetClipRect(x<<FRACBITS, y<<FRACBITS, 48<<FRACBITS, 16<<FRACBITS, V_SNAPTOLEFT);
}
if (!levelinfo[votes[i]].encore)
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, V_SNAPTOLEFT, pic, NULL);
V_DrawFixedPatch(x<<FRACBITS, (y<<FRACBITS) - (highplayers ? smallpicoffset : 0), scale, V_SNAPTOLEFT, pic, NULL);
else
{
V_DrawFixedPatch((x+FixedMul(pic->width, scale))<<FRACBITS, y<<FRACBITS, scale, V_SNAPTOLEFT|V_FLIP, pic, NULL);
V_DrawFixedPatch((x+20)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, FRACUNIT/2, V_SNAPTOLEFT, VoteScreen.rubyicon, NULL);
V_DrawFixedPatch((x+FixedMul(pic->width, scale))<<FRACBITS, (y<<FRACBITS) - (highplayers ? smallpicoffset : 0), scale, V_SNAPTOLEFT|V_FLIP, pic, NULL);
V_DrawFixedPatch((x+20)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight - (highplayers ? smallrubyoffset : 0), FRACUNIT/2, V_SNAPTOLEFT, VoteScreen.rubyicon, NULL);
}
if (highplayers)
{
V_ClearClipRect();
}
if (levelinfo[votes[i]].gts)
@ -1471,22 +1560,22 @@ void Y_VoteDrawer(void)
UINT8 *colormap = R_GetTranslationColormap(players[i].skin, players[i].skincolor, GTC_CACHE);
patch_t *facerank = faceprefix[players[i].skin][FACE_RANK];
V_DrawMappedPatch(x+24+facerank->leftoffset, y+9+facerank->topoffset, V_SNAPTOLEFT, facerank, colormap);
V_DrawMappedPatch(x+24+facerank->leftoffset, y+(highplayers ? smallfaceheight : bigfaceheight)+facerank->topoffset, V_SNAPTOLEFT, facerank, colormap);
}
if (!splitscreen && i == consoleplayer)
{
UINT8 cursorframe = (votetic / 4) % 8;
patch_t *highlight = W_CachePatchName(va("K_CHILI%d", cursorframe+1), PU_CACHE);
V_DrawScaledPatch(x+24+highlight->leftoffset, y+9+highlight->topoffset, V_SNAPTOLEFT, highlight);
V_DrawScaledPatch(x+24+highlight->leftoffset, y+(highplayers ? smallfaceheight : bigfaceheight)+highlight->topoffset, V_SNAPTOLEFT, highlight);
}
}
y += 30;
y += highplayers ? smalladdy : bigaddy;
if (y > BASEVIDHEIGHT-40)
{
x += 60;
x += highplayers ? smalladdx : bigaddx;
y = 10;
}
}