This commit is contained in:
Sally Coolatta 2023-04-20 15:25:07 -04:00
parent 4b1de10627
commit 996ca9adad
19 changed files with 1663 additions and 55 deletions

View file

@ -142,6 +142,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
k_rank.c
k_vote.c
k_serverstats.c
k_zvote.c
)
if(SRB2_CONFIG_ENABLE_WEBM_MOVIES)

View file

@ -62,6 +62,7 @@
#include "g_party.h"
#include "k_vote.h"
#include "k_serverstats.h"
#include "k_zvote.h"
// cl loading screen
#include "v_video.h"
@ -2308,6 +2309,7 @@ static void CL_ConnectToServer(void)
Schedule_Clear();
Automate_Clear();
K_ClearClientPowerLevels();
K_ResetMidVote();
pnumnodes = 1;
oldtic = 0;
@ -3151,7 +3153,7 @@ static void Command_Kick(void)
if (COM_Argc() == 2)
{
WRITEUINT8(p, KICK_MSG_GO_AWAY);
WRITEUINT8(p, KICK_MSG_KICKED);
SendNetXCmd(XD_KICK, &buf, 2);
}
else
@ -3253,7 +3255,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
// to keep it all in one place.
if (server)
{
if (msg == KICK_MSG_GO_AWAY || msg == KICK_MSG_CUSTOM_KICK)
if (msg == KICK_MSG_KICKED || msg == KICK_MSG_CUSTOM_KICK)
{
// Kick as a temporary ban.
banMinutes = cv_kicktime.value;
@ -3293,7 +3295,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
switch (msg)
{
case KICK_MSG_GO_AWAY:
case KICK_MSG_KICKED:
HU_AddChatText(va("\x82*%s has been kicked (No reason given)", player_names[pnum]), false);
kickreason = KR_KICK;
break;
@ -3692,6 +3694,7 @@ void SV_ResetServer(void)
Automate_Clear();
K_ClearClientPowerLevels();
G_ObliterateParties();
K_ResetMidVote();
memset(splitscreen_invitations, -1, sizeof splitscreen_invitations);
memset(player_name_changes, 0, sizeof player_name_changes);
@ -3788,6 +3791,7 @@ void D_QuitNetGame(void)
Automate_Clear();
K_ClearClientPowerLevels();
G_ObliterateParties();
K_ResetMidVote();
DEBFILE("===========================================================================\n"
" Log finish\n"

View file

@ -458,15 +458,20 @@ extern consvar_t cv_playbackspeed;
#define FILETXHEADER offsetof(filetx_pak, data)
#define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0])
#define KICK_MSG_GO_AWAY 1
#define KICK_MSG_CON_FAIL 2
#define KICK_MSG_PLAYER_QUIT 3
#define KICK_MSG_TIMEOUT 4
#define KICK_MSG_BANNED 5
#define KICK_MSG_PING_HIGH 6
#define KICK_MSG_CUSTOM_KICK 7
#define KICK_MSG_CUSTOM_BAN 8
#define KICK_MSG_SIGFAIL 9
typedef enum
{
KICK_MSG_PLAYER_QUIT = 0, // Player intentionally left
KICK_MSG_KICKED, // Server kick message w/ no reason
KICK_MSG_CUSTOM_KICK, // Server kick message w/ reason
KICK_MSG_VOTE_KICK, // Vote kick message
KICK_MSG_BANNED, // Ban message w/ no reason
KICK_MSG_CUSTOM_BAN, // Ban message w/ custom reason
KICK_MSG_TIMEOUT, // Player's connection timed out
KICK_MSG_PING_HIGH, // Player hit the ping limit
KICK_MSG_CON_FAIL, // Player failed to resync game state
KICK_MSG_SIGFAIL, // Player failed signature check
KICK_MSG__MAX // Number of unique messages
} kickmsg_t;
typedef enum
{
@ -476,7 +481,6 @@ typedef enum
KR_TIMEOUT = 4, //Connection Timeout
KR_BAN = 5, //Banned by server
KR_LEAVE = 6, //Quit the game
} kickreason_t;
/* the max number of name changes in some time period */

View file

@ -65,6 +65,7 @@
#include "k_race.h"
#include "g_party.h"
#include "k_vote.h"
#include "k_zvote.h"
#ifdef SRB2_CONFIG_ENABLE_WEBM_MOVIES
#include "m_avrecorder.h"
@ -632,6 +633,8 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
"AUTOMATE", // XD_AUTOMATE
"REQMAPQUEUE", // XD_REQMAPQUEUE
"MAPQUEUE", // XD_MAPQUEUE
"CALLZVOTE", // XD_CALLZVOTE
"SETZVOTE", // XD_SETZVOTE
};
// =========================================================================
@ -844,6 +847,8 @@ void D_RegisterServerCommands(void)
#ifdef LUA_ALLOW_BYTECODE
COM_AddCommand("dumplua", Command_Dumplua_f);
#endif
K_RegisterMidVoteCVars();
}
// =========================================================================

View file

@ -163,7 +163,7 @@ typedef enum
XD_LUAVAR, // 20
XD_LUAFILE, // 21
// SRB2Kart
// Ring Racers
XD_SETUPVOTE, // 22
XD_MODIFYVOTE, // 23
XD_PICKVOTE, // 24
@ -181,6 +181,8 @@ typedef enum
XD_AUTOMATE, // 36
XD_REQMAPQUEUE, // 37
XD_MAPQUEUE, // 38
XD_CALLZVOTE, // 39
XD_SETZVOTE, // 40
MAXNETXCMD
} netxcmd_t;

View file

@ -68,6 +68,7 @@
#include "g_party.h"
#include "k_vote.h"
#include "k_serverstats.h"
#include "k_zvote.h"
#ifdef HAVE_DISCORDRPC
#include "discord.h"
@ -2390,6 +2391,11 @@ void G_Ticker(boolean run)
{
memset(player_name_changes, 0, sizeof player_name_changes);
}
if (Playing() == true)
{
K_TickMidVote();
}
}
}

View file

@ -316,6 +316,14 @@ void HU_Init(void)
PR ("TLWFN");
REG;
ADIM (NUM);
PR ("OPPRF");
REG;
ADIM (NUM);
PR ("PINGF");
REG;
#undef REG
#undef DIG
#undef PR
@ -2323,7 +2331,7 @@ Ping_gfx_color (int lag)
//
// HU_drawPing
//
void HU_drawPing(INT32 x, INT32 y, UINT32 lag, INT32 flags, boolean offline)
void HU_drawPing(fixed_t x, fixed_t y, UINT32 lag, INT32 flags, boolean offline)
{
UINT8 *colormap = NULL;
INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
@ -2339,12 +2347,36 @@ void HU_drawPing(INT32 x, INT32 y, UINT32 lag, INT32 flags, boolean offline)
gfxnum = Ping_gfx_num(lag);
if (measureid == 1)
V_DrawScaledPatch(x+11 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
{
V_DrawFixedPatch(
x + ((11 - pingmeasure[measureid]->width) * FRACUNIT),
y + (9 * FRACUNIT),
FRACUNIT, flags,
pingmeasure[measureid],
NULL
);
}
if (drawlocal)
V_DrawScaledPatch(x+2, y, flags, pinglocal[0]);
{
V_DrawFixedPatch(
x + (2 * FRACUNIT),
y,
FRACUNIT, flags,
pinglocal[0],
NULL
);
}
else
V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]);
{
V_DrawFixedPatch(
x + (2 * FRACUNIT),
y,
FRACUNIT, flags,
pinggfx[gfxnum],
NULL
);
}
colormap = R_GetTranslationColormap(TC_RAINBOW, Ping_gfx_color(lag), GTC_CACHE);
@ -2359,10 +2391,23 @@ void HU_drawPing(INT32 x, INT32 y, UINT32 lag, INT32 flags, boolean offline)
lag = (INT32)(lag * (1000.00f / TICRATE));
}
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+9, flags, lag, colormap);
x = V_DrawPingNum(
x + (((measureid == 1) ? 11 - pingmeasure[measureid]->width : 10) * FRACUNIT),
y + (9 * FRACUNIT),
flags, lag,
colormap
);
if (measureid == 0)
V_DrawScaledPatch(x+1 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
{
V_DrawFixedPatch(
x + ((1 - pingmeasure[measureid]->width) * FRACUNIT),
y + (9 * FRACUNIT),
FRACUNIT, flags,
pingmeasure[measureid],
NULL
);
}
}
void

View file

@ -32,7 +32,7 @@ extern "C" {
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
// SRB2kart
#define KART_FONTSTART '\"' // the first font character
#define KART_FONTSTART '!' // the first font character
#define KART_FONTEND 'Z'
#define KART_FONTSIZE (KART_FONTEND - KART_FONTSTART + 1)
@ -41,6 +41,11 @@ extern "C" {
#define AZ_FONTEND 'Z'
#define AZ_FONTSIZE (AZ_FONTEND - AZ_FONTSTART + 1)
#define NUM_FONTSTART '-' // the first font character
#define NUM_FONTEND '9'
#define NUM_FONTSIZE (NUM_FONTEND - NUM_FONTSTART + 1)
//
// Level title font
@ -75,6 +80,9 @@ enum
X (GM),
X (LSHI),
X (LSLOW),
X (OPPRF),
X (PINGF),
};
#undef X
@ -143,7 +151,7 @@ void HU_TickSongCredits(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);
void HU_clearChatChars(void);
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags, boolean offline); // Lat': Ping drawer for scoreboard.
void HU_drawPing(fixed_t x, fixed_t y, UINT32 ping, INT32 flags, boolean offline); // Lat': Ping drawer for scoreboard.
void HU_drawMiniPing(INT32 x, INT32 y, UINT32 ping, INT32 flags);
INT32 HU_CreateTeamScoresTbl(playersort_t *tab, UINT32 dmtotals[]);

View file

@ -2322,7 +2322,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
}
else if (tab[i].num != serverplayer || !server_lagless)
{
HU_drawPing(x + ((i < 8) ? -17 : rightoffset + 11), y-4, playerpingtable[tab[i].num], 0, false);
HU_drawPing((x + ((i < 8) ? -17 : rightoffset + 11)) * FRACUNIT, (y-4) * FRACUNIT, playerpingtable[tab[i].num], 0, false);
}
}
@ -4955,11 +4955,16 @@ K_drawMiniPing (void)
}
}
void K_drawButton(fixed_t x, fixed_t y, INT32 flags, patch_t *button[2], boolean pressed)
{
V_DrawFixedPatch(x, y, FRACUNIT, flags, button[pressed], NULL);
}
void K_drawButtonAnim(INT32 x, INT32 y, INT32 flags, patch_t *button[2], tic_t animtic)
{
const UINT8 anim_duration = 16;
const UINT8 anim = (animtic % (anim_duration * 2)) < anim_duration;
V_DrawScaledPatch(x, y, flags, button[anim]);
const boolean anim = ((animtic % (anim_duration * 2)) < anim_duration);
K_drawButton(x << FRACBITS, y << FRACBITS, flags, button, anim);
}
static void K_DrawDirectorButton(INT32 idx, const char *label, patch_t *kp[2], INT32 textflags)

View file

@ -45,6 +45,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
void K_DrawMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, UINT16 map, UINT8 *colormap);
void K_DrawLikeMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, patch_t *patch, UINT8 *colormap);
void K_drawTargetHUD(const vector3_t *origin, player_t *player);
void K_drawButton(fixed_t x, fixed_t y, INT32 flags, patch_t *button[2], boolean pressed);
void K_drawButtonAnim(INT32 x, INT32 y, INT32 flags, patch_t *button[2], tic_t animtic);
extern patch_t *kp_capsuletarget_arrow[2][2];

1123
src/k_zvote.c Normal file

File diff suppressed because it is too large Load diff

269
src/k_zvote.h Normal file
View file

@ -0,0 +1,269 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) by Sally "TehRealSalt" Cochenour
// Copyright (C) by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file k_zvote.h
/// \brief Player callable mid-game vote
#ifndef __K_ZVOTE__
#define __K_ZVOTE__
#include "doomdef.h"
#include "doomstat.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ZVOTE_GUI_CONFIRM (TICRATE)
#define ZVOTE_GUI_SUCCESS (3 * TICRATE)
#define ZVOTE_GUI_SLIDE (TICRATE / 2)
typedef enum
{
MVT_KICK, // Kick another player in the server
MVT_RTV, // Exit level early
MVT__MAX, // Total number of vote types
} midVoteType_e;
extern const char *g_midVoteTypeNames[MVT__MAX];
struct midVoteGUI_t
{
tic_t slide; // Slide in when Z is first pressed.
tic_t confirm; // How long this player has held Z.
boolean unpress; // Z button needs unpressed to continue accepting input.
};
struct midVote_t
{
boolean active; // If true, a vote is currently running.
player_t *caller; // The player that called for this vote.
player_t *victim; // If non-NULL, then this vote targets a player (kicks), don't let them vote on it.
boolean votes[MAXPLAYERS]; // Votes recieved from each player.
midVoteType_e type; // Type of vote that was called, see midVoteType_e.
INT32 variable; // Extra variable, unique purpose for each vote type.
tic_t time; // Time until the vote times out and fails.
tic_t delay; // Delay before another vote is allowed to be called.
tic_t end; // Ended animation, wait a second before activating callback.
UINT8 endVotes; // How many votes it got when the vote went through.
UINT8 endRequired; // How many votes were required when the vote went through.
midVoteGUI_t gui[MAXSPLITSCREENPLAYERS]; // GUI / inputs struct
};
extern midVote_t g_midVote;
/*--------------------------------------------------
void K_RegisterMidVoteCVars(void);
Registers the console variables related to
the Z-voting systems.
--------------------------------------------------*/
void K_RegisterMidVoteCVars(void);
/*--------------------------------------------------
void K_ResetMidVote(void);
Resets Z-voting variables to their default state.
--------------------------------------------------*/
void K_ResetMidVote(void);
/*--------------------------------------------------
boolean K_AnyMidVotesAllowed(void);
Determines if the server has enabled any types
of Z-votes. If this is false, then any menu options
for Z-voting should be disabled.
Input Arguments:-
N/A
Return:-
true if any vote types are enabled, otherwise false.
--------------------------------------------------*/
boolean K_AnyMidVotesAllowed(void);
/*--------------------------------------------------
boolean K_PlayerIDAllowedInMidVote(const UINT8 id);
Determines if this player ID is allowed to
vote or not.
Input Arguments:-
id - Player index to check.
Return:-
true if the player index can vote, otherwise false.
--------------------------------------------------*/
boolean K_PlayerIDAllowedInMidVote(const UINT8 id);
/*--------------------------------------------------
UINT8 K_RequiredMidVotes(void);
Calculates the number of votes needed for thr
vote to go through (aka, the "quorum"), as
per the server's settings. Usually at least
2 players are required for the vote to go through.
Input Arguments:-
N/A
Return:-
Number of player votes needed before we should
call K_MidVoteSuccess.
--------------------------------------------------*/
UINT8 K_RequiredMidVotes(void);
/*--------------------------------------------------
boolean K_PlayerIDMidVoted(const UINT8 id);
Determines if this player ID has voted for
the current issue or not. Is mostly safety
checks for g_midVote.votes[id], to force
the player who called the vote to vote for it,
the victim being affected to vote against,
and invalid players not having a vote.
Input Arguments:-
id - Player index to check.
Return:-
true if the player index voted yes, otherwise false.
--------------------------------------------------*/
boolean K_PlayerIDMidVoted(const UINT8 id);
/*--------------------------------------------------
UINT8 K_CountMidVotes(void);
Counts the total number of votes in favor of
the current issue.
Input Arguments:-
N/A
Return:-
Number of votes that agree.
--------------------------------------------------*/
UINT8 K_CountMidVotes(void);
/*--------------------------------------------------
boolean K_AllowNewMidVote(player_t *caller, midVoteType_e type, INT32 variable, player_t *victim);
Returns if the variables given are a valid state for
K_InitNewMidVote. Creates console alerts if it's not.
Input Arguments:-
caller - The player that is trying to call for a vote.
type - The type of vote they're trying to call.
variable - Extra arguments for the vote type.
victim - If this is a vote that negatively affects a
player, the player being affected would go here.
Return:-
true if we can start a new vote, otherwise false.
--------------------------------------------------*/
boolean K_AllowNewMidVote(player_t *caller, midVoteType_e type, INT32 variable, player_t *victim);
/*--------------------------------------------------
void K_InitNewMidVote(player_t *caller, midVoteType_e type, INT32 variable, player_t *victim);
Tries to start a new Z-vote, or mid-game vote. This will
handle everything needed to be initialized. Also calls
K_AllowNewMidVote to prevent invalid states from happening.
Input Arguments:-
caller - The player that is trying to call for a vote.
type - The type of vote they're trying to call.
variable - Extra arguments for the vote type.
victim - If this is a vote that negatively affects a
player, the player being affected would go here.
Return:-
N/A
--------------------------------------------------*/
void K_InitNewMidVote(player_t *caller, midVoteType_e type, INT32 variable, player_t *victim);
/*--------------------------------------------------
void K_MidVoteSuccess(void);
Ran whenever a vote meets the quorum, activates
the effect that the current vote is intended to
have.
--------------------------------------------------*/
void K_MidVoteSuccess(void);
/*--------------------------------------------------
void K_MidVoteFailure(void);
Ran when a vote times out without meeting the quorum.
Doesn't do anything but set a very long delay before
accepting another vote.
--------------------------------------------------*/
void K_MidVoteFailure(void);
/*--------------------------------------------------
void K_TickMidVote(void);
Run every game tick when in a server to process
the vote in progress, if it exists.
--------------------------------------------------*/
void K_TickMidVote(void);
/*--------------------------------------------------
void K_UpdateMidVotePatches(void);
Caches the patches needed for drawing the
HUD elements for Z-voting.
--------------------------------------------------*/
void K_UpdateMidVotePatches(void);
/*--------------------------------------------------
void K_DrawMidVote(void);
Handles drawing the HUD elements for Z-voting.
--------------------------------------------------*/
void K_DrawMidVote(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __K_ZVOTE__

View file

@ -807,8 +807,8 @@ static int libd_drawPingNum(lua_State *L)
UINT8 *colormap = NULL;
huddrawlist_h list;
HUDONLY
x = luaL_checkinteger(L, 1);
y = luaL_checkinteger(L, 2);
x = luaL_checkfixed(L, 1);
y = luaL_checkfixed(L, 2);
num = luaL_checkinteger(L, 3);
flags = luaL_optinteger(L, 4, 0);
flags &= ~V_PARAMMASK; // Don't let crashes happen.

View file

@ -44,6 +44,7 @@
#include "acs/interface.h"
#include "g_party.h"
#include "k_vote.h"
#include "k_zvote.h"
savedata_t savedata;
@ -53,6 +54,7 @@ savedata_t savedata;
#define ARCHIVEBLOCK_PLAYERS 0x7F448008
#define ARCHIVEBLOCK_PARTIES 0x7F87AF0C
#define ARCHIVEBLOCK_ROUNDQUEUE 0x7F721331
#define ARCHIVEBLOCK_ZVOTE 0x7F54FF0D
#define ARCHIVEBLOCK_WORLD 0x7F8C08C0
#define ARCHIVEBLOCK_POBJS 0x7F928546
#define ARCHIVEBLOCK_THINKERS 0x7F37037C
@ -985,6 +987,90 @@ static void P_NetUnArchiveRoundQueue(savebuffer_t *save)
}
}
static void P_NetArchiveZVote(savebuffer_t *save)
{
INT32 i;
WRITEUINT32(save->p, ARCHIVEBLOCK_ZVOTE);
WRITEUINT8(save->p, g_midVote.active);
if (g_midVote.active == true)
{
WRITEUINT8(
save->p,
(g_midVote.caller != NULL) ? (g_midVote.caller - players) : UINT8_MAX
);
WRITEUINT8(
save->p,
(g_midVote.victim != NULL) ? (g_midVote.victim - players) : UINT8_MAX
);
for (i = 0; i < MAXPLAYERS; i++)
{
WRITEUINT8(save->p, g_midVote.votes[i]);
}
WRITEUINT8(save->p, g_midVote.type);
WRITEINT32(save->p, g_midVote.variable);
WRITEUINT32(save->p, g_midVote.time);
WRITEUINT32(save->p, g_midVote.end);
WRITEUINT8(save->p, g_midVote.endVotes);
WRITEUINT8(save->p, g_midVote.endRequired);
}
WRITEUINT32(save->p, g_midVote.delay);
}
static void P_NetUnArchiveZVote(savebuffer_t *save)
{
INT32 i;
if (READUINT32(save->p) != ARCHIVEBLOCK_ZVOTE)
{
I_Error("Bad $$$.sav at archive block Z-Vote");
}
g_midVote.active = (boolean)READUINT8(save->p);
if (g_midVote.active == true)
{
UINT8 callerID = READUINT8(save->p);
UINT8 victimID = READUINT8(save->p);
if (callerID < MAXPLAYERS)
{
g_midVote.caller = &players[callerID];
}
if (victimID < MAXPLAYERS)
{
g_midVote.victim = &players[victimID];
}
for (i = 0; i < MAXPLAYERS; i++)
{
g_midVote.votes[i] = (boolean)READUINT8(save->p);
}
g_midVote.type = READUINT8(save->p);
g_midVote.variable = READINT32(save->p);
g_midVote.time = (tic_t)READUINT32(save->p);
g_midVote.end = (tic_t)READUINT32(save->p);
g_midVote.endVotes = READUINT8(save->p);
g_midVote.endRequired = READUINT8(save->p);
}
else
{
K_ResetMidVote();
}
g_midVote.delay = (tic_t)READUINT32(save->p);
}
///
/// Colormaps
///
@ -5463,6 +5549,7 @@ void P_SaveNetGame(savebuffer_t *save, boolean resending)
P_NetArchivePlayers(save);
P_NetArchiveParties(save);
P_NetArchiveRoundQueue(save);
P_NetArchiveZVote(save);
if (gamestate == GS_LEVEL)
{
@ -5514,6 +5601,7 @@ boolean P_LoadNetGame(savebuffer_t *save, boolean reloading)
P_NetUnArchivePlayers(save);
P_NetUnArchiveParties(save);
P_NetUnArchiveRoundQueue(save);
P_NetUnArchiveZVote(save);
if (gamestate == GS_LEVEL)
{

View file

@ -637,7 +637,7 @@ void SCR_DisplayTicRate(void)
}
// draw total frame:
V_DrawPingNum(x, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, cap, ticcntcolor);
V_DrawPingNum(x<<FRACBITS, 190<<FRACBITS, V_SNAPTOBOTTOM|V_SNAPTORIGHT, cap, ticcntcolor);
x -= digits * 4;
// draw "/"
@ -645,7 +645,7 @@ void SCR_DisplayTicRate(void)
}
// draw our actual framerate
V_DrawPingNum(x, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, fps, ticcntcolor);
V_DrawPingNum(x<<FRACBITS, 190<<FRACBITS, V_SNAPTOBOTTOM|V_SNAPTORIGHT, fps, ticcntcolor);
}
// SCR_DisplayLocalPing
@ -660,7 +660,7 @@ void SCR_DisplayLocalPing(void)
{
INT32 dispy = cv_ticrate.value ? 160 : 181;
offline = (consoleplayer == serverplayer);
HU_drawPing(307, dispy, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM | V_HUDTRANS, offline);
HU_drawPing(307 * FRACUNIT, dispy * FRACUNIT, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM | V_HUDTRANS, offline);
}
}

View file

@ -31,15 +31,9 @@
#include "m_misc.h" // moviemode
#include "m_anigif.h" // cv_gif_downscale
#include "p_setup.h" // NiGHTS grading
#include "k_grandprix.h" // we need to know grandprix status for titlecards
#include "k_boss.h"
#include "r_fps.h"
//random index
#include "m_random.h"
// item finder
#include "m_cond.h"
#include "m_random.h" // random index
#include "m_cond.h" // item finder
#ifdef HWRENDER
#include "hardware/hw_main.h"
@ -53,8 +47,9 @@
#include "k_hud.h" // SRB2kart
#include "v_video.h"
#include "r_skins.h" // NUMFACES
#include "r_fps.h"
#include "k_grandprix.h" // we need to know grandprix status for titlecards
#include "k_boss.h"
#include "k_zvote.h"
UINT16 objectsdrawn = 0;
@ -164,6 +159,7 @@ void ST_LoadGraphics(void)
// first anyway
// cache the status bar overlay icons (fullscreen mode)
K_LoadKartHUDGraphics();
K_UpdateMidVotePatches();
// Midnight Channel:
HU_UpdatePatch(&hud_tv1, "HUD_TV1");
@ -1242,6 +1238,8 @@ static void ST_overlayDrawer(void)
}
}
}
K_DrawMidVote();
}
void ST_DrawDemoTitleEntry(void)

View file

@ -212,6 +212,10 @@ TYPEDEF (waypoint_t);
// k_rank.h
TYPEDEF (gpRank_t);
// k_zvote.h
TYPEDEF (midVote_t);
TYPEDEF (midVoteGUI_t);
// lua_hudlib_drawlist.h
typedef struct huddrawlist_s *huddrawlist_h;

View file

@ -2264,7 +2264,7 @@ void V_DrawStringScaled(
spacew = 16;
break;
case KART_FONT:
spacew = 12;
spacew = 3;
switch (spacing)
{
case V_MONOSPACE:
@ -2287,6 +2287,12 @@ void V_DrawStringScaled(
case LSLOW_FONT:
spacew = 16;
break;
case OPPRF_FONT:
spacew = 5;
break;
case PINGF_FONT:
spacew = 3;
break;
}
switch (fontno)
@ -2311,6 +2317,10 @@ void V_DrawStringScaled(
case LSLOW_FONT:
lfh = 38;
break;
case OPPRF_FONT:
case PINGF_FONT:
lfh = 10;
break;
}
hchw = chw >> 1;
@ -2363,6 +2373,12 @@ void V_DrawStringScaled(
else
dim_fn = VariableCharacterDim;
break;
case KART_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = BunchedCharacterDim;
break;
case TINY_FONT:
if (chw)
dim_fn = FixedCharacterDim;
@ -2394,6 +2410,13 @@ void V_DrawStringScaled(
else
dim_fn = LSTitleCharacterDim;
break;
case OPPRF_FONT:
case PINGF_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = VariableCharacterDim;
break;
}
cx = x;
@ -2535,7 +2558,7 @@ fixed_t V_StringScaledWidth(
spacew = 16;
break;
case KART_FONT:
spacew = 12;
spacew = 3;
switch (spacing)
{
case V_MONOSPACE:
@ -2556,6 +2579,12 @@ fixed_t V_StringScaledWidth(
case LSLOW_FONT:
spacew = 16;
break;
case OPPRF_FONT:
spacew = 5;
break;
case PINGF_FONT:
spacew = 3;
break;
}
switch (fontno)
@ -2580,6 +2609,10 @@ fixed_t V_StringScaledWidth(
case LSLOW_FONT:
lfh = 38;
break;
case OPPRF_FONT:
case PINGF_FONT:
lfh = 10;
break;
}
hchw = chw >> 1;
@ -2619,6 +2652,12 @@ fixed_t V_StringScaledWidth(
else
dim_fn = VariableCharacterDim;
break;
case KART_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = BunchedCharacterDim;
break;
case TINY_FONT:
if (chw)
dim_fn = FixedCharacterDim;
@ -2650,6 +2689,13 @@ fixed_t V_StringScaledWidth(
else
dim_fn = LSTitleCharacterDim;
break;
case OPPRF_FONT:
case PINGF_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = VariableCharacterDim;
break;
}
cx = cy = 0;
@ -2734,23 +2780,22 @@ void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, con
// Draws a number using the PING font thingy.
// TODO: Merge number drawing functions into one with "font name" selection.
INT32 V_DrawPingNum(INT32 x, INT32 y, INT32 flags, INT32 num, const UINT8 *colormap)
fixed_t V_DrawPingNum(fixed_t x, fixed_t y, INT32 flags, INT32 num, const UINT8 *colormap)
{
INT32 w = SHORT(fontv[PINGNUM_FONT].font[0]->width); // this SHOULD always be 5 but I guess custom graphics exist.
if (flags & V_NOSCALESTART)
w *= vid.dupx;
// this SHOULD always be 5 but I guess custom graphics exist.
const fixed_t w = (fontv[PINGNUM_FONT].font[0]->width) * FRACUNIT;
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, fontv[PINGNUM_FONT].font[num%10], colormap);
num = -num;
}
do // draw the number
{
x -= (w - FRACUNIT); // Oni wanted their outline to intersect.
V_DrawFixedPatch(x, y, FRACUNIT, flags, fontv[PINGNUM_FONT].font[num % 10], colormap);
num /= 10;
} while (num);
} while (num > 0);
return x;
}

View file

@ -353,7 +353,7 @@ 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.
INT32 V_DrawPingNum(INT32 x, INT32 y, INT32 flags, INT32 num, const UINT8 *colormap);
fixed_t V_DrawPingNum(fixed_t x, fixed_t y, INT32 flags, INT32 num, const UINT8 *colormap);
void V_DrawProfileNum(INT32 x, INT32 y, INT32 flags, UINT8 num);