Merge branch 'ping-stuff-take2' into 'next'

Ping improvements

See merge request KartKrew/Kart-Public!68
This commit is contained in:
Sal 2019-02-22 19:13:49 -05:00
commit 5e9a11d467
18 changed files with 199 additions and 56 deletions

View file

@ -93,6 +93,7 @@ static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the
UINT16 pingmeasurecount = 1;
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
tic_t servermaxping = 800; // server's max ping. Defaults to 800
#endif
SINT8 nodetoplayer[MAXNETNODES];
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen)
@ -4403,6 +4404,8 @@ FILESTAMP
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
servermaxping = (tic_t)netbuffer->u.pingtable[i++];
}
break;
@ -5045,6 +5048,18 @@ void TryRunTics(tic_t realtics)
}
#ifdef NEWPING
/* Ping Update except better:
We call this once per second and check for people's pings. If their ping happens to be too high, we increment some timer and kick them out.
If they're not lagging, decrement the timer by 1. Of course, reset all of this if they leave.
Why do we do that? Well, I'm a person with unfortunately sometimes unstable internet and happen to keep getting kicked very unconveniently for very short high spikes. (700+ ms)
Because my spikes are so high, the average ping is exponentially higher too (700s really add up...!) which leads me to getting kicked for a short burst of spiking.
With this change here, this doesn't happen anymore as it checks if my ping has been CONSISTENTLY bad for long enough before killing me.
*/
static INT32 pingtimeout[MAXPLAYERS];
static inline void PingUpdate(void)
{
INT32 i;
@ -5065,6 +5080,9 @@ static inline void PingUpdate(void)
laggers[i] = true;
numlaggers++;
}
else
pingtimeout[i] = 0;
}
//kick lagging players... unless everyone but the server's ping sucks.
@ -5075,6 +5093,10 @@ static inline void PingUpdate(void)
{
if (playeringame[i] && laggers[i])
{
pingtimeout[i]++;
if (pingtimeout[i] > cv_pingtimeout.value) // ok your net has been bad for too long, you deserve to die.
{
pingtimeout[i] = 0;
XBOXSTATIC char buf[2];
buf[0] = (char)i;
@ -5082,6 +5104,9 @@ static inline void PingUpdate(void)
SendNetXCmd(XD_KICK, &buf, 2);
}
}
else // you aren't lagging, but you aren't free yet. In case you'll keep spiking, we just make the timer go back down. (Very unstable net must still get kicked).
pingtimeout[i] = (pingtimeout[i] == 0 ? 0 : pingtimeout[i]-1);
}
}
}
@ -5095,10 +5120,13 @@ static inline void PingUpdate(void)
realpingtable[i] = 0; //Reset each as we go.
}
// send the server's maxping as last element of our ping table. This is useful to let us know when we're about to get kicked.
netbuffer->u.pingtable[i++] = cv_maxping.value;
//send out our ping packets
for (i = 0; i < MAXNETNODES; i++)
if (nodeingame[i])
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1));
pingmeasurecount = 1; //Reset count
}
@ -5112,7 +5140,7 @@ static void UpdatePingTable(void)
INT32 i;
if (server)
{
if (netgame && !(gametime % 255))
if (netgame && !(gametime % 35)) // update once per second.
PingUpdate();
// update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++)

View file

@ -521,6 +521,7 @@ extern tic_t jointimeout;
extern UINT16 pingmeasurecount;
extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
#endif
extern consvar_t

View file

@ -435,6 +435,14 @@ consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_co
#ifdef NEWPING
static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}};
consvar_t cv_maxping = {"maxping", "800", CV_SAVE, maxping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t pingtimeout_cons_t[] = {{8, "MIN"}, {120, "MAX"}, {0, NULL}};
consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// show your ping on the HUD next to framerate. Defaults to warning only (shows up if your ping is > maxping)
static CV_PossibleValue_t showping_cons_t[] = {{0, "Off"}, {1, "Always"}, {2, "Warning"}, {0, NULL}};
consvar_t cv_showping = {"showping", "Warning", CV_SAVE, showping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
// Intermission time Tails 04-19-2002
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
@ -664,6 +672,8 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_sleep);
#ifdef NEWPING
CV_RegisterVar(&cv_maxping);
CV_RegisterVar(&cv_pingtimeout);
CV_RegisterVar(&cv_showping);
#endif
#ifdef SEENAMES

View file

@ -145,6 +145,8 @@ extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionb
#ifdef NEWPING
extern consvar_t cv_maxping;
extern consvar_t cv_pingtimeout;
extern consvar_t cv_showping;
#endif
extern consvar_t cv_skipmapcheck;

View file

@ -94,6 +94,9 @@ void I_FinishUpdate (void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
//blast it to the screen
// this code sucks
//memcpy(dascreen,screens[0],screenwidth*screenheight);

View file

@ -74,6 +74,14 @@ patch_t *nightsnum[10]; // 0-9
patch_t *lt_font[LT_FONTSIZE];
patch_t *cred_font[CRED_FONTSIZE];
// ping font
// Note: I'd like to adress that at this point we might *REALLY* want to work towards a common drawString function that can take any font we want because this is really turning into a MESS. :V -Lat'
patch_t *pingnum[10];
patch_t *pinggfx[5]; // small ping graphic
patch_t *framecounter;
patch_t *frameslash; // framerate stuff. Used in screen.c
static player_t *plr;
boolean chat_on; // entering a chat message?
static char w_chat[HU_MAXMSGLEN];
@ -263,6 +271,8 @@ void HU_LoadGraphics(void)
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "NGTNUM%d", i);
nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "PINGN%d", i);
pingnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
}
// minus for negative tallnums
@ -295,6 +305,17 @@ void HU_LoadGraphics(void)
tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX);
songcreditbg = W_CachePatchName("K_SONGCR", PU_HUDGFX);
// cache ping gfx:
for (i = 0; i < 5; i++)
{
sprintf(buffer, "PINGGFX%d", i+1);
pinggfx[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// fps stuff
framecounter = W_CachePatchName("FRAMER", PU_HUDGFX);
frameslash = W_CachePatchName("FRAMESL", PU_HUDGFX);;
}
// Initialise Heads up
@ -1612,9 +1633,9 @@ static void HU_drawChatLog(INT32 offset)
// draw arrows to indicate that we can (or not) scroll.
if (chat_scroll > 0)
V_DrawThinString(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight, "\x1A"); // up arrow
V_DrawCharacter(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1A', false); // up arrow
if (chat_scroll < chat_maxscroll)
V_DrawThinString(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight, "\x1B"); // down arrow
V_DrawCharacter(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1B', false); // down arrow
justscrolleddown = false;
justscrolledup = false;
@ -2178,6 +2199,7 @@ static void HU_DrawSongCredits(void)
V_DrawRightAlignedThinString(cursongcredit.x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
}
// Heads up displays drawer, call each frame
//
void HU_Drawer(void)
@ -2369,36 +2391,25 @@ void HU_Erase(void)
//
// HU_drawPing
//
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags)
{
UINT8 numbars = 1; // how many ping bars do we draw?
UINT8 barcolor = 128; // color we use for the bars (green, yellow or red)
SINT8 i = 0;
SINT8 yoffset = 6;
INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2);
INT32 gfxnum = 4; // gfx to draw
UINT8 const *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SALMON, GTC_CACHE);
if (ping < 128)
{
numbars = 3;
barcolor = 184;
}
if (ping < 76)
gfxnum = 0;
else if (ping < 137)
gfxnum = 1;
else if (ping < 256)
{
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103;
}
gfxnum = 2;
else if (ping < 500)
gfxnum = 3;
if (!notext || vid.width >= 640) // how sad, we're using a shit resolution.
V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping));
for (i=0; (i<3); i++) // Draw the ping bar
{
V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31);
if (i < numbars)
V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor);
yoffset -= 2;
}
V_DrawScaledPatch(x, y, flags, pinggfx[gfxnum]);
if (servermaxping && ping > servermaxping && hu_tick < 4) // flash ping red if too high
V_DrawPingNum(x, y+9, flags, ping, colormap);
else
V_DrawPingNum(x, y+9, flags, ping, NULL);
}
//

View file

@ -80,7 +80,11 @@ extern boolean chat_on;
extern patch_t *hu_font[HU_FONTSIZE], *kart_font[KART_FONTSIZE], *tny_font[HU_FONTSIZE]; // SRB2kart
extern patch_t *tallnum[10];
extern patch_t *pingnum[10];
extern patch_t *pinggfx[5];
extern patch_t *nightsnum[10];
extern patch_t *framecounter;
extern patch_t *frameslash;
extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *emeraldpics[7];
@ -109,7 +113,7 @@ void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);
void HU_clearChatChars(void);
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard.
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags); // Lat': Ping drawer for scoreboard.
//void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
//void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);

View file

@ -4695,6 +4695,7 @@ static void K_KartDrift(player_t *player, boolean onground)
player->kartstuff[k_driftend] = 0;
}
// Incease/decrease the drift value to continue drifting in that direction
if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_jmp] == 1 && onground && player->kartstuff[k_drift] != 0)
{
@ -7184,7 +7185,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
if (netgame // don't draw it offline
&& tab[i].num != serverplayer)
HU_drawPing(x + ((i < 8) ? -19 : rightoffset + 13), y+2, playerpingtable[tab[i].num], false);
HU_drawPing(x + ((i < 8) ? -17 : rightoffset + 11), y-4, playerpingtable[tab[i].num], 0);
STRBUFCPY(strtime, tab[i].name);

View file

@ -410,6 +410,24 @@ static int libd_drawPaddedNum(lua_State *L)
return 0;
}
static int libd_drawPingNum(lua_State *L)
{
INT32 x, y, flags, num;
const UINT8 *colormap = NULL;
HUDONLY
x = luaL_checkinteger(L, 1);
y = luaL_checkinteger(L, 2);
num = luaL_checkinteger(L, 3);
flags = luaL_optinteger(L, 4, 0);
flags &= ~V_PARAMMASK; // Don't let crashes happen.
if (!lua_isnoneornil(L, 5))
colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP));
V_DrawPingNum(x, y, flags, num, colormap);
return 0;
}
static int libd_drawFill(lua_State *L)
{
INT32 x = luaL_optinteger(L, 1, 0);
@ -613,6 +631,7 @@ static luaL_Reg lib_draw[] = {
{"drawScaled", libd_drawScaled},
{"drawNum", libd_drawNum},
{"drawPaddedNum", libd_drawPaddedNum},
{"drawPingNum", libd_drawPingNum},
{"drawFill", libd_drawFill},
{"fadeScreen", libd_fadeScreen},
{"drawString", libd_drawString},

View file

@ -1390,7 +1390,7 @@ static menuitem_t OP_HUDOptionsMenu[] =
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
NULL, "HUD Visibility", &cv_translucenthud, 20},
{IT_STRING | IT_SUBMENU, NULL, "Online chat options...",&OP_ChatOptionsDef, 35},
{IT_STRING | IT_SUBMENU, NULL, "Online HUD options...",&OP_ChatOptionsDef, 35},
{IT_STRING | IT_CVAR, NULL, "Background Glass", &cons_backcolor, 45},
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
@ -1404,6 +1404,7 @@ static menuitem_t OP_HUDOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 120},
};
// Ok it's still called chatoptions but we'll put ping display in here to be clean
static menuitem_t OP_ChatOptionsMenu[] =
{
// will ANYONE who doesn't know how to use the console want to touch this one?
@ -1417,6 +1418,8 @@ static menuitem_t OP_ChatOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 50},
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 60},
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 70},
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 90}, // shows ping next to framerate if we want to.
};
static menuitem_t OP_GameOptionsMenu[] =
@ -1469,15 +1472,16 @@ static menuitem_t OP_AdvServerOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 40},
{IT_STRING | IT_CVAR, NULL, "Ping limit (ms)", &cv_maxping, 50},
{IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", &cv_nettimeout, 60},
{IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", &cv_jointimeout, 70},
{IT_STRING | IT_CVAR, NULL, "Ping timeout (s)", &cv_pingtimeout, 60},
{IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", &cv_nettimeout, 70},
{IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", &cv_jointimeout, 80},
{IT_STRING | IT_CVAR, NULL, "Max. file transfer send (KB)", &cv_maxsend, 90},
{IT_STRING | IT_CVAR, NULL, "File transfer packet rate", &cv_downloadspeed, 100},
{IT_STRING | IT_CVAR, NULL, "Max. file transfer send (KB)", &cv_maxsend, 100},
{IT_STRING | IT_CVAR, NULL, "File transfer packet rate", &cv_downloadspeed, 110},
{IT_STRING | IT_CVAR, NULL, "Log join addresses", &cv_showjoinaddress, 120},
{IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 130},
{IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 140},
{IT_STRING | IT_CVAR, NULL, "Log join addresses", &cv_showjoinaddress, 130},
{IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 140},
{IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 150},
};
#endif

View file

@ -403,7 +403,7 @@ void SCR_DisplayTicRate(void)
tic_t i;
tic_t ontic = I_GetTime();
tic_t totaltics = 0;
INT32 ticcntcolor = 0;
const UINT8 *ticcntcolor = NULL;
for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i)
fpsgraph[i % TICRATE] = false;
@ -414,13 +414,36 @@ void SCR_DisplayTicRate(void)
if (fpsgraph[i])
++totaltics;
if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP;
else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP;
if (totaltics <= TICRATE/2) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SALMON, GTC_CACHE);
else if (totaltics == TICRATE) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE);
V_DrawString(vid.width-(24*vid.dupx), vid.height-(16*vid.dupy),
/*V_DrawString(vid.width-(24*vid.dupx), vid.height-(16*vid.dupy),
V_YELLOWMAP|V_NOSCALESTART, "FPS");
V_DrawString(vid.width-(40*vid.dupx), vid.height-( 8*vid.dupy),
ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));
ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));*/
// draw "FPS"
V_DrawFixedPatch(306<<FRACBITS, 183<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, framecounter, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE));
// draw total frame:
V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, TICRATE, ticcntcolor);
// draw "/"
V_DrawFixedPatch(306<<FRACBITS, 190<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, frameslash, ticcntcolor);
// draw our actual framerate
V_DrawPingNum(306, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, totaltics, ticcntcolor);
lasttic = ontic;
}
// SCR_DisplayLocalPing
// Used to draw the user's local ping next to the framerate for a quick check without having to hold TAB for instance. By default, it only shows up if your ping is too high and risks getting you kicked.
void SCR_DisplayLocalPing(void)
{
UINT32 ping = playerpingtable[consoleplayer]; // consoleplayer's ping is everyone's ping in a splitnetgame :P
if (cv_showping.value == 1 || (cv_showping.value == 2 && ping > servermaxping)) // only show 2 (warning) if our ping is at a bad level
{
INT32 dispy = cv_ticrate.value ? 160 : 181;
HU_drawPing(307, dispy, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM);
}
}

View file

@ -180,5 +180,6 @@ FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
// move out to main code for consistency
void SCR_DisplayTicRate(void);
void SCR_DisplayLocalPing(void);
#undef DNWH
#endif //__SCREEN_H__

View file

@ -1361,6 +1361,9 @@ void I_FinishUpdate(void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
if (rendermode == render_soft && screens[0])
{
SDL_Rect rect;

View file

@ -1343,6 +1343,9 @@ void I_FinishUpdate(void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
if (render_soft == rendermode && screens[0])
{
SDL_Rect *dstrect = NULL;

View file

@ -1342,8 +1342,8 @@ void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed)
V_DrawScaledPatch(x, y, flags, hu_font[c]);
}
// Writes a single character for the chat. (draw WHITE if bit 7 set)
// Essentially the same as the above but it's small or big depending on what resolution you've chosen to huge..
// Writes a single character for the chat (half scaled). (draw WHITE if bit 7 set)
// 16/02/19: Scratch the scaling thing, chat doesn't work anymore under 2x res -Lat'
//
void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap)
{
@ -1359,13 +1359,11 @@ void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UI
if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
return;
w = (vid.width < 640 ) ? (SHORT(hu_font[c]->width)/2) : (SHORT(hu_font[c]->width)); // use normal sized characters if we're using a terribly low resolution.
w = SHORT(hu_font[c]->width)/2;
if (x + w > vid.width)
return;
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, (vid.width < 640) ? (FRACUNIT) : (FRACUNIT/2), flags, hu_font[c], colormap);
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/2, flags, hu_font[c], colormap);
}
// Precompile a wordwrapped string to any given width.
@ -2015,6 +2013,28 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits)
} while (--digits);
}
// Draws a number using the PING font thingy.
// TODO: Merge number drawing functions into one with "font name" selection.
void V_DrawPingNum(INT32 x, INT32 y, INT32 flags, INT32 num, const UINT8 *colormap)
{
INT32 w = SHORT(pingnum[0]->width); // this SHOULD always be 5 but I guess custom graphics exist.
if (flags & V_NOSCALESTART)
w *= vid.dupx;
if (num < 0)
num = -num;
// draw the number
do
{
x -= (w-1); // Oni wanted their outline to intersect.
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, flags, pingnum[num%10], colormap);
num /= 10;
} while (num);
}
// Write a string using the credit font
// NOTE: the text is centered for screens larger than the base width
//

View file

@ -190,6 +190,10 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num);
void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits);
// Draw ping numbers. Used by the scoreboard and that one ping option. :P
// This is a separate function because IMO lua should have access to it as well.
void V_DrawPingNum(INT32 x, INT32 y, INT32 flags, INT32 num, const UINT8 *colormap);
// Find string width from lt_font chars
INT32 V_LevelNameWidth(const char *string);
INT32 V_LevelNameHeight(const char *string);

View file

@ -366,6 +366,9 @@ void I_FinishUpdate(void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
//
if (bDIBMode)
{

View file

@ -198,6 +198,9 @@ void I_FinishUpdate(void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
//
if (bDIBMode)
{