Switch to using epoll on linux, because we can.
Rework q3bsp_mergedlightmaps as q3bsp_mergelightmaps. Now a boolean filling to the gpu's limit. Now also fills horizontally too. ftemaster now provides needpass info for sv_public 2 servers. fix (most?) ftemaster crashes. ftemaster now supports protocol name aliases (allowing for more friendly game names in its html). ftemaster now pings the servers from a different port. This should highlight/exclude servers that are unreachable for nat/firewall reasons. Fix memory leak from mvd recording. Servers should now cope better with ctrl-z and related fg/bg unix shell commands. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5638 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
62f2a380e1
commit
fe28099e68
30 changed files with 2126 additions and 1468 deletions
|
@ -976,24 +976,6 @@ readit:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_GetMessage
|
||||
|
||||
Handles recording and playback of demos, on top of NET_ code
|
||||
====================
|
||||
*/
|
||||
qboolean CL_GetMessage (void)
|
||||
{
|
||||
if (cls.demoplayback != DPB_NONE)
|
||||
return CL_GetDemoMessage ();
|
||||
|
||||
if (NET_GetPacket (cls.sockets, 0) < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_Stop_f
|
||||
|
|
|
@ -743,6 +743,12 @@ char *CL_TryingToConnect(void)
|
|||
return cls.servername;
|
||||
}
|
||||
|
||||
#ifdef NQPROT
|
||||
static void CL_NullReadPacket(void)
|
||||
{ //just drop it all
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_CheckForResend
|
||||
|
@ -972,9 +978,10 @@ void CL_CheckForResend (void)
|
|||
NET_AdrToString(data, sizeof(data), &connectinfo.adr);
|
||||
|
||||
/*eat up the server's packets, to clear any lingering loopback packets (like disconnect commands... yes this might cause packetloss for other clients)*/
|
||||
while(NET_GetPacket (svs.sockets, 0) >= 0)
|
||||
{
|
||||
}
|
||||
svs.sockets->ReadGamePacket = CL_NullReadPacket;
|
||||
NET_ReadPackets(svs.sockets);
|
||||
svs.sockets->ReadGamePacket = SV_ReadPacket;
|
||||
|
||||
net_message.packing = SZ_RAWBYTES;
|
||||
net_message.cursize = 0;
|
||||
MSG_BeginReading(net_message.prim);
|
||||
|
@ -3814,6 +3821,134 @@ void CLNQ_ConnectionlessPacket(void)
|
|||
|
||||
void CL_MVDUpdateSpectator (void);
|
||||
void CL_WriteDemoMessage (sizebuf_t *msg, int payloadoffset);
|
||||
|
||||
void CL_ReadPacket(void)
|
||||
{
|
||||
if (!qrenderer)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_DTLS
|
||||
if (*(int *)net_message.data != -1)
|
||||
if (NET_DTLS_Decode(cls.sockets))
|
||||
if (!net_message.cursize)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef NQPROT
|
||||
if (cls.demoplayback == DPB_NETQUAKE)
|
||||
{
|
||||
MSG_BeginReading (cls.netchan.netprim);
|
||||
cls.netchan.last_received = realtime;
|
||||
CLNQ_ParseServerMessage ();
|
||||
|
||||
if (!cls.demoplayback)
|
||||
CL_NextDemo();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef Q2CLIENT
|
||||
if (cls.demoplayback == DPB_QUAKE2)
|
||||
{
|
||||
MSG_BeginReading (cls.netchan.netprim);
|
||||
cls.netchan.last_received = realtime;
|
||||
CLQ2_ParseServerMessage ();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// remote command packet
|
||||
//
|
||||
if (*(int *)net_message.data == -1)
|
||||
{
|
||||
CL_ConnectionlessPacket ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (net_message.cursize < 6 && (cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV)) //MVDs don't have the whole sequence header thing going on
|
||||
{
|
||||
char adr[MAX_ADR_SIZE];
|
||||
Con_TPrintf ("%s: Runt packet\n", NET_AdrToString(adr, sizeof(adr), &net_from));
|
||||
return;
|
||||
}
|
||||
|
||||
if (cls.state == ca_disconnected)
|
||||
{ //connect to nq servers, but don't get confused with sequenced packets.
|
||||
if (NET_WasSpecialPacket(cls.sockets))
|
||||
return;
|
||||
#ifdef NQPROT
|
||||
CLNQ_ConnectionlessPacket ();
|
||||
#endif
|
||||
return; //ignore it. We arn't connected.
|
||||
}
|
||||
|
||||
//
|
||||
// packet from server
|
||||
//
|
||||
if (!cls.demoplayback &&
|
||||
!NET_CompareAdr (&net_from, &cls.netchan.remote_address))
|
||||
{
|
||||
char adr[MAX_ADR_SIZE];
|
||||
if (NET_WasSpecialPacket(cls.sockets))
|
||||
return;
|
||||
Con_DPrintf ("%s:sequenced packet from wrong server\n"
|
||||
,NET_AdrToString(adr, sizeof(adr), &net_from));
|
||||
return;
|
||||
}
|
||||
|
||||
if (cls.netchan.pext_stunaware) //should be safe to do this here.
|
||||
if (NET_WasSpecialPacket(cls.sockets))
|
||||
return;
|
||||
|
||||
switch(cls.protocol)
|
||||
{
|
||||
case CP_NETQUAKE:
|
||||
#ifdef NQPROT
|
||||
if(NQNetChan_Process(&cls.netchan))
|
||||
{
|
||||
MSG_ChangePrimitives(cls.netchan.netprim);
|
||||
CL_WriteDemoMessage (&net_message, msg_readcount);
|
||||
CLNQ_ParseServerMessage ();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case CP_PLUGIN:
|
||||
break;
|
||||
case CP_QUAKE2:
|
||||
#ifdef Q2CLIENT
|
||||
if (!Netchan_Process(&cls.netchan))
|
||||
return; // wasn't accepted for some reason
|
||||
CLQ2_ParseServerMessage ();
|
||||
break;
|
||||
#endif
|
||||
case CP_QUAKE3:
|
||||
#ifdef Q3CLIENT
|
||||
CLQ3_ParseServerMessage();
|
||||
#endif
|
||||
break;
|
||||
case CP_QUAKEWORLD:
|
||||
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
|
||||
{
|
||||
MSG_BeginReading(cls.netchan.netprim);
|
||||
cls.netchan.last_received = realtime;
|
||||
cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence;
|
||||
}
|
||||
else if (!Netchan_Process(&cls.netchan))
|
||||
return; // wasn't accepted for some reason
|
||||
|
||||
CL_WriteDemoMessage (&net_message, msg_readcount);
|
||||
|
||||
if (cls.netchan.incoming_sequence > cls.netchan.outgoing_sequence)
|
||||
{ //server should not be responding to packets we have not sent yet
|
||||
Con_DPrintf("Server is from the future! (%i packets)\n", cls.netchan.incoming_sequence - cls.netchan.outgoing_sequence);
|
||||
cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence;
|
||||
}
|
||||
MSG_ChangePrimitives(cls.netchan.netprim);
|
||||
CLQW_ParseServerMessage ();
|
||||
break;
|
||||
case CP_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
=================
|
||||
CL_ReadPackets
|
||||
|
@ -3821,145 +3956,14 @@ CL_ReadPackets
|
|||
*/
|
||||
void CL_ReadPackets (void)
|
||||
{
|
||||
char adr[MAX_ADR_SIZE];
|
||||
|
||||
if (!qrenderer)
|
||||
return;
|
||||
|
||||
// while (NET_GetPacket ())
|
||||
for(;;)
|
||||
if (cls.demoplayback != DPB_NONE)
|
||||
{
|
||||
if (!CL_GetMessage())
|
||||
#ifndef HAVE_DTLS
|
||||
break;
|
||||
#else
|
||||
{
|
||||
NET_DTLS_Timeouts(cls.sockets);
|
||||
break;
|
||||
}
|
||||
|
||||
if (*(int *)net_message.data != -1)
|
||||
if (NET_DTLS_Decode(cls.sockets))
|
||||
if (!net_message.cursize)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
#ifdef NQPROT
|
||||
if (cls.demoplayback == DPB_NETQUAKE)
|
||||
{
|
||||
MSG_BeginReading (cls.netchan.netprim);
|
||||
cls.netchan.last_received = realtime;
|
||||
CLNQ_ParseServerMessage ();
|
||||
|
||||
if (!cls.demoplayback)
|
||||
CL_NextDemo();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#ifdef Q2CLIENT
|
||||
if (cls.demoplayback == DPB_QUAKE2)
|
||||
{
|
||||
MSG_BeginReading (cls.netchan.netprim);
|
||||
cls.netchan.last_received = realtime;
|
||||
CLQ2_ParseServerMessage ();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// remote command packet
|
||||
//
|
||||
if (*(int *)net_message.data == -1)
|
||||
{
|
||||
CL_ConnectionlessPacket ();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (net_message.cursize < 6 && (cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV)) //MVDs don't have the whole sequence header thing going on
|
||||
{
|
||||
Con_TPrintf ("%s: Runt packet\n", NET_AdrToString(adr, sizeof(adr), &net_from));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cls.state == ca_disconnected)
|
||||
{ //connect to nq servers, but don't get confused with sequenced packets.
|
||||
if (NET_WasSpecialPacket(cls.sockets))
|
||||
continue;
|
||||
#ifdef NQPROT
|
||||
CLNQ_ConnectionlessPacket ();
|
||||
#endif
|
||||
continue; //ignore it. We arn't connected.
|
||||
}
|
||||
|
||||
//
|
||||
// packet from server
|
||||
//
|
||||
if (!cls.demoplayback &&
|
||||
!NET_CompareAdr (&net_from, &cls.netchan.remote_address))
|
||||
{
|
||||
if (NET_WasSpecialPacket(cls.sockets))
|
||||
continue;
|
||||
Con_DPrintf ("%s:sequenced packet from wrong server\n"
|
||||
,NET_AdrToString(adr, sizeof(adr), &net_from));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cls.netchan.pext_stunaware) //should be safe to do this here.
|
||||
if (NET_WasSpecialPacket(cls.sockets))
|
||||
continue;
|
||||
|
||||
switch(cls.protocol)
|
||||
{
|
||||
case CP_NETQUAKE:
|
||||
#ifdef NQPROT
|
||||
if(NQNetChan_Process(&cls.netchan))
|
||||
{
|
||||
MSG_ChangePrimitives(cls.netchan.netprim);
|
||||
CL_WriteDemoMessage (&net_message, msg_readcount);
|
||||
CLNQ_ParseServerMessage ();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case CP_PLUGIN:
|
||||
break;
|
||||
case CP_QUAKE2:
|
||||
#ifdef Q2CLIENT
|
||||
if (!Netchan_Process(&cls.netchan))
|
||||
continue; // wasn't accepted for some reason
|
||||
CLQ2_ParseServerMessage ();
|
||||
break;
|
||||
#endif
|
||||
case CP_QUAKE3:
|
||||
#ifdef Q3CLIENT
|
||||
CLQ3_ParseServerMessage();
|
||||
#endif
|
||||
break;
|
||||
case CP_QUAKEWORLD:
|
||||
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
|
||||
{
|
||||
MSG_BeginReading(cls.netchan.netprim);
|
||||
cls.netchan.last_received = realtime;
|
||||
cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence;
|
||||
}
|
||||
else if (!Netchan_Process(&cls.netchan))
|
||||
continue; // wasn't accepted for some reason
|
||||
|
||||
CL_WriteDemoMessage (&net_message, msg_readcount);
|
||||
|
||||
if (cls.netchan.incoming_sequence > cls.netchan.outgoing_sequence)
|
||||
{ //server should not be responding to packets we have not sent yet
|
||||
Con_DPrintf("Server is from the future! (%i packets)\n", cls.netchan.incoming_sequence - cls.netchan.outgoing_sequence);
|
||||
cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence;
|
||||
}
|
||||
MSG_ChangePrimitives(cls.netchan.netprim);
|
||||
CLQW_ParseServerMessage ();
|
||||
break;
|
||||
case CP_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
// if (cls.demoplayback && cls.state >= ca_active && !CL_DemoBehind())
|
||||
// return;
|
||||
while(CL_GetDemoMessage())
|
||||
CL_ReadPacket();
|
||||
}
|
||||
else
|
||||
NET_ReadPackets(cls.sockets);
|
||||
NET_DTLS_Timeouts(cls.sockets);
|
||||
|
||||
//
|
||||
// check timeout
|
||||
|
|
|
@ -1246,6 +1246,7 @@ void CL_ClearState (qboolean gamestart);
|
|||
void CLQ2_ClearState(void);
|
||||
|
||||
void CL_ReadPackets (void);
|
||||
void CL_ReadPacket(void);
|
||||
|
||||
int CL_ReadFromServer (void);
|
||||
void CL_WriteToServer (usercmd_t *cmd);
|
||||
|
@ -1273,7 +1274,7 @@ int CL_RemoveClientCommands(char *command);
|
|||
// cl_demo.c
|
||||
//
|
||||
void CL_StopPlayback (void);
|
||||
qboolean CL_GetMessage (void);
|
||||
qboolean CL_GetDemoMessage (void);
|
||||
void CL_WriteDemoCmd (usercmd_t *pcmd);
|
||||
void CL_Demo_ClientCommand(char *commandtext); //for QTV.
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
#include "shader.h"
|
||||
#include "glquake.h" //we need some of the gl format enums
|
||||
|
||||
//#define PURGEIMAGES //somewhat experimental still. we're still flushing more than we should.
|
||||
|
||||
#if defined(NPFTE) || defined(IMGTOOL)
|
||||
//#define Con_Printf(f, ...)
|
||||
//hope you're on a littleendian machine
|
||||
|
@ -29,6 +27,14 @@ cvar_t r_dodgytgafiles = CVARD("r_dodgytgafiles", "0", "Many old glquake engines
|
|||
cvar_t r_dodgypcxfiles = CVARD("r_dodgypcxfiles", "0", "When enabled, this will ignore the palette stored within pcx files, for compatibility with quake2.");
|
||||
#endif
|
||||
cvar_t r_dodgymiptex = CVARD("r_dodgymiptex", "1", "When enabled, this will force regeneration of mipmaps, discarding mips1-4 like glquake did. This may eg solve fullbright issues with some maps, but may reduce distant detail levels.");
|
||||
static void QDECL R_Image_BuggyCvar (struct cvar_s *var, char *oldvalue)
|
||||
{ //force these cvars to value 1 if they're empty.
|
||||
//cvars using this should be changed to 0 by default, once our engine bugs are debugged/fixed.
|
||||
if (!*var->string)
|
||||
var->ival = true;
|
||||
}
|
||||
cvar_t r_keepimages = CVARCD("r_keepimages", "", R_Image_BuggyCvar, "Retain unused images in memory for slightly faster map loading. FIXME: a setting of 0 may be crashy! (empty is treated as 1 for now)");
|
||||
cvar_t r_ignoremapprefixes = CVARCD("r_ignoremapprefixes", "", R_Image_BuggyCvar, "Ignores when textures were loaded from map-specific paths. FIXME: empty is currently interpretted as 1 because the alternative is too memory hungary with r_keepimages 1.");
|
||||
|
||||
char *r_defaultimageextensions =
|
||||
#ifdef IMAGEFMT_DDS
|
||||
|
@ -13181,9 +13187,7 @@ image_t *Image_FindTexture(const char *identifier, const char *subdir, unsigned
|
|||
{
|
||||
if (!((tex->flags ^ flags) & (IF_CLAMP|IF_PALETTIZE|IF_PREMULTIPLYALPHA)))
|
||||
{
|
||||
#ifdef PURGEIMAGES
|
||||
if (!strcmp(subdir, tex->subpath?tex->subpath:""))
|
||||
#endif
|
||||
if (r_ignoremapprefixes.ival || !strcmp(subdir, tex->subpath?tex->subpath:""))
|
||||
{
|
||||
tex->regsequence = r_regsequence;
|
||||
return tex;
|
||||
|
@ -13423,7 +13427,7 @@ void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, in
|
|||
size_t i;
|
||||
|
||||
//skip if we're not actually changing the data/size/format.
|
||||
if (!data && tex->format == fmt && tex->width == width && tex->height == height && tex->depth == 1)
|
||||
if (!data && tex->format == fmt && tex->width == width && tex->height == height && tex->depth == 1 && tex->status == TEX_LOADED)
|
||||
return;
|
||||
|
||||
mips.extrafree = NULL;
|
||||
|
@ -13562,10 +13566,9 @@ void Image_DestroyTexture(image_t *tex)
|
|||
void Shader_TouchTextures(void);
|
||||
void Image_Purge(void)
|
||||
{
|
||||
#ifdef PURGEIMAGES
|
||||
image_t *tex, *a;
|
||||
int loaded = 0, total = 0;
|
||||
size_t mem = 0;
|
||||
image_t *tex;
|
||||
if (r_keepimages.ival)
|
||||
return;
|
||||
Shader_TouchTextures();
|
||||
for (tex = imagelist; tex; tex = tex->next)
|
||||
{
|
||||
|
@ -13574,7 +13577,6 @@ void Image_Purge(void)
|
|||
if (tex->regsequence != r_regsequence)
|
||||
Image_UnloadTexture(tex);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -13638,7 +13640,10 @@ void Image_List_f(void)
|
|||
imgmem = blockbytes * (tex->width+blockwidth-1)/blockwidth * (tex->height+blockheight-1)/blockheight;
|
||||
if (!(tex->flags & IF_NOMIPMAP))
|
||||
imgmem += imgmem/3; //mips take about a third extra mem.
|
||||
Con_Printf("^2loaded (%i*%i ^4%s^2, %3fKB->%3fKB)\n", tex->width, tex->height, Image_FormatName(tex->format), loc.len/(1024.0), imgmem/(1024.0));
|
||||
if (tex->depth != 1)
|
||||
Con_Printf("^2loaded (%i*%i*%i ^4%s^2, %3fKB->%3fKB)\n", tex->width, tex->height, tex->depth, Image_FormatName(tex->format), loc.len/(1024.0), imgmem/(1024.0));
|
||||
else
|
||||
Con_Printf("^2loaded (%i*%i ^4%s^2, %3fKB->%3fKB)\n", tex->width, tex->height, Image_FormatName(tex->format), loc.len/(1024.0), imgmem/(1024.0));
|
||||
if (tex->aliasof)
|
||||
{
|
||||
aliasedmem += imgmem;
|
||||
|
|
|
@ -167,7 +167,7 @@ static net_masterlist_t net_masterlist[] = {
|
|||
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "master.teamdamage.com:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "master.teamdamage.com"},
|
||||
|
||||
//Total conversions will need to define their own in defaults.cfg or whatever.
|
||||
{MP_DPMASTER, CVARFC("net_masterextra1", "frag-net.com:27950 198.58.111.37:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //admin: Eukara
|
||||
{MP_DPMASTER, CVARFC("net_masterextra1", "master.frag-net.com:27950 198.58.111.37:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //admin: Eukara
|
||||
// {MP_DPMASTER, CVARFC("net_masterextra1", ""/*"ghdigital.com:27950 207.55.114.154:27950"*/, CVAR_NOSAVE, Net_Masterlist_Callback)}, //(was 69.59.212.88) admin: LordHavoc
|
||||
{MP_DPMASTER, CVARFC("net_masterextra2", "dpmaster.deathmask.net:27950 107.161.23.68:27950 [2604:180::4ac:98c1]:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //admin: Willis
|
||||
{MP_DPMASTER, CVARFC("net_masterextra3", "dpmaster.tchr.no:27950 92.62.40.73:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //admin: tChr
|
||||
|
@ -2724,7 +2724,7 @@ void MasterInfo_Refresh(qboolean doreset)
|
|||
url = va("http://%s/raw/%s", fs_manifest->rtcbroker+6, com_token);
|
||||
else
|
||||
url = va("http://%s/raw/%s", fs_manifest->rtcbroker, com_token);
|
||||
Master_AddMasterHTTP(url, MT_MASTERHTTP, MP_QUAKEWORLD, "Public Servers Potentially Behind A NAT.");
|
||||
Master_AddMasterHTTP(url, MT_MASTERHTTP, MP_DPMASTER, "Public Servers Potentially Behind A NAT.");
|
||||
}
|
||||
|
||||
for (i = 0; net_masterlist[i].cv.name; i++)
|
||||
|
|
|
@ -327,6 +327,8 @@ cvar_t r_stereo_method = CVARFD("r_stereo_method", "0", CVAR_ARCHIVE, "Valu
|
|||
|
||||
extern cvar_t r_dodgytgafiles;
|
||||
extern cvar_t r_dodgypcxfiles;
|
||||
extern cvar_t r_keepimages;
|
||||
extern cvar_t r_ignoremapprefixes;
|
||||
extern cvar_t r_dodgymiptex;
|
||||
extern char *r_defaultimageextensions;
|
||||
extern cvar_t r_imageextensions;
|
||||
|
@ -865,6 +867,8 @@ void Renderer_Init(void)
|
|||
Cmd_AddCommand("sky", R_ForceSky_f); //QS compat
|
||||
Cmd_AddCommand("loadsky", R_ForceSky_f);//DP compat
|
||||
|
||||
Cvar_Register(&r_keepimages, GRAPHICALNICETIES);
|
||||
Cvar_Register(&r_ignoremapprefixes, GRAPHICALNICETIES);
|
||||
#ifdef IMAGEFMT_TGA
|
||||
Cvar_Register(&r_dodgytgafiles, "Hacky bug workarounds");
|
||||
#endif
|
||||
|
|
|
@ -885,7 +885,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, chanupdat
|
|||
else //we don't want to play anything more.
|
||||
break;
|
||||
if (!queuedbufs)
|
||||
{ //queue 0.1 secs if we're starting/resetting a new stream this is to try to cover up discintinuities caused by packetloss or whatever
|
||||
{ //queue 0.1 secs if we're starting/resetting a new stream this is to try to cover up discontinuities caused by packetloss or whatever
|
||||
sfxcache_t silence;
|
||||
silence.speed = snd_speed;
|
||||
silence.width = 2;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue