diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index 496004e35..d179305a6 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -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 } } diff --git a/engine/client/clq3_parse.c b/engine/client/clq3_parse.c index 2d7ff59d0..1630afd2a 100644 --- a/engine/client/clq3_parse.c +++ b/engine/client/clq3_parse.c @@ -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) diff --git a/engine/client/image.c b/engine/client/image.c index 75f04e284..7ee4f0afd 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -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. diff --git a/engine/client/m_download.c b/engine/client/m_download.c index 22986e676..49de84c01 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -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")) { diff --git a/engine/client/net_master.c b/engine/client/net_master.c index 8bf586b45..3130f855e 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -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) diff --git a/engine/client/render.h b/engine/client/render.h index 9b361c630..d1c415de2 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -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); diff --git a/engine/client/screen.h b/engine/client/screen.h index 770bc57e9..4d25fc33b 100644 --- a/engine/client/screen.h +++ b/engine/client/screen.h @@ -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) diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 56a08a2ba..8a7276ab2 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -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 diff --git a/engine/common/config_fteqw.h b/engine/common/config_fteqw.h index c80ba3d83..66d9475c2 100644 --- a/engine/common/config_fteqw.h +++ b/engine/common/config_fteqw.h @@ -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. diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index 71f58352f..d1ee2e12a 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -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 @@ -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)); diff --git a/engine/common/netinc.h b/engine/common/netinc.h index 66c152ce5..b47da8367 100644 --- a/engine/common/netinc.h +++ b/engine/common/netinc.h @@ -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 diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 8417c74e5..44cc14e3c 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -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; } diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index 529f779af..d267ce5d8 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -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) diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index d8fa5fb04..054095338 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -429,8 +429,16 @@ void Mod_Think (void) f = FS_OpenVFS(filename, "wb", FS_GAME); if (f) { - VFS_WRITE(f, "QLIT\1\0\0\0", 8); - VFS_WRITE(f, lightmodel->lightdata, numlightdata*3); + 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,20 +2116,37 @@ 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; - litdata = ZG_Malloc(&loadmodel->memgroup, samples*3); - littmp = false; - if (lumdata) + unsigned int *ergb; + + if (r_loadlits.ival >= 3) { - for (i = 0; i < samples; i++) + ergb = ZG_Malloc(&loadmodel->memgroup, samples*4); + expdata = (qbyte*)ergb; + littmp = false; + if (lumdata) { - litdata[i*3+0] = lumdata[i]; - litdata[i*3+1] = lumdata[i]; - litdata[i*3+2] = lumdata[i]; + 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) + { + for (i = 0; i < samples; i++) + { + litdata[i*3+0] = lumdata[i]; + litdata[i*3+1] = lumdata[i]; + litdata[i*3+2] = lumdata[i]; + } + lumdata = NULL; } - lumdata = NULL; } } /*if we're relighting, make sure there's the proper lux data to be updated*/ diff --git a/engine/gl/ltface.c b/engine/gl/ltface.c index ea9d86ae0..709e3022e 100644 --- a/engine/gl/ltface.c +++ b/engine/gl/ltface.c @@ -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<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<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<lmshift); } #endif diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index ba31b16da..8ae0aa5ef 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -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...