1
0
Fork 0
forked from fte/fteqw

Fix compile issues when HAVE_PACKET is disabled, also removing references to resulting unusable hostnames.

Fix recent sizeof(void) error.
Fix crashes from 0-byte lit files (and a few other related bugs that noone else noticed yet).
r_loadlit 3 now generates e5bgr9 .lit format (for over-over-bright). Also supports world.light for minlight values, now also uses super-sampling (slower but nicer).
Additionally disable PEXT_TRANS in the FortressOne fork of ezQuake (sidestepping its inherited bugs).
Fix q3's sprites getting horizontally flipped.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5501 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2019-08-03 01:58:03 +00:00
parent 7991260cc0
commit 26e527a8a6
16 changed files with 148 additions and 47 deletions

View file

@ -1665,7 +1665,9 @@ void UI_Stop (void)
//note that q3 checks every frame. we only check when the ui is closed.
if (Cvar_UnsavedArchive())
Cmd_ExecuteString("cfg_save", RESTRICT_LOCAL);
#if defined(CL_MASTER)
MasterInfo_WriteServers();
#endif
}
}

View file

@ -1009,6 +1009,7 @@ void CLQ3_SendCmd(usercmd_t *cmd)
void CLQ3_SendAuthPacket(netadr_t *gameserver)
{
#ifdef HAVE_PACKET
char data[2048];
sizebuf_t msg;
@ -1045,6 +1046,7 @@ void CLQ3_SendAuthPacket(netadr_t *gameserver)
Con_Printf(" failed\n");
}
}
#endif
}
void CLQ3_SendConnectPacket(netadr_t *to, int challenge, int qport)

View file

@ -7937,16 +7937,23 @@ static void Image_DecompressFormat(struct pendingtextureinfo *mips)
{
for (mip = 0; mip < mips->mipcount; mip++)
{
size_t sz;
void *out;
if (decodefunc64)
{
sz = sizeof(pixel64_t);
out = Image_Block_Decode64(mips->mip[mip].data, mips->mip[mip].datasize, mips->mip[mip].width, mips->mip[mip].height, decodefunc64, mips->encoding);
}
else
{
sz = sizeof(pixel32_t);
out = Image_Block_Decode(mips->mip[mip].data, mips->mip[mip].datasize, mips->mip[mip].width, mips->mip[mip].height, decodefunc, mips->encoding);
}
if (mips->mip[mip].needfree)
BZ_Free(mips->mip[mip].data);
mips->mip[mip].data = out;
mips->mip[mip].needfree = true;
mips->mip[mip].datasize = mips->mip[mip].width*mips->mip[mip].height*sizeof(*out);
mips->mip[mip].datasize = mips->mip[mip].width*mips->mip[mip].height*sz;
}
if (mips->extrafree)
BZ_Free(mips->extrafree); //might as well free this now, as nothing is poking it any more.

View file

@ -695,7 +695,7 @@ static qboolean PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *ur
else
subprefix = com_token;
#ifdef HAVE_LEGACY
#if defined(HAVE_LEGACY) && defined(WEBCLIENT)
//hack. I'm trying to retire the self-signed cert on [fte.]triptohell.info
if (!strcmp(url, "https://triptohell.info/downloadables.php") || !strcmp(url, "https://fte.triptohell.info/downloadables.php"))
{

View file

@ -138,6 +138,7 @@ static net_masterlist_t net_masterlist[] = {
{MP_QUAKE3, CVARC("net_q3master4", "", Net_Masterlist_Callback)},
#endif
#ifdef HAVE_PACKET
#ifndef QUAKETC
//engine-specified/maintained master lists (so users can be lazy and update the engine without having to rewrite all their configs).
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra1", "qwmaster.ocrana.de:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Ocrana(2nd)"}, //german. admin unknown
@ -193,6 +194,7 @@ static net_masterlist_t net_masterlist[] = {
{MP_QUAKE3, CVARFC("net_q3masterextra5", "master.maverickservers.com:27950", CVAR_NOSAVE, Net_Masterlist_Callback), "US: Maverickservers.com"},
{MP_QUAKE3, CVARFC("net_q3masterextra6", "dpmaster.deathmask.net:27950", CVAR_NOSAVE, Net_Masterlist_Callback), "US: DeathMask.net"},
{MP_QUAKE3, CVARFC("net_q3masterextra8", "master3.idsoftware.com:27950", CVAR_NOSAVE, Net_Masterlist_Callback), "US: id Software Quake III Master"},
#endif
#endif
{MP_UNSPECIFIED, CVAR(NULL, NULL)}
@ -3609,14 +3611,17 @@ void CL_Connect_c(int argn, const char *partial, struct xcommandargcompletioncb_
#ifdef Q3CLIENT
static void NetQ3_LocalServers_f(void)
{
#if defined(CL_MASTER)
netadr_t na;
MasterInfo_Refresh(true);
if (NET_StringToAdr("255.255.255.255", PORT_Q3SERVER, &na))
NET_SendPollPacket (14, va("%c%c%c%cgetstatus\n", 255, 255, 255, 255), na);
#endif
}
static void NetQ3_GlobalServers_f(void)
{
#if defined(CL_MASTER)
size_t masternum = atoi(Cmd_Argv(1));
int protocol = atoi(Cmd_Argv(2));
char *keywords;
@ -3645,6 +3650,7 @@ static void NetQ3_GlobalServers_f(void)
for (i = 0; i < n; i++)
NET_SendPollPacket (strlen(str), str, adr[i]);
}
#endif
}
#endif
void Net_Master_Init(void)

View file

@ -554,7 +554,7 @@ void Mod_ModelLoaded(void *ctx, void *data, size_t a, size_t b);
struct relight_ctx_s;
struct llightinfo_s;
void LightFace (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, int surfnum); //version that is aware of bsp trees
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, qbyte surf_styles[4], qbyte *surf_rgbsamples, qbyte *surf_deluxesamples, vec4_t surf_plane, vec4_t surf_texplanes[2], vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2], float lmscale); //special version that doesn't know what a face is or anything.
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, qbyte surf_styles[4], unsigned int *surf_expsamples, qbyte *surf_rgbsamples, qbyte *surf_deluxesamples, vec4_t surf_plane, vec4_t surf_texplanes[2], vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2], float lmscale); //special version that doesn't know what a face is or anything.
struct relight_ctx_s *LightStartup(struct relight_ctx_s *ctx, struct model_s *model, qboolean shadows, qboolean skiplit);
void LightReloadEntities(struct relight_ctx_s *ctx, const char *entstring, qboolean ignorestyles);
void LightShutdown(struct relight_ctx_s *ctx, struct model_s *mod);

View file

@ -150,7 +150,7 @@ typedef enum uploadfmt
PTI_ETC2_RGB8_SRGB,
PTI_ETC2_RGB8A1_SRGB,
PTI_ETC2_RGB8A8_SRGB,
PTI_EAC_R11, //no idea what this might be used for, whatever
PTI_EAC_R11, //might be useful for overlays, with swizzles.
PTI_EAC_R11_SNORM, //no idea what this might be used for, whatever
PTI_EAC_RG11, //useful for normalmaps (calculate blue)
PTI_EAC_RG11_SNORM, //useful for normalmaps (calculate blue)

View file

@ -5275,6 +5275,12 @@ static galiasinfo_t *Mod_LoadQ3ModelLod(model_t *mod, int *surfcount, void *buff
indexes[i*3+0] = LittleLong(intris[i].indexes[0]);
indexes[i*3+1] = LittleLong(intris[i].indexes[1]);
indexes[i*3+2] = LittleLong(intris[i].indexes[2]);
if (indexes[i*3+0] >= numverts || indexes[i*3+1] >= numverts || indexes[i*3+2] >= numverts)
{
Con_Printf(CON_WARNING "Warning: surface %s has invalid vertex indexes\n", galias->surfacename);
indexes[i*3+0] = indexes[i*3+1] = indexes[i*3+2] = 0;
}
}
//figure out where we're putting the pose data

View file

@ -157,7 +157,7 @@
// Other Audio Options
#define VOICECHAT
#define HAVE_SPEEX //Support the speex codec.
//#define HAVE_SPEEX //Support the speex codec.
#define HAVE_OPUS //Support the opus codec.
#define HAVE_MEDIA_DECODER //can play cin/roq, more with plugins
#define HAVE_MEDIA_ENCODER //capture/capturedemo work.

View file

@ -18,8 +18,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// net_wins.c
struct sockaddr;
#include "quakedef.h"
#include "netinc.h"
#include <stddef.h>
@ -266,6 +264,10 @@ int NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
void SockadrToNetadr (struct sockaddr_qstorage *s, int sizeofsockaddr, netadr_t *a)
{
#ifndef HAVE_PACKET
memset(a, 0, sizeof(*a));
a->type = NA_INVALID;
#else
a->scopeid = 0;
a->connum = 0;
a->prot = NP_DGRAM;
@ -336,6 +338,7 @@ void SockadrToNetadr (struct sockaddr_qstorage *s, int sizeofsockaddr, netadr_t
a->type = NA_INVALID;
break;
}
#endif
}
char *NET_SockadrToString (char *s, int len, struct sockaddr_qstorage *a, size_t sizeofa)
{
@ -588,7 +591,7 @@ qboolean NET_AddressSmellsFunny(netadr_t *a)
}
}
#if _POSIX_C_SOURCE >= 200112L || defined(getnameinfo)
#if (_POSIX_C_SOURCE >= 200112L || defined(getnameinfo)) && defined(HAVE_PACKET)
static void NET_AdrToStringDoResolve(void *ctx, void *data, size_t a, size_t b)
{
netadr_t *n = data;
@ -1042,6 +1045,7 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
if (!(*s) || !addresses)
return result;
#ifdef WEBCLIENT
//EVIL HACK!
//updates.tth uses a known self-signed certificate (to protect against dns hijacks like fteqw.com suffered).
//its not meant to be used for browsers etc, and I cba to register dns stuff for it.
@ -1049,6 +1053,7 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
//redirect the dns to the base host without affecting http(s) hosts/certificates.
if (!strcmp(s, "updates.triptohell.info"))
s += 8;
#endif
memset (sadr, 0, sizeof(*sadr));

View file

@ -5,10 +5,10 @@
#ifndef HAVE_PACKET
#ifndef _XBOX
struct sockaddr
{
short sa_family;
};
// struct sockaddr
// {
// short sa_family;
// };
#define ntohs BigShort
#define htons BigShort
@ -381,8 +381,8 @@ vfsfile_t *FS_OpenTCPSocket(SOCKET socket, qboolean conpending, const char *peer
#endif
vfsfile_t *FS_OpenTCP(const char *name, int defaultport);
#ifndef SOCK_CLOEXEC
#define SOCK_CLOEXEC 0
#endif
/*#ifndef SOCK_CLOEXEC
#define SOCK_CLOEXEC naught
#endif*/
#endif //NETINC_INCLUDED

View file

@ -2614,6 +2614,7 @@ static void R_Sprite_GenerateTrisoup(entity_t *e, int bemode)
{
genframe.down = genframe.left = -1;
genframe.up = genframe.right = 1;
genframe.xmirror = false;
sprtype = SPR_VP_PARALLEL;
frame = &genframe;
}

View file

@ -4375,7 +4375,7 @@ qbyte *Heightmap_ClusterPVS (model_t *model, int num, pvsbuffer_t *buffer, pvsme
}
int Heightmap_ClusterForPoint (model_t *model, const vec3_t point, int *area)
{
if (*area)
if (area)
*area = 0;
return -1;
}
@ -5669,7 +5669,7 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
dorelight = false;
br->faces[j].relight = false;
LightPlane (hm->relightcontext, hm->lightthreadmem, styles, br->faces[j].lightdata, NULL, br->planes[j], br->faces[j].stdir, exactmins, exactmaxs, br->faces[j].lmbias, texsize, br->faces[j].lmscale); //special version that doesn't know what a face is or anything.
LightPlane (hm->relightcontext, hm->lightthreadmem, styles, NULL, br->faces[j].lightdata, NULL, br->planes[j], br->faces[j].stdir, exactmins, exactmaxs, br->faces[j].lmbias, texsize, br->faces[j].lmscale); //special version that doesn't know what a face is or anything.
br->faces[j].relit = true;
}
if (br->faces[j].relit && br->faces[j].lightmap >= 0)

View file

@ -428,9 +428,17 @@ void Mod_Think (void)
f = FS_OpenVFS(filename, "wb", FS_GAME);
if (f)
{
if (lightmodel->lightmaps.fmt == LM_E5BGR9)
{
VFS_WRITE(f, "QLIT\x01\0\x01\0", 8);
VFS_WRITE(f, lightmodel->lightdata, numlightdata*4);
}
else
{
VFS_WRITE(f, "QLIT\1\0\0\0", 8);
VFS_WRITE(f, lightmodel->lightdata, numlightdata*3);
}
VFS_CLOSE(f);
}
else
@ -1889,10 +1897,10 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
litsize = 0;
}
if (litdata && litsize >= 8)
if (litdata)
{ //validate it, if we loaded one.
int litver = LittleLong(*(int *)&litdata[4]);
if (litdata[0] != 'Q' || litdata[1] != 'L' || litdata[2] != 'I' || litdata[3] != 'T')
if (litsize < 8 || litdata[0] != 'Q' || litdata[1] != 'L' || litdata[2] != 'I' || litdata[3] != 'T')
{
litdata = NULL;
Con_Printf("lit \"%s\" isn't a lit\n", litname);
@ -1915,7 +1923,7 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
expdata = litdata+8; //header+version
litdata = NULL;
}
else if (litver == 2 && overrides)
else if (litver == 2 && overrides && litsize > sizeof(qlit2_t))
{
qlit2_t *ql2 = (qlit2_t*)litdata;
unsigned int *offsets = (unsigned int*)(ql2+1);
@ -1932,6 +1940,11 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
litdata = NULL;
Con_Printf("lit \"%s\" doesn't match level. Ignored.\n", litname);
}
else if (litsize != sizeof(qlit2_t)+ql2->numsurfs*4+ql2->lmsize*6)
{
litdata = NULL;
Con_Printf("lit \"%s\" is truncated. Ignored.\n", litname);
}
else
{
inhibitvalidation = true;
@ -1958,7 +1971,7 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
}
exptmp = littmp = false;
if (!litdata)
if (!litdata && !expdata)
{
int size;
/*FIXME: bspx support for extents+lmscale, may require style+offset lumps too, not sure what to do here*/
@ -1976,7 +1989,7 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
}
else if (!inhibitvalidation)
{
if (lumdata)
if (lumdata && litdata)
{
float prop;
int i;
@ -2060,7 +2073,7 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
}
else
{
if (luxdata[0] == 'Q' && luxdata[1] == 'L' && luxdata[2] == 'I' && luxdata[3] == 'T')
if (luxsz < 8 || (luxdata[0] == 'Q' && luxdata[1] == 'L' && luxdata[2] == 'I' && luxdata[3] == 'T'))
{
if (LittleLong(*(int *)&luxdata[4]) == 1)
luxdata+=8;
@ -2082,9 +2095,9 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
#ifdef RUNTIMELIGHTING
if ((loadmodel->type == mod_brush && loadmodel->fromgame == fg_quake) || loadmodel->type == mod_heightmap)
{ //we only support a couple of formats. :(
if (!lightmodel && r_loadlits.value == 2 && (!litdata || (!luxdata && r_deluxemapping)))
if (!lightmodel && r_loadlits.value == 2 && ((!litdata&&!expdata) || (!luxdata && r_deluxemapping)))
{
writelitfile = !litdata;
writelitfile = !litdata&&!expdata;
numlightdata = l->filelen;
lightmodel = loadmodel;
relitsurface = 0;
@ -2103,9 +2116,25 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
}
/*if we're relighting, make sure there's the proper lit data to be updated*/
if (lightmodel == loadmodel && !litdata)
if (lightmodel == loadmodel && !litdata && !expdata)
{
int i;
unsigned int *ergb;
if (r_loadlits.ival >= 3)
{
ergb = ZG_Malloc(&loadmodel->memgroup, samples*4);
expdata = (qbyte*)ergb;
littmp = false;
if (lumdata)
{
for (i = 0; i < samples; i++)
ergb[i] = 15<<27 | lumdata[i]<<18 | lumdata[i]<<9 << lumdata[i]<<0;
lumdata = NULL;
}
}
else
{
litdata = ZG_Malloc(&loadmodel->memgroup, samples*3);
littmp = false;
if (lumdata)
@ -2119,6 +2148,7 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
lumdata = NULL;
}
}
}
/*if we're relighting, make sure there's the proper lux data to be updated*/
if (lightmodel == loadmodel && r_deluxemapping && !luxdata)
{

View file

@ -21,6 +21,7 @@ struct relight_ctx_s
unsigned int nummodels;
model_t *models[2048];
float minlight;
qboolean skiplit; //lux only
qboolean shadows;
mentity_t *entities;
@ -45,7 +46,7 @@ struct relight_ctx_s
#define scaledist 1
#define rangescale 0.5
#define extrasamples 0
#define extrasamples 1
#define scalecos 0.5
@ -263,6 +264,10 @@ void LightReloadEntities(struct relight_ctx_s *ctx, const char *entstring, qbool
ctx->num_entities++;
}
if (ctx->num_entities)
if (ctx->entities[0].light)
ctx->minlight = ctx->entities[0].light;
for (mapent = ctx->entities; mapent < &ctx->entities[ctx->num_entities]; mapent++)
{
if (*mapent->target)
@ -704,9 +709,7 @@ FixMinlight
static void FixMinlight (llightinfo_t *l)
{
int i, j;
float minlight;
minlight = 0;
float minlight = l->ctx->minlight;
// if minlight is set, there must be a style 0 light map
if (!minlight)
@ -744,13 +747,38 @@ static void FixMinlight (llightinfo_t *l)
}
}
static unsigned int PackE5BRG9(vec3_t rgb)
{ //5 bits exponent, 3*9 bits of mantissa. no sign bit.
int e = 0;
float m = max(max(rgb[0], rgb[1]), rgb[2]);
float scale;
unsigned int hdr;
if (m >= 0.5)
{ //positive exponent
while (m >= (1<<(e)) && e < 30-15) //don't do nans.
e++;
}
else
{ //negative exponent...
while (m < 1/(1<<-e) && e > -15) //don't do denormals.
e--;
}
scale = pow(2, e-9);
hdr = ((e+15)<<27);
hdr |= bound(0, (int)(rgb[0]/scale + 0.5), 0x1ff)<<0;
hdr |= bound(0, (int)(rgb[1]/scale + 0.5), 0x1ff)<<9;
hdr |= bound(0, (int)(rgb[2]/scale + 0.5), 0x1ff)<<18;
return hdr;
}
/*
============
LightFace
============
*/
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_styles[MAXQ1LIGHTMAPS], qbyte *surf_rgbsamples, qbyte *surf_deluxesamples, vec4_t surf_plane, vec4_t surf_texplanes[2], vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2], float lmscale)
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_styles[MAXQ1LIGHTMAPS], unsigned int *surf_expsamples, qbyte *surf_rgbsamples, qbyte *surf_deluxesamples, vec4_t surf_plane, vec4_t surf_texplanes[2], vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2], float lmscale)
{
int s, t;
int i,c,ch;
@ -761,6 +789,7 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_s
int lightmapsize;
byte *out;
#endif
unsigned int *expout;
qbyte *rgbout;
qbyte *dulout;
vec3_t *light, *norm;
@ -771,7 +800,7 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_s
//
// some surfaces don't need lightmaps
//
if (!surf_rgbsamples)
if (!surf_rgbsamples && !surf_expsamples)
return;
// memset (l, 0, sizeof(*l));
@ -840,21 +869,28 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_s
if (runningrgblightdatabase)
{
out = GetFakeFileSpace(&f->lightofs, lightmapsize);
expout = NULL;
rgbout = runningrgblightdatabase + f->lightofs*3;
dulout = runninglightnormbase + f->lightofs*3;
}
else
{
out = GetFileSpace (&f->lightofs, lightmapsize);
expout = NULL;
rgbout = GetRGBFileSpace (f->lightofs, lightmapsize);
dulout = GetNormFileSpace (f->lightofs, lightmapsize);
}
#else
if (!ctx->skiplit)
{
expout = surf_expsamples;
rgbout = surf_rgbsamples;
}
else
{
expout = NULL;
rgbout = NULL;
}
if (l->ctx->models[0]->deluxdata)
{
dulout = surf_deluxesamples;
@ -906,6 +942,7 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_s
wnorm[ch] = norm[c][ch];
}
total *= rangescale; // scale before clamping
temp[ch] = total/0x80; // quake bsps store logical light values between 0 and 2 for overbrights. normalise it appropriately.
#ifndef UTILITY
// if (total > *rgbout) //sorry - for qw
// total = *rgbout;
@ -919,6 +956,8 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_s
*rgbout++ = total;
mean += total;
}
if (expout)
*expout++ = PackE5BRG9(temp);
#ifdef UTILITY
*out++ = mean/3;
#endif
@ -961,6 +1000,9 @@ void LightFace (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, int f
return;
LightCalcFaceExtents(ctx->models[0], f, exactmins, exactmaxs, texmins, texsize);
LightPlane(ctx, threadctx, f->styles, f->samples, f->samples - ctx->models[0]->lightdata + ctx->models[0]->deluxdata, plane, f->texinfo->vecs, exactmins, exactmaxs, texmins, texsize, 1<<f->lmshift);
if (ctx->models[0]->lightmaps.fmt == LM_E5BGR9)
LightPlane(ctx, threadctx, f->styles, (unsigned int*)f->samples, NULL, 3*(f->samples - ctx->models[0]->lightdata)/4 + ctx->models[0]->deluxdata, plane, f->texinfo->vecs, exactmins, exactmaxs, texmins, texsize, 1<<f->lmshift);
else
LightPlane(ctx, threadctx, f->styles, NULL, f->samples, f->samples - ctx->models[0]->lightdata + ctx->models[0]->deluxdata, plane, f->texinfo->vecs, exactmins, exactmaxs, texmins, texsize, 1<<f->lmshift);
}
#endif

View file

@ -310,10 +310,10 @@ void SV_New_f (void)
const char *s;
int ver;
s = InfoBuf_ValueForKey(&host_client->userinfo, "*client");
if (!strncmp(s, "ezQuake", 7))
if (!strncmp(s, "ezQuake", 7) || !strncmp(s, "FortressOne", 11))
{
s += 7;
COM_Parse(s);
COM_Parse(s); //skip name-of-fork
COM_Parse(s); //tokenize the version
ver = atoi(com_token);
//this should actually have been resolved now, but for future use...