1
0
Fork 0
forked from fte/fteqw

make developer a little less spammy. move much of it to developer 2.

net_mtu "" now means something large for servers and something smaller for clients. this should give clients more freedom to screw up their connections as much as they want when servers are not configured. I dunno.
package manager now tries to include packages listed from default.fmf. note that this may include dlls etc so this isn't available for any other fmf (ie: ones specified via the commandline/file associations).
fix up trace logic to use skeletal data for skeletal models, finally fixing toneddu's big hitmodel crash. hopefully.
console links inherit background text colours, where possible.
fix text background colour weirdness for both freetype2 fonts and spaces.
qcc: implement support for mac line endings, matching scintilla's line numbers, although this breaks rogue due to stray carrage returns inside a single-line comment (easy to fix, assuming some scintilla-based editor, anyway).
server: reworked deltas overflow to do round-robin properly with priority for players, so things shouldn't stall when overloaded.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5067 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2017-03-04 19:36:06 +00:00
parent 1b88cda2db
commit 9aed521689
30 changed files with 432 additions and 220 deletions

View file

@ -1781,7 +1781,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
{
next = clientcmdlist->next;
CL_Demo_ClientCommand(clientcmdlist->command);
Con_DPrintf("Sending stringcmd %s\n", clientcmdlist->command);
Con_DLPrintf(2, "Sending stringcmd %s\n", clientcmdlist->command);
Z_Free(clientcmdlist);
clientcmdlist = next;
}
@ -1946,7 +1946,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
MSG_WriteString (&buf, clientcmdlist->command);
}
}
Con_DPrintf("Sending stringcmd %s\n", clientcmdlist->command);
Con_DLPrintf(2, "Sending stringcmd %s\n", clientcmdlist->command);
Z_Free(clientcmdlist);
clientcmdlist = next;
}

View file

@ -680,18 +680,23 @@ void CL_SendConnectPacket (netadr_t *to, int mtu,
Q_strncatz(data, va("0x%x 0x%x\n", PROTOCOL_VERSION_FTE2, fteprotextsupported2), sizeof(data));
#endif
if (mtu > 0)
{
int ourmtu;
if (to->type == NA_LOOPBACK)
mtu = MAX_UDP_PACKET;
else if (net_mtu.ival > 64 && mtu > net_mtu.ival)
mtu = net_mtu.ival;
mtu &= ~7;
Q_strncatz(data, va("0x%x %i\n", PROTOCOL_VERSION_FRAGMENT, mtu), sizeof(data));
connectinfo.mtu = mtu;
ourmtu = MAX_UDP_PACKET;
else if (*net_mtu.string)
ourmtu = net_mtu.ival;
else
ourmtu = 1440; //a safe bet. servers have an unsafe bet by default
if (ourmtu < 0)
ourmtu = 0;
if (mtu > ourmtu)
mtu = ourmtu;
connectinfo.mtu = mtu & ~7;
if (connectinfo.mtu > 0)
Q_strncatz(data, va("0x%x %i\n", PROTOCOL_VERSION_FRAGMENT, connectinfo.mtu), sizeof(data));
}
else
connectinfo.mtu = 0;
#ifdef HUFFNETWORK
if (compressioncrc && net_compress.ival && Huff_CompressionCRC(compressioncrc))
@ -5665,6 +5670,9 @@ void Host_FinishLoading(void)
IPLog_Merge_File("iplog.dat"); //legacy crap, for compat with proquake
}
if (PM_IsApplying(true))
return;
#ifdef ANDROID
//android needs to wait a bit longer before it's allowed to init its video properly.
extern int sys_glesversion;

View file

@ -6203,7 +6203,7 @@ void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from n
while((msg = strchr(stufftext, '\n')))
{
*msg = '\0';
Con_DPrintf("stufftext: %s\n", stufftext);
Con_DLPrintf((cls.state==ca_active)?1:2, "stufftext: %s\n", stufftext);
if (!strncmp(stufftext, "fullserverinfo ", 15))
{
Cmd_ExecuteString(stufftext, RESTRICT_SERVER+destsplit); //do this NOW so that it's done before any models or anything are loaded

View file

@ -1067,7 +1067,7 @@ static void Con_DPrintFromThread (void *ctx, void *data, size_t a, size_t b)
{
if (log_developer.ival)
Con_Log(data);
if (developer.ival)
if (developer.ival >= (int)a)
{
Sys_Printf ("%s", (const char*)data); // also echo to debugging console
Con_PrintCon(&con_main, data, con_main.parseflags);
@ -1103,7 +1103,7 @@ void VARGS Con_DPrintf (const char *fmt, ...)
if (!Sys_IsMainThread())
{
COM_AddWork(WG_MAIN, Con_DPrintFromThread, NULL, Z_StrDup(msg), 0, 0);
COM_AddWork(WG_MAIN, Con_DPrintFromThread, NULL, Z_StrDup(msg), 1, 0);
return;
}
@ -1116,6 +1116,42 @@ void VARGS Con_DPrintf (const char *fmt, ...)
Con_PrintCon(&con_main, msg, con_main.parseflags);
}
}
void VARGS Con_DLPrintf (int level, const char *fmt, ...)
{
va_list argptr;
char msg[MAXPRINTMSG];
#ifdef CRAZYDEBUGGING
va_start (argptr,fmt);
vsnprintf (msg,sizeof(msg)-1, fmt,argptr);
va_end (argptr);
Sys_Printf("%s", msg);
return;
#else
if (developer.ival<level && !log_developer.ival)
return; // early exit
#endif
va_start (argptr,fmt);
vsnprintf (msg,sizeof(msg)-1, fmt,argptr);
va_end (argptr);
if (!Sys_IsMainThread())
{
COM_AddWork(WG_MAIN, Con_DPrintFromThread, NULL, Z_StrDup(msg), level, 0);
return;
}
if (log_developer.ival)
Con_Log(msg);
if (developer.ival >= level)
{
Sys_Printf ("%s", msg); // also echo to debugging console
if (con_initialized)
Con_PrintCon(&con_main, msg, con_main.parseflags);
}
}
/*description text at the bottom of the console*/
void Con_Footerf(console_t *con, qboolean append, const char *fmt, ...)

View file

@ -180,7 +180,7 @@ static qboolean loadedinstalled;
static package_t *availablepackages;
static int numpackages;
static char *manifestpackage; //metapackage named by the manicfest.
static qboolean domanifestinstall;
static int domanifestinstall; //SECURITY_MANIFEST_*
static qboolean doautoupdate; //updates will be marked (but not applied without the user's actions)
@ -1211,6 +1211,23 @@ static unsigned int PM_MarkUpdates (void)
{
unsigned int changecount = 0;
package_t *p, *o, *b, *e = NULL;
if (manifestpackage)
{
p = PM_MarkedPackage(manifestpackage);
if (!p)
{
p = PM_FindPackage(manifestpackage);
if (p)
{
PM_MarkPackage(p);
changecount++;
}
}
else if (!(p->flags & DPF_PRESENT))
changecount++;
}
for (p = availablepackages; p; p = p->next)
{
if ((p->flags & DPF_ENGINE) && !(p->flags & DPF_HIDDEN))
@ -1318,38 +1335,40 @@ static void PM_ListDownloaded(struct dl_download *dl)
if (!downloadablelist[i].received)
break;
}
if (domanifestinstall)
if (domanifestinstall == MANIFEST_SECURITY_INSTALLER)
{
package_t *meta;
meta = PM_MarkedPackage(manifestpackage);
if (!meta)
meta = PM_FindPackage(manifestpackage);
if (meta)
{
PM_RevertChanges();
PM_MarkPackage(meta);
PM_ApplyChanges();
meta = PM_FindPackage(manifestpackage);
if (meta)
{
PM_RevertChanges();
PM_MarkPackage(meta);
PM_ApplyChanges();
#ifdef DOWNLOADMENU
if (!isDedicated)
{
if (Key_Dest_Has(kdm_emenu))
if (!isDedicated)
{
Key_Dest_Remove(kdm_emenu);
m_state = m_none;
}
if (Key_Dest_Has(kdm_emenu))
{
Key_Dest_Remove(kdm_emenu);
m_state = m_none;
}
#ifdef MENU_DAT
if (Key_Dest_Has(kdm_gmenu))
MP_Toggle(0);
if (Key_Dest_Has(kdm_gmenu))
MP_Toggle(0);
#endif
Cmd_ExecuteString("menu_download\n", RESTRICT_LOCAL);
Cmd_ExecuteString("menu_download\n", RESTRICT_LOCAL);
}
}
#endif
return;
return;
}
}
}
if (doautoupdate && i == numdownloadablelists)
if ((doautoupdate || domanifestinstall == MANIFEST_SECURITY_DEFAULT) && i == numdownloadablelists)
{
if (PM_MarkUpdates())
{
@ -1863,15 +1882,18 @@ static char *PM_GetTempName(package_t *p)
p->previewimage = NULL;
}*/
int PM_IsApplying(void)
int PM_IsApplying(qboolean listsonly)
{
package_t *p;
int count = 0;
int i;
for (p = availablepackages; p ; p=p->next)
if (!listsonly)
{
if (p->download)
count++;
for (p = availablepackages; p ; p=p->next)
{
if (p->download)
count++;
}
}
for (i = 0; i < numdownloadablelists; i++)
{
@ -1887,10 +1909,10 @@ static void PM_StartADownload(void)
vfsfile_t *tmpfile;
char *temp;
package_t *p;
const int simultaneous = 1;
const int simultaneous = PM_IsApplying(true)?1:2;
int i;
for (p = availablepackages; p && simultaneous > PM_IsApplying(); p=p->next)
for (p = availablepackages; p && simultaneous > PM_IsApplying(false); p=p->next)
{
if (p->trymirrors)
{ //flagged for a (re?)download
@ -2096,14 +2118,14 @@ static void PM_ApplyChanges(void)
//names packages that were listed from the manifest.
//if 'mark' is true, then this is an initial install.
void PM_ManifestPackage(const char *metaname, qboolean mark)
void PM_ManifestPackage(const char *metaname, int security)
{
domanifestinstall = mark;
domanifestinstall = security;
Z_Free(manifestpackage);
if (metaname)
{
manifestpackage = Z_StrDup(metaname);
if (mark)
if (security)
PM_UpdatePackageList(false, false);
}
else

View file

@ -1259,11 +1259,8 @@ void M_Shutdown(qboolean total)
#ifdef MENU_DAT
MP_Shutdown();
#endif
if (total)
{
M_RemoveAllMenus(false);
M_DeInit_Internal();
}
M_RemoveAllMenus(!total);
M_DeInit_Internal();
}
void M_Reinit(void)

View file

@ -2679,7 +2679,7 @@ void MP_CoreDump_f(void)
void MP_Reload_f(void)
{
M_Shutdown(true);
M_Shutdown(false);
M_Reinit();
}

View file

@ -771,13 +771,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define ON_EPSILON 0.1 // point on plane side epsilon
#define MAX_NQMSGLEN 65536 // max length of a reliable message
#define MAX_NQMSGLEN 65536 // max length of a reliable message. FIXME: should be 8000 to play safe with proquake
#define MAX_Q2MSGLEN 1400
#define MAX_QWMSGLEN 1450
#define MAX_OVERALLMSGLEN 65536 // mvdsv sends packets this big
#define MAX_DATAGRAM 1450 // max length of unreliable message
#define MAX_Q2DATAGRAM MAX_Q2MSGLEN
#define MAX_NQDATAGRAM 1024 // max length of unreliable message
#define MAX_NQDATAGRAM 1024 // max length of unreliable message with vanilla nq protocol
#define MAX_OVERALLDATAGRAM MAX_DATAGRAM
#define MAX_BACKBUFLEN 1200

View file

@ -2296,9 +2296,9 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, framestate_t *framestate, v
indexes = mod->ofs_indexes;
#ifdef SKELETALMODELS
if (mod->numbones)
if (mod->ofs_skel_xyz)
{
if (!mod->ofs_skel_idx || !framestate)
if (!mod->ofs_skel_idx || !framestate || !mod->numbones)
posedata = mod->ofs_skel_xyz; //if there's no weights, don't try animating anything.
else if (mod->shares_verts != cursurfnum || !posedata)
{
@ -2330,6 +2330,8 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, framestate_t *framestate, v
if (!group->numposes)
continue;
pose = group->poseofs;
if (!pose)
continue; //error...
if (framestate)
pose += (int)(framestate->g[FS_REG].frametime[0] * group->rate)%group->numposes;
posedata = pose->ofsverts;
@ -7056,7 +7058,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, size_t fsi
}
else
fuckedevents = true; //we're not using the animation data from the model, so ignore any events because they won't make sense any more.
if (!numgroups)
if (!numgroups && !noweights && h->num_joints)
{ /*base frame only*/
numgroups = 1;
framegroups = malloc(sizeof(*framegroups));

View file

@ -116,6 +116,8 @@ typedef struct
unsigned int subframe;
bucket_t bucket;
} galiascolourmapped_t;
#else
typedef void galiasskin_t;
#endif
typedef struct
@ -145,20 +147,20 @@ typedef struct galiasinfo_s
float lerpcutoff; //hack. should probably be part of the entity structure, but I really don't want new models (and thus code) to have access to this ugly inefficient hack. make your models properly in the first place.
int numskins;
#ifndef SERVERONLY
//#ifndef SERVERONLY
galiasskin_t *ofsskins;
#endif
//#endif
int shares_verts; //used with models with two shaders using the same vertex. set to the surface number to inherit from (or itself).
int shares_bones; //use last mesh's bones. set to the surface number to inherit from (or itself).
int numverts;
#ifndef SERVERONLY
//#ifndef SERVERONLY
vec2_t *ofs_st_array;
vec4_t *ofs_rgbaf;
byte_vec4_t *ofs_rgbaub;
#endif
//#endif
int numanimations;
galiasanimation_t *ofsanimations;

View file

@ -3252,6 +3252,8 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
//preserved flags and reset to white. links must contain their own colours.
linkinitflags = ext;
ext = COLOR_RED << CON_FGSHIFT;
if (!(linkinitflags & CON_RICHFORECOLOUR))
ext |= linkinitflags & (CON_NONCLEARBG|CON_HALFALPHA|CON_BGMASK);
linkstart = out;
*out++ = '[';

View file

@ -600,7 +600,12 @@ enum manifestdeptype_e
typedef struct
{
qboolean blockupdate; //set to block the updateurl from being used this session. this avoids recursive updates when manifests contain the same update url.
qboolean doinstall; //manifest was embedded in the engine. don't assume its already installed, but ask to install it (also, enable some extra permissions for writing dlls)
enum
{
MANIFEST_SECURITY_NOT, //don't trust it, don't even allow downloadsurl.
MANIFEST_SECURITY_DEFAULT, //the default.fmf file may suggest packages
MANIFEST_SECURITY_INSTALLER //built-in fmf files can force packages
} security; //manifest was embedded in the engine. don't assume its already installed, but ask to install it (also, enable some extra permissions for writing dlls)
enum
{

View file

@ -225,7 +225,8 @@ void Con_CenterPrint(const char *txt);
void Con_PrintFlags(const char *text, unsigned int setflags, unsigned int clearflags);
void VARGS Con_Printf (const char *fmt, ...) LIKEPRINTF(1);
void VARGS Con_TPrintf (translation_t text, ...);
void VARGS Con_DPrintf (const char *fmt, ...) LIKEPRINTF(1);
void VARGS Con_DPrintf (const char *fmt, ...) LIKEPRINTF(1); //developer>=1, for stuff that's probably actually slightly useful
void VARGS Con_DLPrintf (int level, const char *fmt, ...) LIKEPRINTF(2); //developer>=2, for spammy stuff
void VARGS Con_SafePrintf (const char *fmt, ...) LIKEPRINTF(1);
void Con_Footerf(console_t *con, qboolean append, const char *fmt, ...) LIKEPRINTF(3);
void Con_Clear_f (void);

View file

@ -2977,14 +2977,14 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
FS_ChangeGame(man, cfg_reload_on_gamedir.ival, false);
}
#ifdef NOLEGACY
#if defined(NOLEGACY) || defined(SERVERONLY)
#define ZFIXHACK
#elif defined(ANDROID) //on android, these numbers seem to be generating major weirdness, so disable these.
#define ZFIXHACK
#elif defined(FTE_TARGET_WEB) //on firefox (but not chrome or ie), these numbers seem to be generating major weirdness, so tone them down significantly by default.
#define ZFIXHACK "r_polygonoffset_submodel_offset 1\nr_polygonoffset_submodel_factor 0.05\n"
#define ZFIXHACK "set r_polygonoffset_submodel_offset 1\nset r_polygonoffset_submodel_factor 0.05\n"
#else //many quake maps have hideous z-fighting. this provides a way to work around it, although the exact numbers are gpu and bitdepth dependant, and trying to fix it can actually break other things.
#define ZFIXHACK "r_polygonoffset_submodel_offset 25\nr_polygonoffset_submodel_factor 0.05\n"
#define ZFIXHACK "set r_polygonoffset_submodel_offset 25\nset r_polygonoffset_submodel_factor 0.05\n"
#endif
/*quake requires a few settings for compatibility*/
@ -4190,6 +4190,7 @@ static ftemanifest_t *FS_GenerateLegacyManifest(char *newbasedir, int sizeof_new
FS_Manifest_ParseTokens(man);
}
}
man->security = MANIFEST_SECURITY_INSTALLER;
return man;
}
@ -4290,7 +4291,7 @@ static char fspdl_finalpath[MAX_OSPATH];
static void FS_BeginNextPackageDownload(void);
qboolean FS_DownloadingPackage(void)
{
if (PM_IsApplying())
if (PM_IsApplying(false))
return true;
return !fs_manifest || !!curpackagedownload;
}
@ -4718,7 +4719,7 @@ static void FS_BeginNextPackageDownload(void)
if (curpackagedownload || !man || com_installer)
return;
if (man->doinstall)
if (man->security != MANIFEST_SECURITY_NOT)
{
for (j = 0; j < sizeof(fs_manifest->package) / sizeof(fs_manifest->package[0]); j++)
{
@ -4824,7 +4825,7 @@ static void FS_ManifestUpdated(struct dl_download *dl)
void FS_BeginManifestUpdates(void)
{
ftemanifest_t *man = fs_manifest;
PM_ManifestPackage(man->installupd, man->doinstall);
PM_ManifestPackage(man->installupd, man->security);
if (curpackagedownload || !man)
return;
@ -4877,6 +4878,7 @@ ftemanifest_t *FS_ReadDefaultManifest(char *newbasedir, size_t newbasedirsize, q
VFS_READ(f, fdata, len);
fdata[len] = 0;
man = FS_Manifest_Parse(NULL, fdata);
man->security = MANIFEST_SECURITY_DEFAULT;
BZ_Free(fdata);
}
VFS_CLOSE(f);
@ -4900,7 +4902,7 @@ ftemanifest_t *FS_ReadDefaultManifest(char *newbasedir, size_t newbasedirsize, q
{
man = FS_Manifest_Parse(va("%sdefault.fmf", newbasedir), host_parms.manifest);
if (man)
man->doinstall = true;
man->security = MANIFEST_SECURITY_INSTALLER;
}
if (!man)
@ -5047,7 +5049,7 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
}
fs_manifest = man;
if (!man->doinstall && strcmp(man->downloadsurl?man->downloadsurl:"", olddownloadsurl?olddownloadsurl:""))
if (man->security == MANIFEST_SECURITY_NOT && strcmp(man->downloadsurl?man->downloadsurl:"", olddownloadsurl?olddownloadsurl:""))
{ //make sure we only fuck over the user if this is a 'secure' manifest, and not hacked in some way.
Z_Free(man->downloadsurl);
man->downloadsurl = olddownloadsurl;
@ -5094,7 +5096,7 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
builtingame = true;
if (!fixedbasedir && !FS_DirHasGame(newbasedir, i))
if (Sys_FindGameData(man->formalname, man->installation, realpath, sizeof(realpath), !man->doinstall) && FS_FixPath(realpath, sizeof(realpath)) && FS_DirHasGame(realpath, i))
if (Sys_FindGameData(man->formalname, man->installation, realpath, sizeof(realpath), man->security != MANIFEST_SECURITY_INSTALLER) && FS_FixPath(realpath, sizeof(realpath)) && FS_DirHasGame(realpath, i))
Q_strncpyz (newbasedir, realpath, sizeof(newbasedir));
break;
}
@ -5105,7 +5107,7 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
{
if (!builtingame && !fixedbasedir && !FS_DirHasAPackage(newbasedir, man))
{
if (Sys_FindGameData(man->formalname, man->installation, realpath, sizeof(realpath), !man->doinstall) && FS_FixPath(realpath, sizeof(realpath)) && FS_DirHasAPackage(realpath, man))
if (Sys_FindGameData(man->formalname, man->installation, realpath, sizeof(realpath), man->security != MANIFEST_SECURITY_INSTALLER) && FS_FixPath(realpath, sizeof(realpath)) && FS_DirHasAPackage(realpath, man))
Q_strncpyz (newbasedir, realpath, sizeof(newbasedir));
#ifndef SERVERONLY
else
@ -5279,7 +5281,7 @@ void FS_CreateBasedir(const char *path)
com_installer = false;
Q_strncpyz (com_gamepath, path, sizeof(com_gamepath));
COM_CreatePath(com_gamepath);
fs_manifest->doinstall = true;
fs_manifest->security = MANIFEST_SECURITY_INSTALLER;
FS_ChangeGame(fs_manifest, true, false);
if (host_parms.manifest)

View file

@ -68,7 +68,7 @@ void FS_UnRegisterFileSystemModule(void *module);
void FS_AddHashedPackage(searchpath_t **oldpaths, const char *parent_pure, const char *parent_logical, searchpath_t *search, unsigned int loadstuff, const char *pakpath, const char *qhash, const char *pakprefix);
void PM_LoadPackages(searchpath_t **oldpaths, const char *parent_pure, const char *parent_logical, searchpath_t *search, unsigned int loadstuff, int minpri, int maxpri);
int PM_IsApplying(void);
int PM_IsApplying(qboolean listsonly);
void PM_ManifestPackage(const char *name, qboolean doinstall);
qboolean PM_FindUpdatedEngine(char *syspath, size_t syspathsize); //names the engine we should be running
void Menu_Download_Update(void);

View file

@ -811,7 +811,7 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
e = NET_SendPacket (chan->sock, (no - offset) + hsz, send.data + offset, &chan->remote_address);
if (e == NETERR_MTU && !offset && chan->fragmentsize > 560)
{
chan->fragmentsize -= 10;
chan->fragmentsize -= 16;
Con_Printf("Reducing MSS to %i\n", chan->fragmentsize);
no = offset;
more = true;

View file

@ -248,6 +248,7 @@ static fontplanes_t fontplanes;
#define FONT_CHAR_BUFFER 512
static index_t font_indicies[FONT_CHAR_BUFFER*6];
static vecV_t font_coord[FONT_CHAR_BUFFER*4];
static vecV_t font_backcoord[FONT_CHAR_BUFFER*4];
static vec2_t font_texcoord[FONT_CHAR_BUFFER*4];
static byte_vec4_t font_forecoloura[FONT_CHAR_BUFFER*4];
static byte_vec4_t font_backcoloura[FONT_CHAR_BUFFER*4];
@ -338,7 +339,7 @@ void Font_Init(void)
font_foremesh.colors4b_array = font_forecoloura;
font_backmesh.indexes = font_indicies;
font_backmesh.xyz_array = font_coord;
font_backmesh.xyz_array = font_backcoord;
font_backmesh.st_array = font_texcoord;
font_backmesh.colors4b_array = font_backcoloura;
@ -400,7 +401,7 @@ static void Font_Flush(void)
fontplanes.planechanged = false;
}
font_foremesh.istrifan = (font_foremesh.numvertexes == 4);
if ((font_colourmask & CON_NONCLEARBG) && font_foremesh.numindexes)
if ((font_colourmask & (CON_RICHFORECOLOUR|CON_NONCLEARBG)) == CON_NONCLEARBG && font_foremesh.numindexes)
{
font_backmesh.numindexes = font_foremesh.numindexes;
font_backmesh.numvertexes = font_foremesh.numvertexes;
@ -1872,7 +1873,7 @@ int Font_DrawChar(int px, int py, unsigned int charflags, unsigned int codepoint
if (codepoint == '\t')
return Font_TabWidth(px);
if (codepoint == ' ')
if (codepoint == ' ' && (charflags & (CON_RICHFORECOLOUR|CON_NONCLEARBG)) != CON_NONCLEARBG)
return nextx;
/* if (charcode & CON_BLINKTEXT)
@ -2052,10 +2053,29 @@ int Font_DrawChar(int px, int py, unsigned int charflags, unsigned int codepoint
*(int*)font_forecoloura[v+1] = *(int*)font_forecolour;
*(int*)font_forecoloura[v+2] = *(int*)font_forecolour;
*(int*)font_forecoloura[v+3] = *(int*)font_forecolour;
*(int*)font_backcoloura[v+0] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+1] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+2] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+3] = *(int*)font_backcolour;
if (font_colourmask & CON_NONCLEARBG)
{
sx = ((px+dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
sw = sx + ((c->advance)*vid.width) / (float)vid.rotpixelwidth;
sh = sy + ((font->charheight)*vid.height) / (float)vid.rotpixelheight;
//don't care about texcoords
font_backcoord[v+0][0] = sx;
font_backcoord[v+0][1] = sy;
font_backcoord[v+1][0] = sw;
font_backcoord[v+1][1] = sy;
font_backcoord[v+2][0] = sw;
font_backcoord[v+2][1] = sh;
font_backcoord[v+3][0] = sx;
font_backcoord[v+3][1] = sh;
*(int*)font_backcoloura[v+0] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+1] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+2] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+3] = *(int*)font_backcolour;
}
return nextx;
}
@ -2102,7 +2122,7 @@ float Font_DrawScaleChar(float px, float py, unsigned int charflags, unsigned in
nextx = px + c->advance*cw;
if (codepoint == ' ')
if (codepoint == ' ' && (charflags & (CON_RICHFORECOLOUR|CON_NONCLEARBG)) != CON_NONCLEARBG)
return nextx;
if (charflags & CON_BLINKTEXT)
@ -2261,10 +2281,34 @@ float Font_DrawScaleChar(float px, float py, unsigned int charflags, unsigned in
*(int*)font_forecoloura[v+1] = *(int*)font_forecolour;
*(int*)font_forecoloura[v+2] = *(int*)font_forecolour;
*(int*)font_forecoloura[v+3] = *(int*)font_forecolour;
*(int*)font_backcoloura[v+0] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+1] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+2] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+3] = *(int*)font_backcolour;
if (font_colourmask & CON_NONCLEARBG)
{
sx = px + dxbias;
sy = py + dxbias;
sw = sx + c->advance;
sh = sy + font->charheight;
sx *= (int)vid.width / (float)vid.rotpixelwidth;
sy *= (int)vid.height / (float)vid.rotpixelheight;
sw *= (int)vid.width / (float)vid.rotpixelwidth;
sh *= (int)vid.height / (float)vid.rotpixelheight;
//don't care about texcoords
font_backcoord[v+0][0] = sx;
font_backcoord[v+0][1] = sy;
font_backcoord[v+1][0] = sw;
font_backcoord[v+1][1] = sy;
font_backcoord[v+2][0] = sw;
font_backcoord[v+2][1] = sh;
font_backcoord[v+3][0] = sx;
font_backcoord[v+3][1] = sh;
*(int*)font_backcoloura[v+0] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+1] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+2] = *(int*)font_backcolour;
*(int*)font_backcoloura[v+3] = *(int*)font_backcolour;
}
return nextx;
}

View file

@ -649,7 +649,7 @@ void Mod_Purge(enum mod_purge_e ptype)
}
if (unused)
Con_DPrintf("model \"%s\" no longer needed\n", mod->name);
Con_DLPrintf(2, "model \"%s\" no longer needed\n", mod->name);
#ifdef TERRAIN
//we can safely flush all terrain sections at any time

View file

@ -111,6 +111,7 @@ extern int qcc_eof;
#define qcc_iswhite(c) ((c) == ' ' || (c) == '\r' || (c) == '\n' || (c) == '\t' || (c) == '\v')
#define qcc_iswhitesameline(c) ((c) == ' ' || (c) == '\t')
#define qcc_islineending(c,n) ((c) == '\n' || ((c) == '\r' && (n) != '\n')) //to try to handle mac line endings, especially if they're in the middle of a line
enum

View file

@ -749,6 +749,7 @@ enum {
WARN_FTE_SPECIFIC, //extension that only FTEQCC will have a clue about.
WARN_EXTENSION_USED, //extension that frikqcc also understands
WARN_IFSTRING_USED,
WARN_IFVECTOR_DISABLED, //if(vector) does if(vector_x) if ifvector is disabled
WARN_LAXCAST, //some errors become this with a compiler flag
WARN_TYPEMISMATCHREDECOPTIONAL,
WARN_UNDESIRABLECONVENTION,

View file

@ -1679,6 +1679,8 @@ QCC_sref_t QCC_MakeSRefForce(QCC_def_t *def, unsigned int ofs, QCC_type_t *type)
QCC_sref_t QCC_MakeSRef(QCC_def_t *def, unsigned int ofs, QCC_type_t *type);
//we're about to overwrite the given def, so if there's any aliases to it, we need to clear them out.
//if def == NULL, then clobber all.
//def should never be a temp...
static void QCC_ClobberDef(QCC_def_t *def)
{
QCC_def_t *a, **link;
@ -1708,7 +1710,7 @@ static void QCC_ClobberDef(QCC_def_t *def)
statements[st].c.sym = a->generatedfor;
}
tmp.sym->refcount = a->symbolheader->refcount;
a->symbolheader = tmp.sym;
a->symbolheader = tmp.sym; //the alias now refers to a temp
from = QCC_MakeSRefForce(a->generatedfor, 0, a->type);
a->generatedfor = tmp.sym;
a->name = tmp.sym->name;
@ -1736,6 +1738,7 @@ static QCC_sref_t QCC_GetAliasTemp(QCC_sref_t ref)
def->name = ref.sym->name;
def->referenced = true;
def->fromstatement = numstatements;
def->scope = pr_scope;
//allaliases allows them to be finalized correctly
def->strip = true;
@ -1831,6 +1834,7 @@ void QCC_FinaliseTemps(void)
//finalize alises so they map correctly.
while(allaliases)
{
allaliases->symbolheader = allaliases->generatedfor->symbolheader;
allaliases->ofs = allaliases->generatedfor->ofs;
allaliases = allaliases->next;
}
@ -1948,7 +1952,7 @@ static QCC_def_t *QCC_MakeLocked(gofs_t tofs, gofs_t tsize, QCC_def_t *tmp)
for (link = &allaliases; *link;)
{
a = *link;
if (a->generatedfor == tmp)
if (a->generatedfor == tmp && a->scope == pr_scope)
{
// *link = a->next;
// a->next = NULL;
@ -4079,9 +4083,6 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
if (!pr_scope)
QCC_PR_ParseError(ERR_BADEXTENSION, "Unable to generate statements at global scope.\n");
if (outstatement)
QCC_ClobberDef(NULL);
if (op->type_c == &type_void || op->associative==ASSOC_RIGHT || op->type_c == NULL)
{
QCC_FreeTemp(var_b); //returns a instead of some result/temp
@ -4094,6 +4095,9 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
QCC_FreeTemp(var_b);
}
if (outstatement)
QCC_ClobberDef(NULL);
statement = &statements[numstatements++];
if (outstatement)
@ -9573,7 +9577,10 @@ QCC_statement_t *QCC_Generate_OP_IFNOT(QCC_sref_t e, pbool preserve)
op = OP_IF_I;
}
else
{
QCC_PR_ParseWarning(WARN_IFVECTOR_DISABLED, "if (vector) tests only the first element with the current compiler flags");
op = OP_IFNOT_I;
}
break;
case ev_variant:
@ -11578,6 +11585,7 @@ void QCC_WriteGUIAsmFunction(QCC_function_t *sc, unsigned int firststatement)
for (i = firststatement; i < (unsigned int)numstatements; i++)
{
line[0] = 0;
// QC_snprintfz(line, sizeof(line), "%i ", QCC_VarAtOffset(statements[i].a));
QC_strlcat(line, pr_opcodes[statements[i].op].opname, sizeof(line));
if (pr_opcodes[statements[i].op].type_a != &type_void)
{

View file

@ -2223,7 +2223,7 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor)
// skip whitespace
while ((c = *pr_file_p) && qcc_iswhite(c))
{
if (c=='\n')
if (qcc_islineending(c, pr_file_p[1]))
{
pr_file_p++;
if (!inhibitpreprocessor)
@ -2242,10 +2242,10 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor)
// skip // comments
if (c=='/' && pr_file_p[1] == '/')
{
while (*pr_file_p && *pr_file_p != '\n')
while (*pr_file_p && !qcc_islineending(pr_file_p[0], pr_file_p[1]))
pr_file_p++;
if (*pr_file_p == '\n')
if (*pr_file_p)
pr_file_p++; //don't break on eof.
if (!inhibitpreprocessor)
QCC_PR_NewLine(false);
@ -2261,7 +2261,7 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor)
do
{
pr_file_p++;
if (pr_file_p[0]=='\n')
if (qcc_islineending(pr_file_p[0], pr_file_p[1]))
{
if (!inhibitpreprocessor)
QCC_PR_NewLine(true);

View file

@ -716,21 +716,6 @@ int GUI_BuildParms(char *args, char **argv, pbool quick)//, char *forceoutputfil
paramlen += strlen(param+paramlen)+1;
}
while(*args)
{
while (*args <= ' '&& *args)
args++;
for (next = args; *next>' '; next++)
;
strncpy(param+paramlen, args, next-args);
param[paramlen+next-args] = '\0';
argv[argc++] = param+paramlen;
paramlen += strlen(param+paramlen)+1;
args=next;
}
targ = 0;
targ |= fl_hexen2?1:0;
targ |= fl_ftetarg?2:0;
@ -796,5 +781,20 @@ int GUI_BuildParms(char *args, char **argv, pbool quick)//, char *forceoutputfil
argv[argc++] = progssrcdir;
}
while(*args)
{
while (*args <= ' '&& *args)
args++;
for (next = args; *next>' '; next++)
;
strncpy(param+paramlen, args, next-args);
param[paramlen+next-args] = '\0';
argv[argc++] = param+paramlen;
paramlen += strlen(param+paramlen)+1;
args=next;
}
return argc;
}

View file

@ -26,6 +26,12 @@ extern int optres_test2;
pbool writeasm;
pbool verbose;
#define VERBOSE_STANDARD 1
#define VERBOSE_FILELIST 2
#define VERBOSE_FIELDLIST 2
#define VERBOSE_AUTOCVARLIST 2
#define VERBOSE_DEBUG 3
#define VERBOSE_DEBUGSTATEMENTS 4 //figuring out the files can be expensive.
pbool qcc_nopragmaoptimise;
pbool opt_stripunusedfields;
extern unsigned int locals_marshalled;
@ -1036,7 +1042,7 @@ void QCC_FinaliseDef(QCC_def_t *def)
if (!def->symbolheader->used)
{
if (verbose >= 3)
if (verbose >= VERBOSE_DEBUG)
printf("not needed: %s\n", def->name);
return;
}
@ -1105,7 +1111,7 @@ void QCC_UnmarshalLocals(void)
#endif
for (d = functions[i].firstlocal; d; d = d->nextlocal)
QCC_FinaliseDef(d);
if (verbose >= 3)
if (verbose >= VERBOSE_DEBUG)
{
if (onum == numpr_globals)
printf("code: %s:%i: function %s no private locals\n", functions[i].filen, functions[i].line, functions[i].name);
@ -1127,7 +1133,7 @@ void QCC_UnmarshalLocals(void)
if (biggest < numpr_globals)
biggest = numpr_globals;
if (verbose >= 3)
if (verbose >= VERBOSE_DEBUG)
{
if (onum == numpr_globals)
printf("code: %s:%i: function %s no locals\n", functions[i].filen, functions[i].line, functions[i].name);
@ -1194,6 +1200,22 @@ static void QCC_GenerateFieldDefs(QCC_def_t *def, char *fieldname, int ofs, QCC_
dd->s_name = sname;
}
char *QCC_FileForStatement(int st)
{
char *ret = "???";
int i;
for (i = 0; i < numfunctions; i++)
{
if (functions[i].code > 0)
{
if (st < functions[i].code)
break;
ret = functions[i].filen;
}
}
return ret;
}
CompilerConstant_t *QCC_PR_CheckCompConstDefined(char *def);
pbool QCC_WriteData (int crc)
@ -1469,9 +1491,11 @@ pbool QCC_WriteData (int crc)
if (funcs[i].locals && !funcs[i].parm_start)
QCC_PR_Warning(0, strings + funcs[i].s_file, functions[i].line, "%s:%i: func %s @%i locals@%i+%i, %i parms\n", functions[i].filen, functions[i].line, strings+funcs[i].s_name, funcs[i].first_statement, funcs[i].parm_start, funcs[i].locals, funcs[i].numparms);
#ifdef DEBUG_DUMP
printf("code: %s:%i: func %s @%i locals@%i+%i, %i parms\n", functions[i].file, functions[i].line, strings+funcs[i].s_named, funcs[i].first_statement, funcs[i].parm_start, funcs[i].locals, funcs[i].numparms);
#endif
if (verbose >= VERBOSE_DEBUG)
{
printf("code: %s:%i: func %s @%i locals@%i+%i, %i parms\n", functions[i].filen, functions[i].line, strings+funcs[i].s_name, funcs[i].first_statement, funcs[i].parm_start, funcs[i].locals, funcs[i].numparms);
printf("code: %s:%i: (%i,%i,%i,%i,%i,%i,%i,%i)\n", functions[i].filen, functions[i].line, funcs[i].parm_size[0], funcs[i].parm_size[1], funcs[i].parm_size[2], funcs[i].parm_size[3], funcs[i].parm_size[4], funcs[i].parm_size[5], funcs[i].parm_size[6], funcs[i].parm_size[7]);
}
}
funcdata = funcs;
funcdatasize = numfunctions*sizeof(*funcs);
@ -1844,9 +1868,8 @@ strofs = (strofs+3)&~3;
statements32[i].b = PRLittleLong((statements[i].b.sym?statements[i].b.sym->ofs:0) + statements[i].b.ofs);
statements32[i].c = PRLittleLong((statements[i].c.sym?statements[i].c.sym->ofs:0) + statements[i].c.ofs);
#ifdef DEBUG_DUMP
printf("code: %s:%i: @%i %s %i %i %i\n", "???", statements[i].linenum, i, pr_opcodes[statements[i].op].name, statements32[i].a, statements32[i].b, statements32[i].c);
#endif
if (verbose >= VERBOSE_DEBUGSTATEMENTS)
printf("code: %s:%i: @%i %s %i %i %i\n", QCC_FileForStatement(i), statements[i].linenum, i, pr_opcodes[statements[i].op].name, statements32[i].a, statements32[i].b, statements32[i].c);
}
if (progs.blockscompressed&1)
@ -1913,19 +1936,22 @@ strofs = (strofs+3)&~3;
unsigned int c = (statements[i].c.sym?statements[i].c.sym->ofs:0) + statements[i].c.ofs;
statements16[i].op = PRLittleShort((unsigned short)statements[i].op);
#if defined(DISASM) && !defined(DEBUG_DUMP)
if (i >= start && i < end)
if (
#if defined(DISASM)
(i >= start && i < end) ||
#endif
#if defined(DEBUG_DUMP) || defined(DISASM)
verbose >= VERBOSE_DEBUGSTATEMENTS)
{
char line[2048];
char *astr = statements[i].a.sym?statements[i].a.sym->name:"";
char *bstr = statements[i].b.sym?statements[i].b.sym->name:"";
char *cstr = statements[i].c.sym?statements[i].c.sym->name:"";
printf("code: %s:%i: @%i\t%s\t%i\t%i\t%i\t(%s", "???", statements[i].linenum, i, pr_opcodes[statements[i].op].opname, a, b, c, QCC_VarAtOffset(statements[i].a, 1));
printf(" %s", QCC_VarAtOffset(statements[i].b, 1));
printf(" %s)\n", QCC_VarAtOffset(statements[i].c, 1));
QC_snprintfz(line, sizeof(line), "code: %s:%i: @%i %s t%i t%i %i (%s", QCC_FileForStatement(i), statements[i].linenum, i, pr_opcodes[statements[i].op].opname, a, b, c, QCC_VarAtOffset(statements[i].a));
QC_snprintfz(line+strlen(line), sizeof(line)-strlen(line), " %s", QCC_VarAtOffset(statements[i].b));
QC_snprintfz(line+strlen(line), sizeof(line)-strlen(line), " %s)\n", QCC_VarAtOffset(statements[i].c));
printf("%s", line);
}
#endif
#ifdef _DEBUG
if (((signed)a >= (signed)numpr_globals && statements[i].a.sym) || ((signed)b >= (signed)numpr_globals && statements[i].b.sym) || ((signed)c >= (signed)numpr_globals && statements[i].c.sym))
printf("invalid offset on %s instruction\n", pr_opcodes[statements[i].op].opname);
@ -1977,13 +2003,13 @@ strofs = (strofs+3)&~3;
else
SafeWrite (h, funcdata, funcdatasize);
if (verbose >= 2)
if (verbose >= VERBOSE_FILELIST)
QCC_PrintFiles();
if (verbose >= 2)
if (verbose >= VERBOSE_FIELDLIST)
QCC_PrintFields();
if (verbose >= 2)
if (verbose >= VERBOSE_AUTOCVARLIST)
QCC_PrintAutoCvars();
switch(outputsttype)

View file

@ -1095,7 +1095,7 @@ progsnum_t AddProgs(const char *name)
Q_strncpyz(gamedir, loc.search->purepath, sizeof(gamedir));
*COM_SkipPath(gamedir) = 0;
}
Con_TPrintf("Loaded progs %s%s\n", gamedir, name);
Con_DPrintf("Loaded progs %s%s\n", gamedir, name);
PR_ProgsAdded(svprogfuncs, num, name);
@ -12555,47 +12555,44 @@ void PR_DumpPlatform_f(void)
VFS_PRINTF(f, "#endif\n");
}
if (accessors)
{
VFS_PRINTF(f, "#ifdef _ACCESSORS\n");
VFS_PRINTF(f,
"accessor strbuf : float\n{\n"
"\tinline get float asfloat[float idx] = {return stof(bufstr_get(this, idx));};\n"
"\tinline set float asfloat[float idx] = {bufstr_set(this, idx, ftos(value));};\n"
"\tget string[float] = bufstr_get;\n"
"\tset string[float] = bufstr_set;\n"
"\tget float length = buf_getsize;\n"
"};\n");
VFS_PRINTF(f,
"accessor searchhandle : float\n{\n"
"\tget string[float] = search_getfilename;\n"
"\tget float length = search_getsize;\n"
"};\n");
VFS_PRINTF(f,
"accessor hashtable : float\n{\n"
"\tinline get vector v[string key] = {return hash_get(this, key, '0 0 0', EV_VECTOR);};\n"
"\tinline set vector v[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_VECTOR);};\n"
"\tinline get string s[string key] = {return hash_get(this, key, \"\", EV_STRING);};\n"
"\tinline set string s[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_STRING);};\n"
"\tinline get string f[string key] = {return hash_get(this, key, 0.0, EV_FLOAT);};\n"
"\tinline set string f[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_FLOAT);};\n"
"\tinline get __variant[string key] = {return hash_get(this, key, __NULL__);};\n"
"\tinline set __variant[string key] = {hash_add(this, key, value, HASH_REPLACE);};\n"
"};\n");
VFS_PRINTF(f,
"accessor infostring : string\n{\n"
"\tget string[string] = infoget;\n"
VFS_PRINTF(f, "#ifdef _ACCESSORS\n");
VFS_PRINTF(f,
"accessor strbuf : float\n{\n"
"\tinline get float asfloat[float idx] = {return stof(bufstr_get(this, idx));};\n"
"\tinline set float asfloat[float idx] = {bufstr_set(this, idx, ftos(value));};\n"
"\tget string[float] = bufstr_get;\n"
"\tset string[float] = bufstr_set;\n"
"\tget float length = buf_getsize;\n"
"};\n");
VFS_PRINTF(f,
"accessor searchhandle : float\n{\n"
"\tget string[float] = search_getfilename;\n"
"\tget float length = search_getsize;\n"
"};\n");
VFS_PRINTF(f,
"accessor hashtable : float\n{\n"
"\tinline get vector v[string key] = {return hash_get(this, key, '0 0 0', EV_VECTOR);};\n"
"\tinline set vector v[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_VECTOR);};\n"
"\tinline get string s[string key] = {return hash_get(this, key, \"\", EV_STRING);};\n"
"\tinline set string s[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_STRING);};\n"
"\tinline get float f[string key] = {return hash_get(this, key, 0.0, EV_FLOAT);};\n"
"\tinline set float f[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_FLOAT);};\n"
"\tinline get __variant[string key] = {return hash_get(this, key, __NULL__);};\n"
"\tinline set __variant[string key] = {hash_add(this, key, value, HASH_REPLACE);};\n"
"};\n");
VFS_PRINTF(f,
"accessor infostring : string\n{\n"
"\tget string[string] = infoget;\n"
#ifdef QCGC
"\tinline set* string[string fld] = {(*this) = infoadd(*this, fld, value);};\n"
"\tinline set* string[string fld] = {(*this) = infoadd(*this, fld, value);};\n"
#endif
"};\n");
VFS_PRINTF(f,
"accessor filestream : float\n{\n"
"\tget string = fgets;\n"
"\tinline set string = {fputs(this,value);};\n"
"};\n");
VFS_PRINTF(f, "#endif\n");
}
"};\n");
VFS_PRINTF(f,
"accessor filestream : float\n{\n"
"\tget string = fgets;\n"
"\tinline set string = {fputs(this,value);};\n"
"};\n");
VFS_PRINTF(f, "#endif\n");
VFS_PRINTF(f, "#pragma noref 0\n");

View file

@ -504,6 +504,8 @@ typedef struct client_s
packet_entities_t sentents;
unsigned int *pendingdeltabits;
unsigned int *pendingcsqcbits;
unsigned int nextdeltaindex; //splurged round-robin to deal with overflows
unsigned int nextcsqcindex; //splurged round-robin
#define SENDFLAGS_USABLE 0x3fffffffu //this number of bits are actually safe in a float. not all together, but otherwise safe.
#define SENDFLAGS_PRESENT 0x80000000u //this entity is present on that client
#define SENDFLAGS_REMOVED 0x40000000u //to handle remove packetloss

View file

@ -1562,7 +1562,6 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
SVFTE_ExpandFrames(client, outno+1);
break;
}
client->pendingdeltabits[j] = 0;
if (bits & UF_REMOVE)
{ //if reset is set, then reset was set eroneously.
@ -1572,6 +1571,11 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
}
else if (client->sentents.entities[j].number) /*only send a new copy of the ent if they actually have one already*/
{
//if we didn't reach the end in the last packet, start at that point to avoid spam
//player slots are exempt from this, so they are in every packet (strictly speaking only the local player 'needs' this, but its nice to have it for high-priority targets too)
if (j < client->nextdeltaindex && j > svs.allocated_client_slots)
continue;
if (bits & UF_RESET2)
{
/*if reset2, then this is the second packet sent to the client and should have a forced reset (but which isn't tracked)*/
@ -1593,11 +1597,19 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
SV_EmitDeltaEntIndex(msg, j, false, true);
SVFTE_WriteUpdate(bits, &client->sentents.entities[j], msg, client->fteprotocolextensions2, client->sentents.bonedata);
}
client->pendingdeltabits[j] = 0;
resend[outno].flags = 0;
resend[outno++].entnum = j;
}
MSG_WriteShort(msg, 0);
if (j == client->sentents.num_entities) //looks like we sent them all
client->nextdeltaindex = 0; //start afresh with the next packet.
else
client->nextdeltaindex = j; //we overflowed or something, start going round-robin
client->frameunion.frames[sequence & UPDATE_MASK].entities.num_entities = outno;
client->frameunion.frames[sequence & UPDATE_MASK].sequence = sequence;
return overflow;
@ -3984,60 +3996,61 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
client->netchan.incoming_sequence++;
}
SV_EmitCSQCUpdate(client, msg, svcdp_csqcentities);
return;
}
#endif
// encode the packet entities as a delta from the
// last packetentities acknowledged by the client
if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
{
SVFTE_EmitPacketEntities(client, pack, msg);
}
else
#endif
{
#ifdef QUAKESTATS
// Z_EXT_TIME protocol extension
// every now and then, send an update so that extrapolation
// on client side doesn't stray too far off
if (ISQWCLIENT(client))
// encode the packet entities as a delta from the
// last packetentities acknowledged by the client
if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
{
if (client->fteprotocolextensions & PEXT_ACCURATETIMINGS && sv.world.physicstime - client->nextservertimeupdate > 0)
{ //the fte pext causes the server to send out accurate timings, allowing for perfect interpolation.
MSG_WriteByte (msg, svcqw_updatestatlong);
MSG_WriteByte (msg, STAT_TIME);
MSG_WriteLong (msg, (int)(sv.world.physicstime * 1000));
client->nextservertimeupdate = sv.world.physicstime;
}
else if (client->zquake_extensions & Z_EXT_SERVERTIME && sv.world.physicstime - client->nextservertimeupdate > 0)
{ //the zquake ext causes the server to send out peridoic timings, allowing for moderatly accurate game time.
MSG_WriteByte (msg, svcqw_updatestatlong);
MSG_WriteByte (msg, STAT_TIME);
MSG_WriteLong (msg, (int)(sv.world.physicstime * 1000));
client->nextservertimeupdate = sv.world.physicstime+10;
}
SVFTE_EmitPacketEntities(client, pack, msg);
}
else
{
#ifdef QUAKESTATS
// Z_EXT_TIME protocol extension
// every now and then, send an update so that extrapolation
// on client side doesn't stray too far off
if (ISQWCLIENT(client))
{
if (client->fteprotocolextensions & PEXT_ACCURATETIMINGS && sv.world.physicstime - client->nextservertimeupdate > 0)
{ //the fte pext causes the server to send out accurate timings, allowing for perfect interpolation.
MSG_WriteByte (msg, svcqw_updatestatlong);
MSG_WriteByte (msg, STAT_TIME);
MSG_WriteLong (msg, (int)(sv.world.physicstime * 1000));
client->nextservertimeupdate = sv.world.physicstime;
}
else if (client->zquake_extensions & Z_EXT_SERVERTIME && sv.world.physicstime - client->nextservertimeupdate > 0)
{ //the zquake ext causes the server to send out peridoic timings, allowing for moderatly accurate game time.
MSG_WriteByte (msg, svcqw_updatestatlong);
MSG_WriteByte (msg, STAT_TIME);
MSG_WriteLong (msg, (int)(sv.world.physicstime * 1000));
client->nextservertimeupdate = sv.world.physicstime+10;
}
}
#endif
// send over the players in the PVS
if (svs.gametype != GT_HALFLIFE)
{
if (client == &demo.recorder)
SV_WritePlayersToMVD(client, frame, msg);
else
SV_WritePlayersToClient (client, frame, clent, cameras, msg);
// send over the players in the PVS
if (svs.gametype != GT_HALFLIFE)
{
if (client == &demo.recorder)
SV_WritePlayersToMVD(client, frame, msg);
else
SV_WritePlayersToClient (client, frame, clent, cameras, msg);
}
SVQW_EmitPacketEntities (client, pack, msg);
}
SVQW_EmitPacketEntities (client, pack, msg);
SV_EmitCSQCUpdate(client, msg, svcfte_csqcentities);
// now add the specialized nail update
SV_EmitNailUpdate (msg, ignorepvs);
}
SV_EmitCSQCUpdate(client, msg, svcfte_csqcentities);
// now add the specialized nail update
SV_EmitNailUpdate (msg, ignorepvs);
}
//just goes and makes sure each client tracks all the right SendFlags.

View file

@ -1488,8 +1488,10 @@ void SVC_GetChallenge (qboolean nodpresponse)
over+=sizeof(lng);
}
#endif
mask = net_mtu.ival&~7;
if (*net_mtu.string)
mask = net_mtu.ival&~7;
else
mask = 8192;
if (mask > 64)
{
lng = LittleLong(PROTOCOL_VERSION_FRAGMENT);

View file

@ -237,7 +237,7 @@ A Con_Printf that only shows up if the "developer" cvar is set
*/
static void Con_DPrintFromThread (void *ctx, void *data, size_t a, size_t b)
{
Con_DPrintf("%s", (char*)data);
Con_DLPrintf(level, "%s", (char*)data);
BZ_Free(data);
}
void Con_DPrintf (const char *fmt, ...)
@ -275,6 +275,41 @@ void Con_DPrintf (const char *fmt, ...)
if (log_developer.value)
Con_Log(msg); // log to console
}
void Con_DLPrintf (int level, const char *fmt, ...)
{
va_list argptr;
char msg[MAXPRINTMSG];
extern cvar_t log_developer;
if (developer.ival < level && !log_developer.value)
return;
va_start (argptr,fmt);
vsnprintf (msg,sizeof(msg)-1, fmt,argptr);
va_end (argptr);
if (!Sys_IsMainThread())
{
COM_AddWork(WG_MAIN, Con_DPrintFromThread, NULL, Z_StrDup(msg), level, 0);
return;
}
// add to redirected message
if (sv_redirected)
{
if (strlen (msg) + strlen(sv_redirected_buf) > sizeof(sv_redirected_buf) - 1)
SV_FlushRedirect ();
strcat (sv_redirected_buf, msg);
if (sv_redirected != -1)
return;
}
if (developer.ival >= level)
Sys_Printf ("%s", msg); // also echo to debugging console
if (log_developer.value)
Con_Log(msg); // log to console
}
#endif
/*
@ -2547,8 +2582,14 @@ qboolean SV_SendClientDatagram (client_t *client)
client->edict->v->goalentity = 0;
}
// if (client->protocol != SCP_FITZ666 && !client->netchan.fragmentsize)
msg.maxsize = MAX_DATAGRAM;
if (client->netchan.fragmentsize)
msg.maxsize = client->netchan.fragmentsize; //try not to overflow
else if (client->protocol == SCP_NETQUAKE)
msg.maxsize = MAX_NQDATAGRAM; //vanilla client is limited.
else
msg.maxsize = MAX_DATAGRAM; //udp limit, ish.
if (msg.maxsize > countof(buf))
msg.maxsize = countof(buf);
if (sv.world.worldmodel && !client->controller)
{

View file

@ -5991,7 +5991,7 @@ void SV_ExecuteUserCommand (char *s, qboolean fromQC)
if (host_client->state < cs_connected)
return;
Con_DPrintf("Client command: %s\n", s);
Con_DLPrintf((host_client->netchan.remote_address.type==NA_LOOPBACK)?2:1, "Client command: %s\n", s);
Cmd_TokenizeString (s, false, false);
sv_player = host_client->edict;