Merge remote-tracking branch 'remotes/pub/next' into followme

This commit is contained in:
wolfy852 2019-02-26 17:12:51 -06:00
commit ab95b45e38
44 changed files with 1045 additions and 269 deletions

View file

@ -379,6 +379,12 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB})
set(SRB2_HAVE_PNG ON) set(SRB2_HAVE_PNG ON)
add_definitions(-DHAVE_PNG) add_definitions(-DHAVE_PNG)
add_definitions(-D_LARGEFILE64_SOURCE) add_definitions(-D_LARGEFILE64_SOURCE)
set(SRB2_PNG_SOURCES apng.c)
set(SRB2_PNG_HEADERS apng.h)
prepend_sources(SRB2_PNG_SOURCES)
prepend_sources(SRB2_PNG_HEADERS)
source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}
${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS})
else() else()
message(WARNING "You have specified that PNG is available but it was not found. SRB2Kart may not compile correctly.") message(WARNING "You have specified that PNG is available but it was not found. SRB2Kart may not compile correctly.")
endif() endif()

View file

@ -341,6 +341,8 @@ endif
LIBS+=$(PNG_LDFLAGS) LIBS+=$(PNG_LDFLAGS)
CFLAGS+=$(PNG_CFLAGS) CFLAGS+=$(PNG_CFLAGS)
OBJS+=$(OBJDIR)/apng.o
endif endif
ifdef HAVE_LIBGME ifdef HAVE_LIBGME

View file

@ -228,6 +228,7 @@ ifdef GCC80
WFLAGS+=-Wno-format-overflow WFLAGS+=-Wno-format-overflow
WFLAGS+=-Wno-stringop-truncation WFLAGS+=-Wno-stringop-truncation
WFLAGS+=-Wno-stringop-overflow WFLAGS+=-Wno-stringop-overflow
WFLAGS+=-Wno-error=multistatement-macros
endif endif

289
src/apng.c Normal file
View file

@ -0,0 +1,289 @@
/*
Copyright 2019, James R.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "apng.h"
#define APNG_INFO_acTL 0x20000U
#define APNG_WROTE_acTL 0x10000U
struct apng_info_def
{
png_uint_32 mode;
png_uint_32 valid;
png_uint_32 num_frames;
png_uint_32 num_plays;
long start_acTL;/* acTL is written here */
png_flush_ptr output_flush_fn;
apng_seek_ptr output_seek_fn;
apng_tell_ptr output_tell_fn;
apng_set_acTL_ptr set_acTL_fn;
};
/* PROTOS (FUCK COMPILER) */
void apng_seek (png_structp, apng_const_infop, size_t);
size_t apng_tell (png_structp, apng_const_infop);
#ifdef PNG_WRITE_FLUSH_SUPPORTED
void apng_flush (png_structp, apng_infop);
#ifdef PNG_STDIO_SUPPORTED
void apng_default_flush (png_structp);
#endif/* PNG_STDIO_SUPPORTED */
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
#ifdef PNG_STDIO_SUPPORTED
void apng_default_seek (png_structp, size_t);
size_t apng_default_tell (png_structp);
#endif/* PNG_STDIO_SUPPORTED */
void apng_write_IEND (png_structp);
void apng_write_acTL (png_structp, png_uint_32, png_uint_32);
#ifndef PNG_WRITE_APNG_SUPPORTED
png_uint_32 apng_set_acTL_dummy (png_structp, png_infop,
png_uint_32, png_uint_32);
#endif/* PNG_WRITE_APNG_SUPPORTED */
apng_infop
apng_create_info_struct (png_structp pngp)
{
apng_infop ainfop;
(void)pngp;
if (( ainfop = calloc(sizeof (apng_info),1) ))
{
apng_set_write_fn(pngp, ainfop, 0, 0, 0, 0, 0);
apng_set_set_acTL_fn(pngp, ainfop, 0);
}
return ainfop;
}
void
apng_destroy_info_struct (png_structp pngp, apng_infopp ainfopp)
{
(void)pngp;
if (!( pngp && ainfopp ))
return;
free((*ainfopp));
}
void
apng_seek (png_structp pngp, apng_const_infop ainfop, size_t l)
{
(*(ainfop->output_seek_fn))(pngp, l);
}
size_t
apng_tell (png_structp pngp, apng_const_infop ainfop)
{
return (*(ainfop->output_tell_fn))(pngp);
}
#ifdef PNG_WRITE_FLUSH_SUPPORTED
void
apng_flush (png_structp pngp, apng_infop ainfop)
{
if (ainfop->output_flush_fn)
(*(ainfop->output_flush_fn))(pngp);
}
#ifdef PNG_STDIO_SUPPORTED
void
apng_default_flush (png_structp pngp)
{
if (!( pngp ))
return;
fflush((png_FILE_p)png_get_io_ptr);
}
#endif/* PNG_STDIO_SUPPORTED */
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
#ifdef PNG_STDIO_SUPPORTED
void
apng_default_seek (png_structp pngp, size_t l)
{
if (!( pngp ))
return;
if (fseek((png_FILE_p)png_get_io_ptr(pngp), (long)l, SEEK_SET) == -1)
png_error(pngp, "Seek Error");
}
size_t
apng_default_tell (png_structp pngp)
{
long l;
if (!( pngp ))
{
png_error(pngp, "Call to apng_default_tell with NULL pngp failed");
}
if (( l = ftell((png_FILE_p)png_get_io_ptr(pngp)) ) == -1)
png_error(pngp, "Tell Error");
return (size_t)l;
}
#endif/* PNG_STDIO_SUPPORTED */
void
apng_set_write_fn (png_structp pngp, apng_infop ainfop, png_voidp iop,
png_rw_ptr write_f, png_flush_ptr flush_f,
apng_seek_ptr seek_f, apng_tell_ptr tell_f)
{
if (!( pngp && ainfop ))
return;
png_set_write_fn(pngp, iop, write_f, flush_f);
#ifdef PNG_WRITE_FLUSH_SUPPORTED
#ifdef PNG_STDIO_SUPPORTED
if (!flush_f)
ainfop->output_flush_fn = &apng_default_flush;
else
#endif/* PNG_STDIO_SUPPORTED */
ainfop->output_flush_fn = flush_f;
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
#ifdef PNG_STDIO_SUPPORTED
if (!seek_f)
ainfop->output_seek_fn = &apng_default_seek;
else
#endif/* PNG_STDIO_SUPPORTED */
ainfop->output_seek_fn = seek_f;
#ifdef PNG_STDIO_SUPPORTED
if (!seek_f)
ainfop->output_tell_fn = apng_default_tell;
else
#endif/* PNG_STDIO_SUPPORTED */
ainfop->output_tell_fn = tell_f;
}
void
apng_write_IEND (png_structp pngp)
{
png_byte chunkc[] = "IEND";
png_write_chunk(pngp, chunkc, 0, 0);
}
void
apng_write_acTL (png_structp pngp, png_uint_32 frames, png_uint_32 plays)
{
png_byte chunkc[] = "acTL";
png_byte buf[8];
png_save_uint_32(buf, frames);
png_save_uint_32(buf + 4, plays);
png_write_chunk(pngp, chunkc, buf, 8);
}
png_uint_32
apng_set_acTL (png_structp pngp, png_infop infop, apng_infop ainfop,
png_uint_32 frames, png_uint_32 plays)
{
(void)pngp;
(void)infop;
if (!( pngp && infop && ainfop ))
return 0;
ainfop->num_frames = frames;
ainfop->num_plays = plays;
ainfop->valid |= APNG_INFO_acTL;
return 1;
}
void
apng_write_info_before_PLTE (png_structp pngp, png_infop infop,
apng_infop ainfop)
{
if (!( pngp && infop && ainfop ))
return;
png_write_info_before_PLTE(pngp, infop);
if (( ainfop->valid & APNG_INFO_acTL )&&!( ainfop->mode & APNG_WROTE_acTL ))
{
ainfop->start_acTL = apng_tell(pngp, ainfop);
apng_write_acTL(pngp, 0, 0);
/* modified for runtime dynamic linking */
(*(ainfop->set_acTL_fn))(pngp, infop, PNG_UINT_31_MAX, 0);
ainfop->mode |= APNG_WROTE_acTL;
}
}
void
apng_write_info (png_structp pngp, png_infop infop,
apng_infop ainfop)
{
apng_write_info_before_PLTE(pngp, infop, ainfop);
png_write_info(pngp, infop);
}
void
apng_write_end (png_structp pngp, png_infop infop, apng_infop ainfop)
{
(void)infop;
apng_write_IEND(pngp);
apng_seek(pngp, ainfop, ainfop->start_acTL);
apng_write_acTL(pngp, ainfop->num_frames, ainfop->num_plays);
#ifdef PNG_WRITE_FLUSH_SUPPORTED
#ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
apng_flush(pngp, infop);
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
#endif/* PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED */
}
#ifndef PNG_WRITE_APNG_SUPPORTED
png_uint_32
apng_set_acTL_dummy (png_structp pngp, png_infop infop,
png_uint_32 frames, png_uint_32 plays)
{
(void)pngp;
(void)infop;
(void)frames;
(void)plays;
return 0;
}
#endif/* PNG_WRITE_APNG_SUPPORTED */
/* Dynamic runtime linking capable! (Hopefully.) */
void
apng_set_set_acTL_fn (png_structp pngp, apng_infop ainfop,
apng_set_acTL_ptr set_acTL_f)
{
(void)pngp;
if (!ainfop->set_acTL_fn)
#ifndef PNG_WRITE_APNG_SUPPORTED
ainfop->set_acTL_fn = &apng_set_acTL_dummy;
#else
ainfop->set_acTL_fn = &png_set_acTL;
#endif/* PNG_WRITE_APNG_SUPPORTED */
else
ainfop->set_acTL_fn = set_acTL_f;
}

82
src/apng.h Normal file
View file

@ -0,0 +1,82 @@
/*
Copyright 2019, James R.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef APNG_H
#define APNG_H
#ifndef _MSC_VER
#ifndef _WII
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#endif
#endif
#ifndef _LFS64_LARGEFILE
#define _LFS64_LARGEFILE
#endif
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 0
#endif
#include <png.h>
typedef struct apng_info_def apng_info;
typedef apng_info * apng_infop;
typedef const apng_info * apng_const_infop;
typedef apng_info * * apng_infopp;
typedef void (*apng_seek_ptr)(png_structp, size_t);
typedef size_t (*apng_tell_ptr)(png_structp);
typedef png_uint_32 (*apng_set_acTL_ptr)(png_structp, png_infop,
png_uint_32, png_uint_32);
apng_infop apng_create_info_struct (png_structp png_ptr);
void apng_destroy_info_struct (png_structp png_ptr,
apng_infopp info_ptr_ptr);
/* Call the following functions in place of the libpng counterparts. */
png_uint_32 apng_set_acTL (png_structp png_ptr, png_infop info_ptr,
apng_infop ainfo_ptr,
png_uint_32 num_frames, png_uint_32 num_plays);
void apng_write_info_before_PLTE (png_structp png_ptr, png_infop info_ptr,
apng_infop ainfo_ptr);
void apng_write_info (png_structp png_ptr, png_infop info_ptr,
apng_infop ainfo_ptr);
void apng_write_end (png_structp png_ptr, png_infop info_ptr,
apng_infop ainfo_ptr);
void apng_set_write_fn (png_structp png_ptr, apng_infop ainfo_ptr,
png_voidp io_ptr,
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn,
apng_seek_ptr output_seek_fn, apng_tell_ptr output_tell_fn);
void apng_set_set_acTL_fn (png_structp png_ptr, apng_infop ainfo_ptr,
apng_set_acTL_ptr set_acTL_fn);
#endif/* APNG_H */

View file

@ -93,6 +93,7 @@ static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the
UINT16 pingmeasurecount = 1; UINT16 pingmeasurecount = 1;
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
tic_t servermaxping = 800; // server's max ping. Defaults to 800
#endif #endif
SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer[MAXNETNODES];
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen)
@ -648,6 +649,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->jointime = (tic_t)LONG(players[i].jointime); rsp->jointime = (tic_t)LONG(players[i].jointime);
rsp->splitscreenindex = players[i].splitscreenindex;
rsp->hasmo = false; rsp->hasmo = false;
//Transfer important mo information if the player has a body. //Transfer important mo information if the player has a body.
//This lets us resync players even if they are dead. //This lets us resync players even if they are dead.
@ -783,6 +786,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].jointime = (tic_t)LONG(rsp->jointime); players[i].jointime = (tic_t)LONG(rsp->jointime);
players[i].splitscreenindex = rsp->splitscreenindex;
//We get a packet for each player in game. //We get a packet for each player in game.
if (!playeringame[i]) if (!playeringame[i])
return; return;
@ -2211,8 +2216,10 @@ static void CL_ConnectToServer(boolean viams)
} }
while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes)))); while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes))));
#ifndef NONET
if (netgame) if (netgame)
F_StartWaitingPlayers(); F_StartWaitingPlayers();
#endif
DEBFILE(va("Synchronisation Finished\n")); DEBFILE(va("Synchronisation Finished\n"));
displayplayer = consoleplayer; displayplayer = consoleplayer;
@ -2723,7 +2730,10 @@ static void Command_Ban(void)
else else
{ {
if (server) // only the server is allowed to do this right now if (server) // only the server is allowed to do this right now
{
Ban_Add(COM_Argv(2)); Ban_Add(COM_Argv(2));
D_SaveBan(); // save the ban list
}
if (COM_Argc() == 2) if (COM_Argc() == 2)
{ {
@ -2754,6 +2764,42 @@ static void Command_Ban(void)
} }
static void Command_BanIP(void)
{
if (COM_Argc() < 2)
{
CONS_Printf(M_GetText("banip <ip> <reason>: ban an ip address\n"));
return;
}
if (server) // Only the server can use this, otherwise does nothing.
{
const char *address = (COM_Argv(1));
const char *reason;
if (COM_Argc() == 2)
reason = NULL;
else
reason = COM_Argv(2);
if (I_SetBanAddress && I_SetBanAddress(address, NULL))
{
if (reason)
CONS_Printf("Banned IP address %s for: %s\n", address, reason);
else
CONS_Printf("Banned IP address %s\n", address);
Ban_Add(reason);
D_SaveBan();
}
else
{
return;
}
}
}
static void Command_Kick(void) static void Command_Kick(void)
{ {
if (COM_Argc() < 2) if (COM_Argc() < 2)
@ -3060,6 +3106,7 @@ void D_ClientServerInit(void)
COM_AddCommand("getplayernum", Command_GetPlayerNum); COM_AddCommand("getplayernum", Command_GetPlayerNum);
COM_AddCommand("kick", Command_Kick); COM_AddCommand("kick", Command_Kick);
COM_AddCommand("ban", Command_Ban); COM_AddCommand("ban", Command_Ban);
COM_AddCommand("banip", Command_BanIP);
COM_AddCommand("clearbans", Command_ClearBans); COM_AddCommand("clearbans", Command_ClearBans);
COM_AddCommand("showbanlist", Command_ShowBan); COM_AddCommand("showbanlist", Command_ShowBan);
COM_AddCommand("reloadbans", Command_ReloadBan); COM_AddCommand("reloadbans", Command_ReloadBan);
@ -3314,6 +3361,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
addedtogame = true; addedtogame = true;
} }
players[newplayernum].splitscreenindex = splitscreenplayer;
if (netgame) if (netgame)
{ {
if (server && cv_showjoinaddress.value) if (server && cv_showjoinaddress.value)
@ -4355,6 +4404,8 @@ FILESTAMP
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i]) if (playeringame[i])
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i]; playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
servermaxping = (tic_t)netbuffer->u.pingtable[i++];
} }
break; break;
@ -4997,6 +5048,18 @@ void TryRunTics(tic_t realtics)
} }
#ifdef NEWPING #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) static inline void PingUpdate(void)
{ {
INT32 i; INT32 i;
@ -5017,6 +5080,9 @@ static inline void PingUpdate(void)
laggers[i] = true; laggers[i] = true;
numlaggers++; numlaggers++;
} }
else
pingtimeout[i] = 0;
} }
//kick lagging players... unless everyone but the server's ping sucks. //kick lagging players... unless everyone but the server's ping sucks.
@ -5027,12 +5093,19 @@ static inline void PingUpdate(void)
{ {
if (playeringame[i] && laggers[i]) if (playeringame[i] && laggers[i])
{ {
XBOXSTATIC char buf[2]; 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; buf[0] = (char)i;
buf[1] = KICK_MSG_PING_HIGH; buf[1] = KICK_MSG_PING_HIGH;
SendNetXCmd(XD_KICK, &buf, 2); 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);
} }
} }
} }
@ -5047,10 +5120,13 @@ static inline void PingUpdate(void)
realpingtable[i] = 0; //Reset each as we go. 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 //send out our ping packets
for (i = 0; i < MAXNETNODES; i++) for (i = 0; i < MAXNETNODES; i++)
if (nodeingame[i]) if (nodeingame[i])
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS); HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1));
pingmeasurecount = 1; //Reset count pingmeasurecount = 1; //Reset count
} }
@ -5064,7 +5140,7 @@ static void UpdatePingTable(void)
INT32 i; INT32 i;
if (server) if (server)
{ {
if (netgame && !(gametime % 255)) if (netgame && !(gametime % 35)) // update once per second.
PingUpdate(); PingUpdate();
// update node latency values so we can take an average later. // update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)

View file

@ -283,6 +283,8 @@ typedef struct
tic_t jointime; tic_t jointime;
UINT8 splitscreenindex;
//player->mo stuff //player->mo stuff
UINT8 hasmo; // Boolean UINT8 hasmo; // Boolean
@ -519,6 +521,7 @@ extern tic_t jointimeout;
extern UINT16 pingmeasurecount; extern UINT16 pingmeasurecount;
extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
#endif #endif
extern consvar_t extern consvar_t

View file

@ -1326,10 +1326,6 @@ void D_SRB2Main(void)
midi_disabled = true; midi_disabled = true;
#endif #endif
} }
else
{
CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
}
if (M_CheckParm("-nosound")) if (M_CheckParm("-nosound"))
sound_disabled = true; sound_disabled = true;
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
@ -1348,10 +1344,18 @@ void D_SRB2Main(void)
if (M_CheckParm("-nodigmusic")) if (M_CheckParm("-nodigmusic"))
digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
} }
I_StartupSound(); if (!( sound_disabled && digital_disabled
I_InitMusic(); #ifndef NO_MIDI
S_InitSfxChannels(cv_soundvolume.value); && midi_disabled
S_InitMusicDefs(); #endif
))
{
CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
I_StartupSound();
I_InitMusic();
S_InitSfxChannels(cv_soundvolume.value);
S_InitMusicDefs();
}
CONS_Printf("ST_Init(): Init status bar.\n"); CONS_Printf("ST_Init(): Init status bar.\n");
ST_Init(); ST_Init();

View file

@ -445,6 +445,14 @@ consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_co
#ifdef NEWPING #ifdef NEWPING
static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}}; 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}; 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 #endif
// Intermission time Tails 04-19-2002 // Intermission time Tails 04-19-2002
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
@ -674,6 +682,8 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_sleep); CV_RegisterVar(&cv_sleep);
#ifdef NEWPING #ifdef NEWPING
CV_RegisterVar(&cv_maxping); CV_RegisterVar(&cv_maxping);
CV_RegisterVar(&cv_pingtimeout);
CV_RegisterVar(&cv_showping);
#endif #endif
#ifdef SEENAMES #ifdef SEENAMES

View file

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

View file

@ -576,6 +576,8 @@ typedef struct player_s
UINT8 bot; UINT8 bot;
tic_t jointime; // Timer when player joins game to change skin/color tic_t jointime; // Timer when player joins game to change skin/color
UINT8 splitscreenindex;
#ifdef HWRENDER #ifdef HWRENDER
fixed_t fovadd; // adjust FOV for hw rendering fixed_t fovadd; // adjust FOV for hw rendering
#endif #endif

View file

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

View file

@ -2162,7 +2162,7 @@ void G_Ticker(boolean run)
G_CopyTiccmd(cmd, &netcmds[buf][i], 1); G_CopyTiccmd(cmd, &netcmds[buf][i], 1);
// Use the leveltime sent in the player's ticcmd to determine control lag // Use the leveltime sent in the player's ticcmd to determine control lag
cmd->latency = modeattacking ? 0 : min((leveltime & 0xFF) - cmd->latency, MAXPREDICTTICS-1); //@TODO add a cvar to allow setting this max cmd->latency = modeattacking ? 0 : min(((leveltime & 0xFF) - cmd->latency) & 0xFF, MAXPREDICTTICS-1); //@TODO add a cvar to allow setting this max
} }
} }
@ -2360,6 +2360,7 @@ void G_PlayerReborn(INT32 player)
UINT8 skincolor; UINT8 skincolor;
INT32 skin; INT32 skin;
tic_t jointime; tic_t jointime;
UINT8 splitscreenindex;
boolean spectator; boolean spectator;
INT16 bot; INT16 bot;
SINT8 pity; SINT8 pity;
@ -2383,6 +2384,7 @@ void G_PlayerReborn(INT32 player)
ctfteam = players[player].ctfteam; ctfteam = players[player].ctfteam;
exiting = players[player].exiting; exiting = players[player].exiting;
jointime = players[player].jointime; jointime = players[player].jointime;
splitscreenindex = players[player].splitscreenindex;
spectator = players[player].spectator; spectator = players[player].spectator;
pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_ANALOGMODE|PF_WANTSTOJOIN)); pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_ANALOGMODE|PF_WANTSTOJOIN));
@ -2482,6 +2484,7 @@ void G_PlayerReborn(INT32 player)
p->pflags = pflags; p->pflags = pflags;
p->ctfteam = ctfteam; p->ctfteam = ctfteam;
p->jointime = jointime; p->jointime = jointime;
p->splitscreenindex = splitscreenindex;
p->spectator = spectator; p->spectator = spectator;
// save player config truth reborn // save player config truth reborn
@ -4777,7 +4780,8 @@ void G_WriteGhostTic(mobj_t *ghost)
// GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic. // GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic.
if (abs(ghost->x-oldghost.x) > MAXMOM if (abs(ghost->x-oldghost.x) > MAXMOM
|| abs(ghost->y-oldghost.y) > MAXMOM || abs(ghost->y-oldghost.y) > MAXMOM
|| abs(ghost->z-oldghost.z) > MAXMOM) || abs(ghost->z-oldghost.z) > MAXMOM
|| (leveltime & 255) == 1) // Hack to enable slightly nicer resyncing
{ {
oldghost.x = ghost->x; oldghost.x = ghost->x;
oldghost.y = ghost->y; oldghost.y = ghost->y;
@ -4791,8 +4795,8 @@ void G_WriteGhostTic(mobj_t *ghost)
{ {
// For moving normally: // For moving normally:
// Store one full byte of movement, plus one byte of fractional movement. // Store one full byte of movement, plus one byte of fractional movement.
INT16 momx = (INT16)((ghost->x-oldghost.x)>>8); INT16 momx = (INT16)((ghost->x-oldghost.x + (1<<4))>>8);
INT16 momy = (INT16)((ghost->y-oldghost.y)>>8); INT16 momy = (INT16)((ghost->y-oldghost.y + (1<<4))>>8);
if (momx != oldghost.momx if (momx != oldghost.momx
|| momy != oldghost.momy) || momy != oldghost.momy)
{ {
@ -4802,7 +4806,7 @@ void G_WriteGhostTic(mobj_t *ghost)
WRITEINT16(demo_p,momx); WRITEINT16(demo_p,momx);
WRITEINT16(demo_p,momy); WRITEINT16(demo_p,momy);
} }
momx = (INT16)((ghost->z-oldghost.z)>>8); momx = (INT16)((ghost->z-oldghost.z + (1<<4))>>8);
if (momx != oldghost.momz) if (momx != oldghost.momz)
{ {
oldghost.momz = momx; oldghost.momz = momx;
@ -4906,8 +4910,9 @@ void G_WriteGhostTic(mobj_t *ghost)
void G_ConsGhostTic(void) void G_ConsGhostTic(void)
{ {
UINT8 ziptic; UINT8 ziptic;
UINT16 px,py,pz,gx,gy,gz; fixed_t px,py,pz,gx,gy,gz;
mobj_t *testmo; mobj_t *testmo;
fixed_t syncleeway;
boolean nightsfail = false; boolean nightsfail = false;
if (!demo_p || !demo_start) if (!demo_p || !demo_start)
@ -4924,6 +4929,7 @@ void G_ConsGhostTic(void)
oldghost.x = READFIXED(demo_p); oldghost.x = READFIXED(demo_p);
oldghost.y = READFIXED(demo_p); oldghost.y = READFIXED(demo_p);
oldghost.z = READFIXED(demo_p); oldghost.z = READFIXED(demo_p);
syncleeway = 0;
} }
else else
{ {
@ -4937,6 +4943,7 @@ void G_ConsGhostTic(void)
oldghost.x += oldghost.momx; oldghost.x += oldghost.momx;
oldghost.y += oldghost.momy; oldghost.y += oldghost.momy;
oldghost.z += oldghost.momz; oldghost.z += oldghost.momz;
syncleeway = FRACUNIT;
} }
if (ziptic & GZT_ANGLE) if (ziptic & GZT_ANGLE)
demo_p++; demo_p++;
@ -5002,14 +5009,14 @@ void G_ConsGhostTic(void)
} }
// Re-synchronise // Re-synchronise
px = testmo->x>>FRACBITS; px = testmo->x;
py = testmo->y>>FRACBITS; py = testmo->y;
pz = testmo->z>>FRACBITS; pz = testmo->z;
gx = oldghost.x>>FRACBITS; gx = oldghost.x;
gy = oldghost.y>>FRACBITS; gy = oldghost.y;
gz = oldghost.z>>FRACBITS; gz = oldghost.z;
if (nightsfail || px != gx || py != gy || pz != gz) if (nightsfail || abs(px-gx) > syncleeway || abs(py-gy) > syncleeway || abs(pz-gz) > syncleeway)
{ {
if (demosynced) if (demosynced)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));

View file

@ -74,6 +74,14 @@ patch_t *nightsnum[10]; // 0-9
patch_t *lt_font[LT_FONTSIZE]; patch_t *lt_font[LT_FONTSIZE];
patch_t *cred_font[CRED_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; static player_t *plr;
boolean chat_on; // entering a chat message? boolean chat_on; // entering a chat message?
static char w_chat[HU_MAXMSGLEN]; static char w_chat[HU_MAXMSGLEN];
@ -263,6 +271,8 @@ void HU_LoadGraphics(void)
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "NGTNUM%d", i); sprintf(buffer, "NGTNUM%d", i);
nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); 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 // minus for negative tallnums
@ -295,6 +305,17 @@ void HU_LoadGraphics(void)
tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX); tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX);
songcreditbg = W_CachePatchName("K_SONGCR", 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 // Initialise Heads up
@ -1612,9 +1633,9 @@ static void HU_drawChatLog(INT32 offset)
// draw arrows to indicate that we can (or not) scroll. // draw arrows to indicate that we can (or not) scroll.
if (chat_scroll > 0) 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) 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; justscrolleddown = false;
justscrolledup = 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); V_DrawRightAlignedThinString(cursongcredit.x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
} }
// Heads up displays drawer, call each frame // Heads up displays drawer, call each frame
// //
void HU_Drawer(void) void HU_Drawer(void)
@ -2369,36 +2391,25 @@ void HU_Erase(void)
// //
// HU_drawPing // 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? INT32 gfxnum = 4; // gfx to draw
UINT8 barcolor = 128; // color we use for the bars (green, yellow or red) UINT8 const *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SALMON, GTC_CACHE);
SINT8 i = 0;
SINT8 yoffset = 6;
INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2);
if (ping < 128) if (ping < 76)
{ gfxnum = 0;
numbars = 3; else if (ping < 137)
barcolor = 184; gfxnum = 1;
}
else if (ping < 256) else if (ping < 256)
{ gfxnum = 2;
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it. else if (ping < 500)
barcolor = 103; gfxnum = 3;
}
if (!notext || vid.width >= 640) // how sad, we're using a shit resolution. V_DrawScaledPatch(x, y, flags, pinggfx[gfxnum]);
V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping)); if (servermaxping && ping > servermaxping && hu_tick < 4) // flash ping red if too high
V_DrawPingNum(x, y+9, flags, ping, colormap);
for (i=0; (i<3); i++) // Draw the ping bar else
{ V_DrawPingNum(x, y+9, flags, ping, NULL);
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;
}
} }
// //

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 *hu_font[HU_FONTSIZE], *kart_font[KART_FONTSIZE], *tny_font[HU_FONTSIZE]; // SRB2kart
extern patch_t *tallnum[10]; extern patch_t *tallnum[10];
extern patch_t *pingnum[10];
extern patch_t *pinggfx[5];
extern patch_t *nightsnum[10]; extern patch_t *nightsnum[10];
extern patch_t *framecounter;
extern patch_t *frameslash;
extern patch_t *lt_font[LT_FONTSIZE]; extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *emeraldpics[7]; extern patch_t *emeraldpics[7];
@ -109,7 +113,7 @@ void HU_Drawer(void);
char HU_dequeueChatChar(void); char HU_dequeueChatChar(void);
void HU_Erase(void); void HU_Erase(void);
void HU_clearChatChars(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_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
//void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, 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); void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);

View file

@ -496,17 +496,17 @@ boolean K_IsPlayerWanted(player_t *player)
static INT32 K_KartItemOddsRace[NUMKARTRESULTS][10] = static INT32 K_KartItemOddsRace[NUMKARTRESULTS][10] =
{ {
//P-Odds 0 1 2 3 4 5 6 7 8 9 //P-Odds 0 1 2 3 4 5 6 7 8 9
/*Sneaker*/ {20, 0, 0, 4, 6, 6, 0, 0, 0, 0 }, // Sneaker /*Sneaker*/ {20, 0, 0, 4, 6, 7, 0, 0, 0, 0 }, // Sneaker
/*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3, 0 }, // Rocket Sneaker /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 1, 4, 5, 3, 0 }, // Rocket Sneaker
/*Invincibility*/ { 0, 0, 0, 0, 0, 1, 4, 6,14, 0 }, // Invincibility /*Invincibility*/ { 0, 0, 0, 0, 0, 1, 4, 6,10, 0 }, // Invincibility
/*Banana*/ { 0,10, 4, 2, 1, 0, 0, 0, 0, 0 }, // Banana /*Banana*/ { 0, 9, 4, 2, 1, 0, 0, 0, 0, 0 }, // Banana
/*Eggman Monitor*/ { 0, 3, 2, 1, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor /*Eggman Monitor*/ { 0, 3, 2, 1, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor
/*Orbinaut*/ { 0, 8, 6, 4, 2, 0, 0, 0, 0, 0 }, // Orbinaut /*Orbinaut*/ { 0, 7, 6, 4, 2, 0, 0, 0, 0, 0 }, // Orbinaut
/*Jawz*/ { 0, 0, 3, 2, 1, 1, 0, 0, 0, 0 }, // Jawz /*Jawz*/ { 0, 0, 3, 2, 1, 1, 0, 0, 0, 0 }, // Jawz
/*Mine*/ { 0, 0, 2, 2, 1, 0, 0, 0, 0, 0 }, // Mine /*Mine*/ { 0, 0, 2, 2, 1, 0, 0, 0, 0, 0 }, // Mine
/*Ballhog*/ { 0, 0, 0, 2, 1, 0, 0, 0, 0, 0 }, // Ballhog /*Ballhog*/ { 0, 0, 0, 2, 1, 0, 0, 0, 0, 0 }, // Ballhog
/*Self-Propelled Bomb*/ { 0, 0, 1, 2, 3, 4, 2, 2, 0,20 }, // Self-Propelled Bomb /*Self-Propelled Bomb*/ { 0, 0, 1, 2, 3, 4, 2, 2, 0,20 }, // Self-Propelled Bomb
/*Grow*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3, 0 }, // Grow /*Grow*/ { 0, 0, 0, 0, 0, 0, 2, 5, 7, 0 }, // Grow
/*Shrink*/ { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // Shrink /*Shrink*/ { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // Shrink
/*Thunder Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0, 0 }, // Thunder Shield /*Thunder Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0, 0 }, // Thunder Shield
/*Hyudoro*/ { 0, 0, 0, 0, 1, 2, 1, 0, 0, 0 }, // Hyudoro /*Hyudoro*/ { 0, 0, 0, 0, 1, 2, 1, 0, 0, 0 }, // Hyudoro
@ -616,7 +616,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
UINT8 pingame = 0, pexiting = 0, pinvin = 0; UINT8 pingame = 0, pexiting = 0, pinvin = 0;
SINT8 first = -1, second = -1; SINT8 first = -1, second = -1;
INT32 secondist = 0; INT32 secondist = 0;
boolean itemenabled[NUMKARTRESULTS] = { boolean itemenabled[NUMKARTRESULTS-1] = {
cv_sneaker.value, cv_sneaker.value,
cv_rocketsneaker.value, cv_rocketsneaker.value,
cv_invincibility.value, cv_invincibility.value,
@ -631,6 +631,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
cv_shrink.value, cv_shrink.value,
cv_thundershield.value, cv_thundershield.value,
cv_hyudoro.value, cv_hyudoro.value,
cv_pogospring.value,
cv_kitchensink.value, cv_kitchensink.value,
cv_triplesneaker.value, cv_triplesneaker.value,
cv_triplebanana.value, cv_triplebanana.value,
@ -640,7 +641,9 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
cv_dualjawz.value cv_dualjawz.value
}; };
if (!itemenabled[item] && !modeattacking) I_Assert(item > KITEM_NONE); // too many off by one scenarioes.
if (!itemenabled[item-1] && !modeattacking)
return 0; return 0;
if (G_BattleGametype()) if (G_BattleGametype())
@ -648,6 +651,9 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
else else
newodds = K_KartItemOddsRace[item-1][pos]; newodds = K_KartItemOddsRace[item-1][pos];
// Base multiplication to ALL item odds to simulate fractional precision
newodds *= 4;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (!playeringame[i] || players[i].spectator) if (!playeringame[i] || players[i].spectator)
@ -761,7 +767,7 @@ static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT3
break; break;
} }
for (j = 0; j < NUMKARTRESULTS; j++) for (j = 1; j < NUMKARTRESULTS; j++)
{ {
if (K_KartGetItemOdds(i, j, mashed) > 0) if (K_KartGetItemOdds(i, j, mashed) > 0)
{ {
@ -864,8 +870,8 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
UINT8 pingame = 0; UINT8 pingame = 0;
UINT8 roulettestop; UINT8 roulettestop;
INT32 useodds = 0; INT32 useodds = 0;
INT32 spawnchance[NUMKARTRESULTS * NUMKARTODDS]; INT32 spawnchance[NUMKARTRESULTS];
INT32 chance = 0, numchoices = 0; INT32 totalspawnchance = 0;
INT32 bestbumper = 0; INT32 bestbumper = 0;
fixed_t mashed = 0; fixed_t mashed = 0;
boolean dontforcespb = false; boolean dontforcespb = false;
@ -962,24 +968,23 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
} }
// Initializes existing spawnchance values // Initializes existing spawnchance values
for (i = 0; i < (NUMKARTRESULTS * NUMKARTODDS); i++) for (i = 0; i < NUMKARTRESULTS; i++)
spawnchance[i] = 0; spawnchance[i] = 0;
// Split into another function for a debug function below // Split into another function for a debug function below
useodds = K_FindUseodds(player, mashed, pingame, bestbumper, (spbplace != -1 && player->kartstuff[k_position] == spbplace+1), dontforcespb); useodds = K_FindUseodds(player, mashed, pingame, bestbumper, (spbplace != -1 && player->kartstuff[k_position] == spbplace+1), dontforcespb);
#define SETITEMRESULT(itemnum) \
for (chance = 0; chance < K_KartGetItemOdds(useodds, itemnum, mashed); chance++) \
spawnchance[numchoices++] = itemnum
for (i = 1; i < NUMKARTRESULTS; i++) for (i = 1; i < NUMKARTRESULTS; i++)
SETITEMRESULT(i); spawnchance[i] = (totalspawnchance += K_KartGetItemOdds(useodds, i, mashed));
#undef SETITEMRESULT
// Award the player whatever power is rolled // Award the player whatever power is rolled
if (numchoices > 0) if (totalspawnchance > 0)
K_KartGetItemResult(player, spawnchance[P_RandomKey(numchoices)]); {
totalspawnchance = P_RandomKey(totalspawnchance);
for (i = 0; i < NUMKARTRESULTS && spawnchance[i] <= totalspawnchance; i++);
K_KartGetItemResult(player, i);
}
else else
{ {
player->kartstuff[k_itemtype] = KITEM_SAD; player->kartstuff[k_itemtype] = KITEM_SAD;
@ -1053,7 +1058,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
mobj_t *fx; mobj_t *fx;
fixed_t momdifx, momdify; fixed_t momdifx, momdify;
fixed_t distx, disty; fixed_t distx, disty;
fixed_t dot, p; fixed_t dot, force;
fixed_t mass1, mass2; fixed_t mass1, mass2;
if (!mobj1 || !mobj2) if (!mobj1 || !mobj2)
@ -1111,6 +1116,30 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
momdifx = mobj1->momx - mobj2->momx; momdifx = mobj1->momx - mobj2->momx;
momdify = mobj1->momy - mobj2->momy; momdify = mobj1->momy - mobj2->momy;
// Adds the OTHER player's momentum times a bunch, for the best chance of getting the correct direction
distx = (mobj1->x + mobj2->momx*3) - (mobj2->x + mobj1->momx*3);
disty = (mobj1->y + mobj2->momy*3) - (mobj2->y + mobj1->momy*3);
if (distx == 0 && disty == 0)
// if there's no distance between the 2, they're directly on top of each other, don't run this
return;
{ // Normalize distance to the sum of the two objects' radii, since in a perfect world that would be the distance at the point of collision...
fixed_t dist = P_AproxDistance(distx, disty) ?: 1;
fixed_t nx = FixedDiv(distx, dist);
fixed_t ny = FixedDiv(disty, dist);
distx = FixedMul(mobj1->radius+mobj2->radius, nx);
disty = FixedMul(mobj1->radius+mobj2->radius, ny);
if (momdifx == 0 && momdify == 0)
{
// If there's no momentum difference, they're moving at exactly the same rate. Pretend they moved into each other.
momdifx = -nx;
momdify = -ny;
}
}
// if the speed difference is less than this let's assume they're going proportionately faster from each other // if the speed difference is less than this let's assume they're going proportionately faster from each other
if (P_AproxDistance(momdifx, momdify) < (25*mapobjectscale)) if (P_AproxDistance(momdifx, momdify) < (25*mapobjectscale))
{ {
@ -1121,34 +1150,6 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
momdify = FixedMul((25*mapobjectscale), normalisedy); momdify = FixedMul((25*mapobjectscale), normalisedy);
} }
// Adds the OTHER player's momentum, so that it reduces the chance of you being "inside" the other object
distx = (mobj1->x + mobj2->momx) - (mobj2->x + mobj1->momx);
disty = (mobj1->y + mobj2->momy) - (mobj2->y + mobj1->momy);
{ // Don't allow dist to get WAY too low, that it pushes you stupidly huge amounts, or backwards...
fixed_t dist = P_AproxDistance(distx, disty);
fixed_t nx = FixedDiv(distx, dist);
fixed_t ny = FixedDiv(disty, dist);
if (P_AproxDistance(distx, disty) < (3*mobj1->radius)/4)
{
distx = FixedMul((3*mobj1->radius)/4, nx);
disty = FixedMul((3*mobj1->radius)/4, ny);
}
if (P_AproxDistance(distx, disty) < (3*mobj2->radius)/4)
{
distx = FixedMul((3*mobj2->radius)/4, nx);
disty = FixedMul((3*mobj2->radius)/4, ny);
}
}
if (distx == 0 && disty == 0)
{
// if there's no distance between the 2, they're directly on top of each other, don't run this
return;
}
dot = FixedMul(momdifx, distx) + FixedMul(momdify, disty); dot = FixedMul(momdifx, distx) + FixedMul(momdify, disty);
if (dot >= 0) if (dot >= 0)
@ -1157,7 +1158,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
return; return;
} }
p = FixedDiv(dot, FixedMul(distx, distx)+FixedMul(disty, disty)); force = FixedDiv(dot, FixedMul(distx, distx)+FixedMul(disty, disty));
if (bounce == true && mass2 > 0) // Perform a Goomba Bounce. if (bounce == true && mass2 > 0) // Perform a Goomba Bounce.
mobj1->momz = -mobj1->momz; mobj1->momz = -mobj1->momz;
@ -1172,14 +1173,14 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
if (mass2 > 0) if (mass2 > 0)
{ {
mobj1->momx = mobj1->momx - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), p), distx); mobj1->momx = mobj1->momx - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), force), distx);
mobj1->momy = mobj1->momy - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), p), disty); mobj1->momy = mobj1->momy - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), force), disty);
} }
if (mass1 > 0 && solid == false) if (mass1 > 0 && solid == false)
{ {
mobj2->momx = mobj2->momx - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), p), -distx); mobj2->momx = mobj2->momx - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), force), -distx);
mobj2->momy = mobj2->momy - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), p), -disty); mobj2->momy = mobj2->momy - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), force), -disty);
} }
// Do the bump fx when we've CONFIRMED we can bump. // Do the bump fx when we've CONFIRMED we can bump.
@ -1891,8 +1892,10 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
} }
} }
#ifdef HAVE_BLUA
if (LUAh_PlayerSpin(player, inflictor, source)) // Let Lua do its thing or overwrite if it wants to. Make sure to let any possible instashield happen because we didn't get "damaged" in this case. if (LUAh_PlayerSpin(player, inflictor, source)) // Let Lua do its thing or overwrite if it wants to. Make sure to let any possible instashield happen because we didn't get "damaged" in this case.
return; return;
#endif
if (source && source != player->mo && source->player) if (source && source != player->mo && source->player)
K_PlayHitEmSound(source); K_PlayHitEmSound(source);
@ -1973,12 +1976,16 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
static void K_RemoveGrowShrink(player_t *player) static void K_RemoveGrowShrink(player_t *player)
{ {
player->kartstuff[k_growshrinktimer] = 0; player->kartstuff[k_growshrinktimer] = 0;
if (player->kartstuff[k_invincibilitytimer] == 0)
player->mo->color = player->skincolor; if (player->mo && !P_MobjWasRemoved(player->mo))
player->mo->scalespeed = mapobjectscale/TICRATE; {
player->mo->destscale = mapobjectscale; if (player->kartstuff[k_invincibilitytimer] == 0)
if (cv_kartdebugshrink.value && !modeattacking && !player->bot) player->mo->color = player->skincolor;
player->mo->destscale = (6*player->mo->destscale)/8; player->mo->scalespeed = mapobjectscale/TICRATE;
player->mo->destscale = mapobjectscale;
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
player->mo->destscale = (6*player->mo->destscale)/8;
}
P_RestoreMusic(player); P_RestoreMusic(player);
} }
@ -2022,8 +2029,10 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor)
} }
} }
#ifdef HAVE_BLUA
if (LUAh_PlayerSquish(player, inflictor, source)) // Let Lua do its thing or overwrite if it wants to. Make sure to let any possible instashield happen because we didn't get "damaged" in this case. if (LUAh_PlayerSquish(player, inflictor, source)) // Let Lua do its thing or overwrite if it wants to. Make sure to let any possible instashield happen because we didn't get "damaged" in this case.
return; return;
#endif
player->kartstuff[k_sneakertimer] = 0; player->kartstuff[k_sneakertimer] = 0;
player->kartstuff[k_driftboost] = 0; player->kartstuff[k_driftboost] = 0;
@ -2136,8 +2145,10 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
} }
} }
#ifdef HAVE_BLUA
if (LUAh_PlayerExplode(player, inflictor, source)) // Same thing. Also make sure to let Instashield happen blah blah if (LUAh_PlayerExplode(player, inflictor, source)) // Same thing. Also make sure to let Instashield happen blah blah
return; return;
#endif
if (source && source != player->mo && source->player) if (source && source != player->mo && source->player)
K_PlayHitEmSound(source); K_PlayHitEmSound(source);
@ -2762,11 +2773,24 @@ void K_SpawnSparkleTrail(mobj_t *mo)
void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent) void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
{ {
mobj_t *dust; mobj_t *dust;
angle_t aoff;
I_Assert(mo != NULL); I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo)); I_Assert(!P_MobjWasRemoved(mo));
dust = P_SpawnMobj(mo->x + (P_RandomRange(-25,25) * mo->scale), mo->y + (P_RandomRange(-25,25) * mo->scale), mo->z, MT_WIPEOUTTRAIL); if (mo->player)
aoff = (mo->player->frameangle + ANGLE_180);
else
aoff = (mo->angle + ANGLE_180);
if ((leveltime / 2) & 1)
aoff -= ANGLE_45;
else
aoff += ANGLE_45;
dust = P_SpawnMobj(mo->x + FixedMul(24*mo->scale, FINECOSINE(aoff>>ANGLETOFINESHIFT)) + (P_RandomRange(-8,8) << FRACBITS),
mo->y + FixedMul(24*mo->scale, FINESINE(aoff>>ANGLETOFINESHIFT)) + (P_RandomRange(-8,8) << FRACBITS),
mo->z, MT_WIPEOUTTRAIL);
P_SetTarget(&dust->target, mo); P_SetTarget(&dust->target, mo);
dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy); dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy);
@ -3255,6 +3279,7 @@ void K_DoSneaker(player_t *player, INT32 type)
{ {
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
K_PlayBoostTaunt(player->mo); K_PlayBoostTaunt(player->mo);
player->powers[pw_flashing] = 0; // Stop flashing after boosting
} }
} }
@ -3280,11 +3305,15 @@ static void K_DoShrink(player_t *user)
{ {
// Start shrinking! // Start shrinking!
K_DropItems(&players[i]); K_DropItems(&players[i]);
players[i].mo->scalespeed = mapobjectscale/TICRATE;
players[i].mo->destscale = (6*mapobjectscale)/8; if (!P_MobjWasRemoved(players[i].mo))
if (cv_kartdebugshrink.value && !modeattacking && !players[i].bot) {
players[i].mo->destscale = (6*players[i].mo->destscale)/8; players[i].mo->scalespeed = mapobjectscale/TICRATE;
players[i].kartstuff[k_growshrinktimer] = -(200+(40*(MAXPLAYERS-players[i].kartstuff[k_position]))); players[i].mo->destscale = (6*mapobjectscale)/8;
if (cv_kartdebugshrink.value && !modeattacking && !players[i].bot)
players[i].mo->destscale = (6*players[i].mo->destscale)/8;
players[i].kartstuff[k_growshrinktimer] = -(200+(40*(MAXPLAYERS-players[i].kartstuff[k_position])));
}
} }
// Grow should get taken away. // Grow should get taken away.
@ -3409,7 +3438,7 @@ void K_DropHnextList(player_t *player)
mobjtype_t type; mobjtype_t type;
boolean orbit, ponground, dropall = true; boolean orbit, ponground, dropall = true;
if (!work) if (!work || P_MobjWasRemoved(work))
return; return;
flip = P_MobjFlip(player->mo); flip = P_MobjFlip(player->mo);
@ -3546,7 +3575,7 @@ void K_DropItems(player_t *player)
K_DropHnextList(player); K_DropHnextList(player);
if (player->mo && player->kartstuff[k_itemamount]) if (player->mo && !P_MobjWasRemoved(player->mo) && player->kartstuff[k_itemamount])
{ {
mobj_t *drop = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FLOATINGITEM); mobj_t *drop = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FLOATINGITEM);
P_SetScale(drop, drop->scale>>4); P_SetScale(drop, drop->scale>>4);
@ -4679,6 +4708,7 @@ static void K_KartDrift(player_t *player, boolean onground)
player->kartstuff[k_driftend] = 0; player->kartstuff[k_driftend] = 0;
} }
// Incease/decrease the drift value to continue drifting in that direction // 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) if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_jmp] == 1 && onground && player->kartstuff[k_drift] != 0)
{ {
@ -4708,7 +4738,7 @@ static void K_KartDrift(player_t *player, boolean onground)
} }
// Disable drift-sparks until you're going fast enough // Disable drift-sparks until you're going fast enough
if (player->kartstuff[k_getsparks] == 0 || player->kartstuff[k_offroad]) if (player->kartstuff[k_getsparks] == 0 || (player->kartstuff[k_offroad] && !player->kartstuff[k_invincibilitytimer] && !player->kartstuff[k_hyudorotimer] && !player->kartstuff[k_sneakertimer]))
driftadditive = 0; driftadditive = 0;
if (player->speed > minspeed*2) if (player->speed > minspeed*2)
player->kartstuff[k_getsparks] = 1; player->kartstuff[k_getsparks] = 1;
@ -5434,43 +5464,46 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
} }
} }
// Friction if (onground)
if (!player->kartstuff[k_offroad])
{ {
if (player->speed > 0 && cmd->forwardmove == 0 && player->mo->friction == 59392) // Friction
player->mo->friction += 4608; if (!player->kartstuff[k_offroad])
if (player->speed > 0 && cmd->forwardmove < 0 && player->mo->friction == 59392) {
player->mo->friction += 1608; if (player->speed > 0 && cmd->forwardmove == 0 && player->mo->friction == 59392)
} player->mo->friction += 4608;
if (player->speed > 0 && cmd->forwardmove < 0 && player->mo->friction == 59392)
player->mo->friction += 1608;
}
// Karma ice physics // Karma ice physics
if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0)
{ {
player->mo->friction += 1228; player->mo->friction += 1228;
if (player->mo->friction > FRACUNIT) if (player->mo->friction > FRACUNIT)
player->mo->friction = FRACUNIT; player->mo->friction = FRACUNIT;
if (player->mo->friction < 0) if (player->mo->friction < 0)
player->mo->friction = 0; player->mo->friction = 0;
player->mo->movefactor = FixedDiv(ORIG_FRICTION, player->mo->friction); player->mo->movefactor = FixedDiv(ORIG_FRICTION, player->mo->friction);
if (player->mo->movefactor < FRACUNIT) if (player->mo->movefactor < FRACUNIT)
player->mo->movefactor = 19*player->mo->movefactor - 18*FRACUNIT; player->mo->movefactor = 19*player->mo->movefactor - 18*FRACUNIT;
else else
player->mo->movefactor = FRACUNIT; //player->mo->movefactor = ((player->mo->friction - 0xDB34)*(0xA))/0x80; player->mo->movefactor = FRACUNIT; //player->mo->movefactor = ((player->mo->friction - 0xDB34)*(0xA))/0x80;
if (player->mo->movefactor < 32) if (player->mo->movefactor < 32)
player->mo->movefactor = 32; player->mo->movefactor = 32;
} }
// Wipeout slowdown // Wipeout slowdown
if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow]) if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow])
{ {
if (player->kartstuff[k_offroad]) if (player->kartstuff[k_offroad])
player->mo->friction -= 4912; player->mo->friction -= 4912;
if (player->kartstuff[k_wipeoutslow] == 1) if (player->kartstuff[k_wipeoutslow] == 1)
player->mo->friction -= 9824; player->mo->friction -= 9824;
}
} }
K_KartDrift(player, onground); K_KartDrift(player, onground);
@ -7165,7 +7198,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
if (netgame // don't draw it offline if (netgame // don't draw it offline
&& tab[i].num != serverplayer) && 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); STRBUFCPY(strtime, tab[i].name);

View file

@ -410,6 +410,24 @@ static int libd_drawPaddedNum(lua_State *L)
return 0; 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) static int libd_drawFill(lua_State *L)
{ {
INT32 x = luaL_optinteger(L, 1, 0); INT32 x = luaL_optinteger(L, 1, 0);
@ -613,6 +631,7 @@ static luaL_Reg lib_draw[] = {
{"drawScaled", libd_drawScaled}, {"drawScaled", libd_drawScaled},
{"drawNum", libd_drawNum}, {"drawNum", libd_drawNum},
{"drawPaddedNum", libd_drawPaddedNum}, {"drawPaddedNum", libd_drawPaddedNum},
{"drawPingNum", libd_drawPingNum},
{"drawFill", libd_drawFill}, {"drawFill", libd_drawFill},
{"fadeScreen", libd_fadeScreen}, {"fadeScreen", libd_fadeScreen},
{"drawString", libd_drawString}, {"drawString", libd_drawString},

View file

@ -325,6 +325,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->bot); lua_pushinteger(L, plr->bot);
else if (fastcmp(field,"jointime")) else if (fastcmp(field,"jointime"))
lua_pushinteger(L, plr->jointime); lua_pushinteger(L, plr->jointime);
else if (fastcmp(field,"splitscreenindex"))
lua_pushinteger(L, plr->splitscreenindex);
#ifdef HWRENDER #ifdef HWRENDER
else if (fastcmp(field,"fovadd")) else if (fastcmp(field,"fovadd"))
lua_pushfixed(L, plr->fovadd); lua_pushfixed(L, plr->fovadd);
@ -613,6 +615,8 @@ static int player_set(lua_State *L)
return NOSET; return NOSET;
else if (fastcmp(field,"jointime")) else if (fastcmp(field,"jointime"))
plr->jointime = (tic_t)luaL_checkinteger(L, 3); plr->jointime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"splitscreenindex"))
return NOSET;
#ifdef HWRENDER #ifdef HWRENDER
else if (fastcmp(field,"fovadd")) else if (fastcmp(field,"fovadd"))
plr->fovadd = luaL_checkfixed(L, 3); plr->fovadd = luaL_checkfixed(L, 3);

View file

@ -1020,7 +1020,7 @@ void LUA_Archive(void)
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (!playeringame[i]) if (!playeringame[i] && i > 0) // NEVER skip player 0, this is for dedi servs.
continue; continue;
// all players in game will be archived, even if they just add a 0. // all players in game will be archived, even if they just add a 0.
ArchiveExtVars(&players[i], "player"); ArchiveExtVars(&players[i], "player");
@ -1056,7 +1056,7 @@ void LUA_UnArchive(void)
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (!playeringame[i]) if (!playeringame[i] && i > 0) // same here, this is to synch dediservs properly.
continue; continue;
UnArchiveExtVars(&players[i]); UnArchiveExtVars(&players[i]);
} }

View file

@ -439,7 +439,7 @@ static CV_PossibleValue_t serversort_cons_t[] = {
{1,"Modified State"}, {1,"Modified State"},
{2,"Most Players"}, {2,"Most Players"},
{3,"Least Players"}, {3,"Least Players"},
{4,"Max Players"}, {4,"Max Player Slots"},
{5,"Gametype"}, {5,"Gametype"},
{0,NULL} {0,NULL}
}; };
@ -1392,7 +1392,7 @@ static menuitem_t OP_HUDOptionsMenu[] =
{IT_STRING | IT_CVAR | IT_CV_SLIDER, {IT_STRING | IT_CVAR | IT_CV_SLIDER,
NULL, "HUD Visibility", &cv_translucenthud, 20}, 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, NULL, "Background Glass", &cons_backcolor, 45},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, {IT_STRING | IT_CVAR | IT_CV_SLIDER,
@ -1406,6 +1406,7 @@ static menuitem_t OP_HUDOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 120}, {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[] = static menuitem_t OP_ChatOptionsMenu[] =
{ {
// will ANYONE who doesn't know how to use the console want to touch this one? // will ANYONE who doesn't know how to use the console want to touch this one?
@ -1419,6 +1420,8 @@ static menuitem_t OP_ChatOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 50}, {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, "Message Fadeout Time", &cv_chattime, 60},
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 70}, {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[] = static menuitem_t OP_GameOptionsMenu[] =
@ -1471,15 +1474,16 @@ static menuitem_t OP_AdvServerOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 40}, {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, "Ping limit (ms)", &cv_maxping, 50},
{IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", &cv_nettimeout, 60}, {IT_STRING | IT_CVAR, NULL, "Ping timeout (s)", &cv_pingtimeout, 60},
{IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", &cv_jointimeout, 70}, {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, "Max. file transfer send (KB)", &cv_maxsend, 100},
{IT_STRING | IT_CVAR, NULL, "File transfer packet rate", &cv_downloadspeed, 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 join addresses", &cv_showjoinaddress, 130},
{IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 130}, {IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 140},
{IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 140}, {IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 150},
}; };
#endif #endif
@ -1832,7 +1836,6 @@ static menu_t SP_NightsGhostDef =
NULL NULL
};*/ };*/
#ifndef NONET
// Multiplayer // Multiplayer
menu_t MP_MainDef = menu_t MP_MainDef =
{ {
@ -1843,12 +1846,18 @@ menu_t MP_MainDef =
M_DrawMPMainMenu, M_DrawMPMainMenu,
42, 30, 42, 30,
0, 0,
M_CancelConnect
};
menu_t MP_ServerDef = MAPICONMENUSTYLE("M_MULTI", MP_ServerMenu, &MP_MainDef);
#endif
menu_t MP_OfflineServerDef = MAPICONMENUSTYLE("M_MULTI", MP_OfflineServerMenu, &MP_MainDef);
#ifndef NONET #ifndef NONET
M_CancelConnect
#else
NULL
#endif
};
menu_t MP_OfflineServerDef = MAPICONMENUSTYLE("M_MULTI", MP_OfflineServerMenu, &MP_MainDef);
#ifndef NONET
menu_t MP_ServerDef = MAPICONMENUSTYLE("M_MULTI", MP_ServerMenu, &MP_MainDef);
menu_t MP_ConnectDef = menu_t MP_ConnectDef =
{ {
"M_MULTI", "M_MULTI",

View file

@ -93,9 +93,8 @@ typedef off_t off64_t;
#ifdef PNG_WRITE_SUPPORTED #ifdef PNG_WRITE_SUPPORTED
#define USE_PNG // Only actually use PNG if write is supported. #define USE_PNG // Only actually use PNG if write is supported.
#if defined (PNG_WRITE_APNG_SUPPORTED) //|| !defined(PNG_STATIC) #if defined (PNG_WRITE_APNG_SUPPORTED) //|| !defined(PNG_STATIC)
#if (PNG_LIBPNG_VER_MAJOR) == 1 && (PNG_LIBPNG_VER_MINOR <= 4) // Supposedly, the current APNG code can't work on newer versions as is #include "apng.h"
#define USE_APNG #define USE_APNG
#endif
#endif #endif
// See hardware/hw_draw.c for a similar check to this one. // See hardware/hw_draw.c for a similar check to this one.
#endif #endif
@ -795,13 +794,13 @@ static inline void M_PNGImage(png_structp png_ptr, png_infop png_info_ptr, PNG_C
#ifdef USE_APNG #ifdef USE_APNG
static png_structp apng_ptr = NULL; static png_structp apng_ptr = NULL;
static png_infop apng_info_ptr = NULL; static png_infop apng_info_ptr = NULL;
static apng_infop apng_ainfo_ptr = NULL;
static png_FILE_p apng_FILE = NULL; static png_FILE_p apng_FILE = NULL;
static png_uint_32 apng_frames = 0; static png_uint_32 apng_frames = 0;
static png_byte acTL_cn[5] = { 97, 99, 84, 76, '\0'};
#ifdef PNG_STATIC // Win32 build have static libpng #ifdef PNG_STATIC // Win32 build have static libpng
#define apng_set_acTL png_set_acTL #define aPNG_set_acTL png_set_acTL
#define apng_write_frame_head png_write_frame_head #define aPNG_write_frame_head png_write_frame_head
#define apng_write_frame_tail png_write_frame_tail #define aPNG_write_frame_tail png_write_frame_tail
#else // outside libpng may not have apng support #else // outside libpng may not have apng support
#ifndef PNG_WRITE_APNG_SUPPORTED // libpng header may not have apng patch #ifndef PNG_WRITE_APNG_SUPPORTED // libpng header may not have apng patch
@ -838,20 +837,20 @@ static png_byte acTL_cn[5] = { 97, 99, 84, 76, '\0'};
#endif #endif
#endif #endif
typedef PNG_EXPORT(png_uint_32, (*P_png_set_acTL)) PNGARG((png_structp png_ptr, typedef png_uint_32 (*P_png_set_acTL) (png_structp png_ptr,
png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays)); png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays);
typedef PNG_EXPORT (void, (*P_png_write_frame_head)) PNGARG((png_structp png_ptr, typedef void (*P_png_write_frame_head) (png_structp png_ptr,
png_infop info_ptr, png_bytepp row_pointers, png_infop info_ptr, png_bytepp row_pointers,
png_uint_32 width, png_uint_32 height, png_uint_32 width, png_uint_32 height,
png_uint_32 x_offset, png_uint_32 y_offset, png_uint_32 x_offset, png_uint_32 y_offset,
png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
png_byte blend_op)); png_byte blend_op);
typedef PNG_EXPORT (void, (*P_png_write_frame_tail)) PNGARG((png_structp png_ptr, typedef void (*P_png_write_frame_tail) (png_structp png_ptr,
png_infop info_ptr)); png_infop info_ptr);
static P_png_set_acTL apng_set_acTL = NULL; static P_png_set_acTL aPNG_set_acTL = NULL;
static P_png_write_frame_head apng_write_frame_head = NULL; static P_png_write_frame_head aPNG_write_frame_head = NULL;
static P_png_write_frame_tail apng_write_frame_tail = NULL; static P_png_write_frame_tail aPNG_write_frame_tail = NULL;
#endif #endif
static inline boolean M_PNGLib(void) static inline boolean M_PNGLib(void)
@ -860,7 +859,7 @@ static inline boolean M_PNGLib(void)
return true; return true;
#else #else
static void *pnglib = NULL; static void *pnglib = NULL;
if (apng_set_acTL && apng_write_frame_head && apng_write_frame_tail) if (aPNG_set_acTL && aPNG_write_frame_head && aPNG_write_frame_tail)
return true; return true;
if (pnglib) if (pnglib)
return false; return false;
@ -880,16 +879,16 @@ static inline boolean M_PNGLib(void)
if (!pnglib) if (!pnglib)
return false; return false;
#ifdef HAVE_SDL #ifdef HAVE_SDL
apng_set_acTL = hwSym("png_set_acTL", pnglib); aPNG_set_acTL = hwSym("png_set_acTL", pnglib);
apng_write_frame_head = hwSym("png_write_frame_head", pnglib); aPNG_write_frame_head = hwSym("png_write_frame_head", pnglib);
apng_write_frame_tail = hwSym("png_write_frame_tail", pnglib); aPNG_write_frame_tail = hwSym("png_write_frame_tail", pnglib);
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
apng_set_acTL = GetProcAddress("png_set_acTL", pnglib); aPNG_set_acTL = GetProcAddress("png_set_acTL", pnglib);
apng_write_frame_head = GetProcAddress("png_write_frame_head", pnglib); aPNG_write_frame_head = GetProcAddress("png_write_frame_head", pnglib);
apng_write_frame_tail = GetProcAddress("png_write_frame_tail", pnglib); aPNG_write_frame_tail = GetProcAddress("png_write_frame_tail", pnglib);
#endif #endif
return (apng_set_acTL && apng_write_frame_head && apng_write_frame_tail); return (aPNG_set_acTL && aPNG_write_frame_head && aPNG_write_frame_tail);
#endif #endif
} }
@ -903,11 +902,6 @@ static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep pn
apng_frames++; apng_frames++;
#ifndef PNG_STATIC
if (apng_set_acTL)
#endif
apng_set_acTL(apng_ptr, apng_info_ptr, apng_frames, 0);
for (y = 0; y < height; y++) for (y = 0; y < height; y++)
{ {
row_pointers[y] = png_buf; row_pointers[y] = png_buf;
@ -915,9 +909,9 @@ static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep pn
} }
#ifndef PNG_STATIC #ifndef PNG_STATIC
if (apng_write_frame_head) if (aPNG_write_frame_head)
#endif #endif
apng_write_frame_head(apng_ptr, apng_info_ptr, row_pointers, aPNG_write_frame_head(apng_ptr, apng_info_ptr, row_pointers,
vid.width, /* width */ vid.width, /* width */
height, /* height */ height, /* height */
0, /* x offset */ 0, /* x offset */
@ -930,57 +924,21 @@ static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep pn
png_write_image(png_ptr, row_pointers); png_write_image(png_ptr, row_pointers);
#ifndef PNG_STATIC #ifndef PNG_STATIC
if (apng_write_frame_tail) if (aPNG_write_frame_tail)
#endif #endif
apng_write_frame_tail(apng_ptr, apng_info_ptr); aPNG_write_frame_tail(apng_ptr, apng_info_ptr);
png_free(png_ptr, (png_voidp)row_pointers); png_free(png_ptr, (png_voidp)row_pointers);
} }
static inline boolean M_PNGfind_acTL(void) static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr,
apng_infop png_ainfo_ptr)
{ {
png_byte cn[8]; // 4 bytes for len then 4 byes for name apng_set_acTL(png_ptr, png_info_ptr, png_ainfo_ptr, apng_frames, 0);
long endpos = ftell(apng_FILE); // not the real end of file, just what of libpng wrote
for (fseek(apng_FILE, 0, SEEK_SET); // let go to the start of the file
ftell(apng_FILE)+12 < endpos; // let not go over the file bound
fseek(apng_FILE, 1, SEEK_CUR) // we went 8 steps back and now we go 1 step forward
)
{
if (fread(cn, sizeof(cn), 1, apng_FILE) != 1) // read 8 bytes
return false; // failed to read data
if (fseek(apng_FILE, -8, SEEK_CUR) != 0) //rewind 8 bytes
return false; // failed to rewird
if (!png_memcmp(cn+4, acTL_cn, 4)) //cmp for chuck header
return true; // found it
}
return false; // acTL chuck not found
}
static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr)
{
png_byte data[16];
long oldpos;
#ifndef PNG_STATIC
if (apng_set_acTL)
#endif
apng_set_acTL(png_ptr, png_info_ptr, apng_frames, 0);
#ifndef NO_PNG_DEBUG #ifndef NO_PNG_DEBUG
png_debug(1, "in png_write_acTL\n"); png_debug(1, "in png_write_acTL\n");
#endif #endif
png_ptr->num_frames_to_write = apng_frames;
png_save_uint_32(data, apng_frames);
png_save_uint_32(data + 4, 0);
oldpos = ftell(apng_FILE);
if (M_PNGfind_acTL())
png_write_chunk(png_ptr, (png_bytep)acTL_cn, data, (png_size_t)8);
fseek(apng_FILE, oldpos, SEEK_SET);
} }
static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal) static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
@ -1012,6 +970,16 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
return false; return false;
} }
apng_ainfo_ptr = apng_create_info_struct(apng_ptr);
if (!apng_ainfo_ptr)
{
CONS_Debug(DBG_RENDER, "M_StartMovie: Error on allocate for apng\n");
png_destroy_write_struct(&apng_ptr, &apng_info_ptr);
fclose(apng_FILE);
remove(filename);
return false;
}
png_init_io(apng_ptr, apng_FILE); png_init_io(apng_ptr, apng_FILE);
#ifdef PNG_SET_USER_LIMITS_SUPPORTED #ifdef PNG_SET_USER_LIMITS_SUPPORTED
@ -1029,12 +997,11 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
M_PNGText(apng_ptr, apng_info_ptr, true); M_PNGText(apng_ptr, apng_info_ptr, true);
#ifndef PNG_STATIC apng_set_set_acTL_fn(apng_ptr, apng_ainfo_ptr, aPNG_set_acTL);
if (apng_set_acTL)
#endif
apng_set_acTL(apng_ptr, apng_info_ptr, PNG_UINT_31_MAX, 0);
png_write_info(apng_ptr, apng_info_ptr); apng_set_acTL(apng_ptr, apng_info_ptr, apng_ainfo_ptr, PNG_UINT_31_MAX, 0);
apng_write_info(apng_ptr, apng_info_ptr, apng_ainfo_ptr);
apng_frames = 0; apng_frames = 0;
@ -1237,8 +1204,8 @@ void M_StopMovie(void)
if (apng_frames) if (apng_frames)
{ {
M_PNGfix_acTL(apng_ptr, apng_info_ptr); M_PNGfix_acTL(apng_ptr, apng_info_ptr, apng_ainfo_ptr);
png_write_end(apng_ptr, apng_info_ptr); apng_write_end(apng_ptr, apng_info_ptr, apng_ainfo_ptr);
} }
png_destroy_write_struct(&apng_ptr, &apng_info_ptr); png_destroy_write_struct(&apng_ptr, &apng_info_ptr);

View file

@ -255,6 +255,8 @@ static void P_NetArchivePlayers(void)
WRITEUINT32(save_p, players[i].jointime); WRITEUINT32(save_p, players[i].jointime);
WRITEUINT8(save_p, players[i].splitscreenindex);
WRITEUINT16(save_p, flags); WRITEUINT16(save_p, flags);
if (flags & CAPSULE) if (flags & CAPSULE)
@ -441,6 +443,8 @@ static void P_NetUnArchivePlayers(void)
players[i].jointime = READUINT32(save_p); players[i].jointime = READUINT32(save_p);
players[i].splitscreenindex = READUINT8(save_p);
flags = READUINT16(save_p); flags = READUINT16(save_p);
if (flags & CAPSULE) if (flags & CAPSULE)

View file

@ -1314,7 +1314,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
return; return;
scalestep = (yscale2 - yscale)/(x2 - x1); scalestep = (yscale2 - yscale)/(x2 - x1) ?: 1;
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2? // The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
// sortscale = max(yscale, yscale2); // sortscale = max(yscale, yscale2);

View file

@ -403,7 +403,7 @@ void SCR_DisplayTicRate(void)
tic_t i; tic_t i;
tic_t ontic = I_GetTime(); tic_t ontic = I_GetTime();
tic_t totaltics = 0; tic_t totaltics = 0;
INT32 ticcntcolor = 0; const UINT8 *ticcntcolor = NULL;
for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i) for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i)
fpsgraph[i % TICRATE] = false; fpsgraph[i % TICRATE] = false;
@ -414,13 +414,36 @@ void SCR_DisplayTicRate(void)
if (fpsgraph[i]) if (fpsgraph[i])
++totaltics; ++totaltics;
if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP; if (totaltics <= TICRATE/2) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SALMON, GTC_CACHE);
else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP; 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_YELLOWMAP|V_NOSCALESTART, "FPS");
V_DrawString(vid.width-(40*vid.dupx), vid.height-( 8*vid.dupy), 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; 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 // move out to main code for consistency
void SCR_DisplayTicRate(void); void SCR_DisplayTicRate(void);
void SCR_DisplayLocalPing(void);
#undef DNWH #undef DNWH
#endif //__SCREEN_H__ #endif //__SCREEN_H__

View file

@ -70,6 +70,8 @@ if(${SDL2_FOUND})
set(SRB2_SDL2_TOTAL_SOURCES set(SRB2_SDL2_TOTAL_SOURCES
${SRB2_CORE_SOURCES} ${SRB2_CORE_SOURCES}
${SRB2_CORE_HEADERS} ${SRB2_CORE_HEADERS}
${SRB2_PNG_SOURCES}
${SRB2_PNG_HEADERS}
${SRB2_CORE_RENDER_SOURCES} ${SRB2_CORE_RENDER_SOURCES}
${SRB2_CORE_GAME_SOURCES} ${SRB2_CORE_GAME_SOURCES}
${SRB2_LUA_SOURCES} ${SRB2_LUA_SOURCES}
@ -80,7 +82,8 @@ if(${SDL2_FOUND})
${SRB2_SDL2_HEADERS} ${SRB2_SDL2_HEADERS}
) )
source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}) source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}
${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS})
source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES}) source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES})
source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES}) source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES})
source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES}) source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES})

View file

@ -164,6 +164,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\am_map.h" /> <ClInclude Include="..\am_map.h" />
<ClInclude Include="..\apng.h" />
<ClInclude Include="..\blua\lapi.h" /> <ClInclude Include="..\blua\lapi.h" />
<ClInclude Include="..\blua\lauxlib.h" /> <ClInclude Include="..\blua\lauxlib.h" />
<ClInclude Include="..\blua\lcode.h" /> <ClInclude Include="..\blua\lcode.h" />
@ -317,6 +318,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\am_map.c" /> <ClCompile Include="..\am_map.c" />
<ClCompile Include="..\apng.c" />
<ClCompile Include="..\blua\lapi.c" /> <ClCompile Include="..\blua\lapi.c" />
<ClCompile Include="..\blua\lauxlib.c" /> <ClCompile Include="..\blua\lauxlib.c" />
<ClCompile Include="..\blua\lbaselib.c" /> <ClCompile Include="..\blua\lbaselib.c" />

View file

@ -294,6 +294,9 @@
<ClInclude Include="..\lua_script.h"> <ClInclude Include="..\lua_script.h">
<Filter>LUA</Filter> <Filter>LUA</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\apng.h">
<Filter>M_Misc</Filter>
</ClInclude>
<ClInclude Include="..\md5.h"> <ClInclude Include="..\md5.h">
<Filter>M_Misc</Filter> <Filter>M_Misc</Filter>
</ClInclude> </ClInclude>

View file

@ -2834,6 +2834,50 @@
RelativePath="..\m_argv.h" RelativePath="..\m_argv.h"
> >
</File> </File>
<File
RelativePath="..\apng.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\apng.h"
>
</File>
<File <File
RelativePath="..\m_bbox.c" RelativePath="..\m_bbox.c"
> >

View file

@ -64,7 +64,7 @@
#include "../m_menu.h" #include "../m_menu.h"
#include "../d_main.h" #include "../d_main.h"
#include "../s_sound.h" #include "../s_sound.h"
#include "../i_sound.h" // midi pause/unpause #include "../i_sound.h" // midi pause/unpause
#include "../i_joy.h" #include "../i_joy.h"
#include "../st_stuff.h" #include "../st_stuff.h"
#include "../g_game.h" #include "../g_game.h"
@ -1361,6 +1361,9 @@ void I_FinishUpdate(void)
if (cv_ticrate.value) if (cv_ticrate.value)
SCR_DisplayTicRate(); SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
if (rendermode == render_soft && screens[0]) if (rendermode == render_soft && screens[0])
{ {
SDL_Rect rect; SDL_Rect rect;

View file

@ -43,6 +43,7 @@
1E44AF0D0B67CDE900BAD059 /* m_fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */; }; 1E44AF0D0B67CDE900BAD059 /* m_fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */; };
1E44AF0F0B67CDE900BAD059 /* m_menu.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF000B67CDE900BAD059 /* m_menu.c */; }; 1E44AF0F0B67CDE900BAD059 /* m_menu.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF000B67CDE900BAD059 /* m_menu.c */; };
1E44AF110B67CDE900BAD059 /* m_misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* m_misc.c */; }; 1E44AF110B67CDE900BAD059 /* m_misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* m_misc.c */; };
1E44AF110B67CDE900BAD059 /* apng.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* apng.c */; };
1E44AF130B67CDE900BAD059 /* m_random.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF040B67CDE900BAD059 /* m_random.c */; }; 1E44AF130B67CDE900BAD059 /* m_random.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF040B67CDE900BAD059 /* m_random.c */; };
1E44AF1A0B67CE2A00BAD059 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF180B67CE2A00BAD059 /* info.c */; }; 1E44AF1A0B67CE2A00BAD059 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF180B67CE2A00BAD059 /* info.c */; };
1E44AF1E0B67CE3600BAD059 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF1C0B67CE3600BAD059 /* md5.c */; }; 1E44AF1E0B67CE3600BAD059 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF1C0B67CE3600BAD059 /* md5.c */; };
@ -253,7 +254,9 @@
1E44AF000B67CDE900BAD059 /* m_menu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_menu.c; path = ../../m_menu.c; sourceTree = SOURCE_ROOT; }; 1E44AF000B67CDE900BAD059 /* m_menu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_menu.c; path = ../../m_menu.c; sourceTree = SOURCE_ROOT; };
1E44AF010B67CDE900BAD059 /* m_menu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_menu.h; path = ../../m_menu.h; sourceTree = SOURCE_ROOT; }; 1E44AF010B67CDE900BAD059 /* m_menu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_menu.h; path = ../../m_menu.h; sourceTree = SOURCE_ROOT; };
1E44AF020B67CDE900BAD059 /* m_misc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_misc.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; }; 1E44AF020B67CDE900BAD059 /* m_misc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_misc.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; };
1E44AF020B67CDE900BAD059 /* apng.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = apng.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; };
1E44AF030B67CDE900BAD059 /* m_misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_misc.h; path = ../../m_misc.h; sourceTree = SOURCE_ROOT; }; 1E44AF030B67CDE900BAD059 /* m_misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_misc.h; path = ../../m_misc.h; sourceTree = SOURCE_ROOT; };
1E44AF020B67CDE900BAD059 /* apng.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = apng.h; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; };
1E44AF040B67CDE900BAD059 /* m_random.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_random.c; path = ../../m_random.c; sourceTree = SOURCE_ROOT; }; 1E44AF040B67CDE900BAD059 /* m_random.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_random.c; path = ../../m_random.c; sourceTree = SOURCE_ROOT; };
1E44AF050B67CDE900BAD059 /* m_random.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_random.h; path = ../../m_random.h; sourceTree = SOURCE_ROOT; }; 1E44AF050B67CDE900BAD059 /* m_random.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_random.h; path = ../../m_random.h; sourceTree = SOURCE_ROOT; };
1E44AF060B67CDE900BAD059 /* m_swap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_swap.h; path = ../../m_swap.h; sourceTree = SOURCE_ROOT; }; 1E44AF060B67CDE900BAD059 /* m_swap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_swap.h; path = ../../m_swap.h; sourceTree = SOURCE_ROOT; };
@ -679,6 +682,8 @@
1E44AEFF0B67CDE900BAD059 /* m_fixed.h */, 1E44AEFF0B67CDE900BAD059 /* m_fixed.h */,
1E44AF020B67CDE900BAD059 /* m_misc.c */, 1E44AF020B67CDE900BAD059 /* m_misc.c */,
1E44AF030B67CDE900BAD059 /* m_misc.h */, 1E44AF030B67CDE900BAD059 /* m_misc.h */,
1E44AF020B67CDE900BAD059 /* apng.c */,
1E44AF030B67CDE900BAD059 /* apng.h */,
676BB51C0E0DE06100C95963 /* m_queue.c */, 676BB51C0E0DE06100C95963 /* m_queue.c */,
676BB51D0E0DE06100C95963 /* m_queue.h */, 676BB51D0E0DE06100C95963 /* m_queue.h */,
1E44AF040B67CDE900BAD059 /* m_random.c */, 1E44AF040B67CDE900BAD059 /* m_random.c */,

View file

@ -835,6 +835,16 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<ClCompile Include="..\apng.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\m_misc.c"> <ClCompile Include="..\m_misc.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -1293,6 +1303,7 @@
<ClInclude Include="filter\interp.h" /> <ClInclude Include="filter\interp.h" />
<ClInclude Include="filter\lq2x.h" /> <ClInclude Include="filter\lq2x.h" />
<ClInclude Include="..\p5prof.h" /> <ClInclude Include="..\p5prof.h" />
<ClInclude Include="..\apng.h" />
<ClInclude Include="..\d_clisrv.h" /> <ClInclude Include="..\d_clisrv.h" />
<ClInclude Include="..\d_event.h" /> <ClInclude Include="..\d_event.h" />
<ClInclude Include="..\d_main.h" /> <ClInclude Include="..\d_main.h" />

View file

@ -2790,6 +2790,50 @@
<Filter <Filter
Name="M_Misc" Name="M_Misc"
> >
<File
RelativePath="..\apng.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\apng.h"
>
</File>
<File <File
RelativePath="..\m_argv.c" RelativePath="..\m_argv.c"
> >

View file

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

View file

@ -1365,6 +1365,20 @@
path = ../../m_misc.h; path = ../../m_misc.h;
refType = 2; refType = 2;
}; };
84177764085A10EB000C01D8 = {
fileEncoding = 30;
isa = PBXFileReference;
name = apng.c;
path = ../../apng.c;
refType = 2;
};
84177765085A10EB000C01D8 = {
fileEncoding = 30;
isa = PBXFileReference;
name = m_misc.h;
path = ../../apng.h;
refType = 2;
};
84177766085A10EB000C01D8 = { 84177766085A10EB000C01D8 = {
fileEncoding = 30; fileEncoding = 30;
isa = PBXFileReference; isa = PBXFileReference;

View file

@ -43,6 +43,7 @@
1E44AF0D0B67CDE900BAD059 /* m_fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */; }; 1E44AF0D0B67CDE900BAD059 /* m_fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */; };
1E44AF0F0B67CDE900BAD059 /* m_menu.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF000B67CDE900BAD059 /* m_menu.c */; }; 1E44AF0F0B67CDE900BAD059 /* m_menu.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF000B67CDE900BAD059 /* m_menu.c */; };
1E44AF110B67CDE900BAD059 /* m_misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* m_misc.c */; }; 1E44AF110B67CDE900BAD059 /* m_misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* m_misc.c */; };
1E44AF110B67CDE900BAD059 /* apng.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* apng.c */; };
1E44AF130B67CDE900BAD059 /* m_random.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF040B67CDE900BAD059 /* m_random.c */; }; 1E44AF130B67CDE900BAD059 /* m_random.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF040B67CDE900BAD059 /* m_random.c */; };
1E44AF1A0B67CE2A00BAD059 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF180B67CE2A00BAD059 /* info.c */; }; 1E44AF1A0B67CE2A00BAD059 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF180B67CE2A00BAD059 /* info.c */; };
1E44AF1E0B67CE3600BAD059 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF1C0B67CE3600BAD059 /* md5.c */; }; 1E44AF1E0B67CE3600BAD059 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF1C0B67CE3600BAD059 /* md5.c */; };
@ -254,6 +255,8 @@
1E44AF010B67CDE900BAD059 /* m_menu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_menu.h; path = ../../m_menu.h; sourceTree = SOURCE_ROOT; }; 1E44AF010B67CDE900BAD059 /* m_menu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_menu.h; path = ../../m_menu.h; sourceTree = SOURCE_ROOT; };
1E44AF020B67CDE900BAD059 /* m_misc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_misc.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; }; 1E44AF020B67CDE900BAD059 /* m_misc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_misc.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; };
1E44AF030B67CDE900BAD059 /* m_misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_misc.h; path = ../../m_misc.h; sourceTree = SOURCE_ROOT; }; 1E44AF030B67CDE900BAD059 /* m_misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_misc.h; path = ../../m_misc.h; sourceTree = SOURCE_ROOT; };
1E44AF020B67CDE900BAD059 /* apng.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = apng.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; };
1E44AF030B67CDE900BAD059 /* apng.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = apng.h; path = ../../m_misc.h; sourceTree = SOURCE_ROOT; };
1E44AF040B67CDE900BAD059 /* m_random.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_random.c; path = ../../m_random.c; sourceTree = SOURCE_ROOT; }; 1E44AF040B67CDE900BAD059 /* m_random.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_random.c; path = ../../m_random.c; sourceTree = SOURCE_ROOT; };
1E44AF050B67CDE900BAD059 /* m_random.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_random.h; path = ../../m_random.h; sourceTree = SOURCE_ROOT; }; 1E44AF050B67CDE900BAD059 /* m_random.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_random.h; path = ../../m_random.h; sourceTree = SOURCE_ROOT; };
1E44AF060B67CDE900BAD059 /* m_swap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_swap.h; path = ../../m_swap.h; sourceTree = SOURCE_ROOT; }; 1E44AF060B67CDE900BAD059 /* m_swap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_swap.h; path = ../../m_swap.h; sourceTree = SOURCE_ROOT; };
@ -679,6 +682,8 @@
1E44AEFF0B67CDE900BAD059 /* m_fixed.h */, 1E44AEFF0B67CDE900BAD059 /* m_fixed.h */,
1E44AF020B67CDE900BAD059 /* m_misc.c */, 1E44AF020B67CDE900BAD059 /* m_misc.c */,
1E44AF030B67CDE900BAD059 /* m_misc.h */, 1E44AF030B67CDE900BAD059 /* m_misc.h */,
1E44AF020B67CDE900BAD059 /* apng.c */,
1E44AF030B67CDE900BAD059 /* apng.h */,
676BB51C0E0DE06100C95963 /* m_queue.c */, 676BB51C0E0DE06100C95963 /* m_queue.c */,
676BB51D0E0DE06100C95963 /* m_queue.h */, 676BB51D0E0DE06100C95963 /* m_queue.h */,
1E44AF040B67CDE900BAD059 /* m_random.c */, 1E44AF040B67CDE900BAD059 /* m_random.c */,

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]); V_DrawScaledPatch(x, y, flags, hu_font[c]);
} }
// Writes a single character for the chat. (draw WHITE if bit 7 set) // Writes a single character for the chat (half scaled). (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.. // 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) 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]) if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
return; 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) if (x + w > vid.width)
return; 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. // 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); } 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 // Write a string using the credit font
// NOTE: the text is centered for screens larger than the base width // 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_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num);
void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits); 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 // Find string width from lt_font chars
INT32 V_LevelNameWidth(const char *string); INT32 V_LevelNameWidth(const char *string);
INT32 V_LevelNameHeight(const char *string); INT32 V_LevelNameHeight(const char *string);

View file

@ -191,8 +191,10 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum)
{ {
posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart); posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart);
posStart++; posStart++;
#ifdef HAVE_BLUA
for (; posStart < posEnd; posStart++) for (; posStart < posEnd; posStart++)
LUA_LoadLump(wadnum, posStart); LUA_LoadLump(wadnum, posStart);
#endif
} }
posStart = W_CheckNumForFolderStartPK3("SOC/", wadnum, 0); posStart = W_CheckNumForFolderStartPK3("SOC/", wadnum, 0);
if (posStart != INT16_MAX) if (posStart != INT16_MAX)
@ -794,7 +796,9 @@ UINT16 W_InitFile(const char *filename)
DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0); DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0);
break; break;
case RET_LUA: case RET_LUA:
#ifdef HAVE_BLUA
LUA_LoadLump(numwadfiles - 1, 0); LUA_LoadLump(numwadfiles - 1, 0);
#endif
break; break;
default: default:
break; break;

View file

@ -182,6 +182,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\am_map.c" /> <ClCompile Include="..\am_map.c" />
<ClCompile Include="..\apng.c" />
<ClCompile Include="..\blua\lapi.c" /> <ClCompile Include="..\blua\lapi.c" />
<ClCompile Include="..\blua\lauxlib.c" /> <ClCompile Include="..\blua\lauxlib.c" />
<ClCompile Include="..\blua\lbaselib.c" /> <ClCompile Include="..\blua\lbaselib.c" />
@ -330,6 +331,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\am_map.h" /> <ClInclude Include="..\am_map.h" />
<ClInclude Include="..\apng.h" />
<ClInclude Include="..\blua\lapi.h" /> <ClInclude Include="..\blua\lapi.h" />
<ClInclude Include="..\blua\lauxlib.h" /> <ClInclude Include="..\blua\lauxlib.h" />
<ClInclude Include="..\blua\lcode.h" /> <ClInclude Include="..\blua\lcode.h" />

View file

@ -2851,6 +2851,50 @@
RelativePath="..\m_misc.h" RelativePath="..\m_misc.h"
> >
</File> </File>
<File
RelativePath="..\apng.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\apng.h"
>
</File>
<File <File
RelativePath="..\m_queue.c" RelativePath="..\m_queue.c"
> >

View file

@ -639,9 +639,6 @@ void I_Error(const char *error, ...)
if (!errorcount) if (!errorcount)
{ {
M_SaveConfig(NULL); // save game config, cvars.. M_SaveConfig(NULL); // save game config, cvars..
#ifndef NONET
D_SaveBan(); // save the ban list
#endif
G_SaveGameData(); G_SaveGameData();
} }

View file

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

View file

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