Added LMSTYLES16 support, increasing max lightstyles to 65k.

Updated networking for these extra lightstyles.
LMSTYLES[16] bspx lumps now also infer the number of styles per face, allowing for up to 16 styles per face.
Support a few more pixel formats in dds files.
Allow r_lightmap_format to be changed instantly.
Remove physics_bullet_enable cvar, as its inferred by whether the plugin is enabled or not.



git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5540 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2019-09-10 15:40:04 +00:00
parent 364328e212
commit c6917a5f8c
34 changed files with 661 additions and 379 deletions

View file

@ -1580,7 +1580,7 @@ static int CL_Record_Lightstyles(sizebuf_t *buf, int seq)
{
unsigned int i;
// send all current light styles
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
for (i=0 ; i<cl_max_lightstyles ; i++)
{
if (i >= MAX_STANDARDLIGHTSTYLES)
if (!*cl_lightstyle[i].map)

View file

@ -187,6 +187,7 @@ static void CL_ClearDlight(dlight_t *dl, int key)
dl->color[2] = 1;
dl->corona = bound(0, 1 * 0.25, 1);
dl->coronascale = bound(0, r_flashblendscale.value, 1);
dl->style = -1;
#ifdef RTLIGHTS
dl->lightcolourscales[0] = r_shadow_realtime_dlight_ambient.value;
dl->lightcolourscales[1] = r_shadow_realtime_dlight_diffuse.value;
@ -3788,16 +3789,21 @@ void CL_TransitionEntities (void)
nolerp = !CL_MayLerp() && cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV;
}
//force our emulated time to as late as we can, if we're not using interpolation, which has the effect of disabling all interpolation
if (cl.demonudge < 0)
{
{ //demo playback allows nudging to earlier frames, generally only when paused though...
servertime = cl.inframes[(cls.netchan.incoming_sequence+cl.demonudge)&UPDATE_MASK].packet_entities.servertime;
nolerp = true;
}
else if (nolerp)
{
//force our emulated time to as late as we can, if we're not using interpolation, which has the effect of disabling all interpolation
servertime = cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.servertime;
}
else
{
//otherwise go for the latest frame we can.
servertime = cl.servertime;
}
// servertime -= 0.1;
@ -3812,7 +3818,7 @@ void CL_TransitionEntities (void)
packnew = &cl.inframes[newf].packet_entities;
packold = &cl.inframes[oldf].packet_entities;
if (packnew->servertime == packold->servertime)
frac = 1; //lerp totally into the new
frac = 1; //lerp totally into the new (avoid any division-by-0 issues here)
else
frac = (servertime-packold->servertime)/(packnew->servertime-packold->servertime);

View file

@ -234,7 +234,8 @@ client_state_t cl;
entity_state_t *cl_baselines;
static_entity_t *cl_static_entities;
unsigned int cl_max_static_entities;
lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
lightstyle_t *cl_lightstyle;
size_t cl_max_lightstyles;
dlight_t *cl_dlights;
size_t cl_maxdlights; /*size of cl_dlights array*/
@ -1814,9 +1815,9 @@ void CL_ClearState (qboolean gamestart)
// clear other arrays
// memset (cl_dlights, 0, sizeof(cl_dlights));
memset (cl_lightstyle, 0, sizeof(cl_lightstyle));
for (i = 0; i < MAX_LIGHTSTYLES; i++)
R_UpdateLightStyle(i, NULL, 1, 1, 1);
Z_Free(cl_lightstyle);
cl_lightstyle = NULL;
cl_max_lightstyles = 0;
rtlights_first = rtlights_max = RTL_FIRST;

View file

@ -1750,7 +1750,18 @@ void CL_RequestNextDownload (void)
break;
case DLFAIL_UNTRIED:
if (COM_FCheckExists(worldname))
Con_Printf(CON_ERROR "Couldn't load \"%s\" - corrupt? - cannot fully connect\n", worldname);
{
if (!cl.worldmodel)
Con_Printf(CON_ERROR "Couldn't load \"%s\" - worldmodel not set - cannot fully connect\n", worldname);
else if (cl.worldmodel->loadstate == MLS_FAILED)
Con_Printf(CON_ERROR "Couldn't load \"%s\" - corrupt? - cannot fully connect\n", worldname);
else if (cl.worldmodel->loadstate == MLS_LOADING)
Con_Printf(CON_ERROR "Couldn't load \"%s\" - still loading - cannot fully connect\n", worldname);
else if (cl.worldmodel->loadstate == MLS_NOTLOADED)
Con_Printf(CON_ERROR "Couldn't load \"%s\" - worldmodel not loaded - cannot fully connect\n", worldname);
else
Con_Printf(CON_ERROR "Couldn't load \"%s\" - corrupt? - cannot fully connect\n", worldname);
}
else
Con_Printf(CON_ERROR "Couldn't find \"%s\" - cannot fully connect\n", worldname);
break;
@ -6415,6 +6426,15 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds
InfoBuf_SetStarKey(&cl.serverinfo, Cmd_Argv(1), Cmd_Argv(2));
CL_CheckServerInfo();
}
else if (!strncmp(stufftext, "//ls ", 5)) //for extended lightstyles
{
vec3_t rgb;
Cmd_TokenizeString(stufftext+2, false, false);
rgb[0] = ((Cmd_Argc()>3)?atof(Cmd_Argv(3)):1);
rgb[1] = ((Cmd_Argc()>5)?atof(Cmd_Argv(4)):rgb[0]);
rgb[2] = ((Cmd_Argc()>5)?atof(Cmd_Argv(5)):rgb[0]);
R_UpdateLightStyle(atoi(Cmd_Argv(1)), Cmd_Argv(2), rgb[0], rgb[1], rgb[2]);
}
#ifdef NQPROT
//DP's download protocol
@ -7019,7 +7039,7 @@ void CLQW_ParseServerMessage (void)
case svc_lightstyle:
i = MSG_ReadByte ();
if (i >= MAX_LIGHTSTYLES)
if (i >= MAX_NET_LIGHTSTYLES)
Host_EndGame ("svc_lightstyle > MAX_LIGHTSTYLES");
R_UpdateLightStyle(i, MSG_ReadString(), 1, 1, 1);
break;
@ -7027,18 +7047,18 @@ void CLQW_ParseServerMessage (void)
case svcfte_lightstylecol:
if (!(cls.fteprotocolextensions & PEXT_LIGHTSTYLECOL))
Host_EndGame("PEXT_LIGHTSTYLECOL is meant to be disabled\n");
i = MSG_ReadByte ();
if (i >= MAX_LIGHTSTYLES)
Host_EndGame ("svc_lightstyle > MAX_LIGHTSTYLES");
{
int bits;
vec3_t rgb;
i = MSG_ReadByte ();
bits = MSG_ReadByte();
if (bits & 0x40)
i |= MSG_ReadByte()<<8; //high bits of style index.
if (bits & 0x80)
{
rgb[0] = MSG_ReadShort()/1024.0;
rgb[1] = MSG_ReadShort()/1024.0;
rgb[2] = MSG_ReadShort()/1024.0;
rgb[0] = (bits&1)?MSG_ReadShort()/1024.0:0;
rgb[1] = (bits&2)?MSG_ReadShort()/1024.0:0;
rgb[2] = (bits&4)?MSG_ReadShort()/1024.0:0;
}
else
{
@ -7046,6 +7066,9 @@ void CLQW_ParseServerMessage (void)
rgb[1] = (bits&2)?1:0;
rgb[2] = (bits&4)?1:0;
}
if (i >= MAX_NET_LIGHTSTYLES)
Host_EndGame ("svc_lightstyle > MAX_LIGHTSTYLES");
R_UpdateLightStyle(i, MSG_ReadString(), rgb[0], rgb[1], rgb[2]);
}
break;
@ -8159,7 +8182,7 @@ void CLNQ_ParseServerMessage (void)
break;
case svc_lightstyle:
i = MSG_ReadByte ();
if (i >= MAX_LIGHTSTYLES)
if (i >= MAX_NET_LIGHTSTYLES)
{
Con_Printf("svc_lightstyle: %i >= MAX_LIGHTSTYLES\n", i);
MSG_ReadString();

View file

@ -343,7 +343,7 @@ typedef struct dlight_s
struct {
float updatetime;
} face [6];
int style; //multiply by style values if > 0
int style; //multiply by style values if >= 0 && < MAX_LIGHTSTYLES
float fov; //spotlight
float nearclip; //for spotlights...
struct dlight_s *next;
@ -1060,10 +1060,13 @@ typedef struct
extern entity_state_t *cl_baselines;
extern static_entity_t *cl_static_entities;
extern unsigned int cl_max_static_entities;
extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
extern lightstyle_t *cl_lightstyle;
extern size_t cl_max_lightstyles;
extern dlight_t *cl_dlights;
extern size_t cl_maxdlights;
extern int d_lightstylevalue[MAX_NET_LIGHTSTYLES];
extern size_t rtlights_first, rtlights_max;
extern int cl_baselines_count;

View file

@ -607,13 +607,31 @@ Con_ToggleConsole_f
*/
void Con_ToggleConsole_Force(void)
{
console_t *con = Con_GetMain();
SCR_EndLoadingPlaque();
Key_ClearTyping ();
if (Key_Dest_Has(kdm_console))
Key_Dest_Remove(kdm_console);
if (con->flags & CONF_ISWINDOW)
{
if (con_curwindow == con && Key_Dest_Has(kdm_cwindows))
{
con_curwindow = NULL;
Key_Dest_Remove(kdm_cwindows);
}
else
{
con_curwindow = con;
Key_Dest_Add(kdm_cwindows);
}
}
else
Key_Dest_Add(kdm_console);
{
if (Key_Dest_Has(kdm_console))
Key_Dest_Remove(kdm_console);
else
Key_Dest_Add(kdm_console);
}
}
void Con_ToggleConsole_f (void)
{

View file

@ -513,6 +513,9 @@ void *ReadTargaFile(qbyte *buf, int length, int *width, int *height, uploadfmt_t
red = *data++;
alphabyte = *data++;
break;
default:
blue = green = red = alphabyte = 255;
break;
}
if (*format!=PTI_L8) //keep colours
@ -4153,7 +4156,11 @@ typedef struct {
unsigned int dwFlags;
unsigned int dwFourCC;
unsigned int unk[5];
unsigned int bitcount;
unsigned int redmask;
unsigned int greenmask;
unsigned int bluemask;
unsigned int alphamask;
} ddspixelformat;
typedef struct {
@ -4205,7 +4212,29 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch
if (nummips < 1)
nummips = 1;
if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('D'<<0)|('X'<<8)|('T'<<16)|('1'<<24)))
if (!(fmtheader.ddpfPixelFormat.dwFlags & 4))
{
#define IsPacked(bits,r,g,b,a) fmtheader.ddpfPixelFormat.bitcount==bits&&fmtheader.ddpfPixelFormat.redmask==r&&fmtheader.ddpfPixelFormat.greenmask==g&&fmtheader.ddpfPixelFormat.bluemask==b&&fmtheader.ddpfPixelFormat.alphamask==a
if (IsPacked(24, 0xff0000, 0x00ff00, 0x0000ff, 0))
encoding = PTI_BGR8;
else if (IsPacked(24, 0x000000, 0x00ff00, 0xff0000, 0))
encoding = PTI_RGB8;
else if (IsPacked(32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000))
encoding = PTI_BGRA8;
else if (IsPacked(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000))
encoding = PTI_RGBA8;
else if (IsPacked(32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0))
encoding = PTI_BGRX8;
else if (IsPacked(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0))
encoding = PTI_RGBX8;
else
{
Con_Printf("Unsupported non-fourcc dds in %s\n", fname);
return NULL;
}
#undef IsPacked
}
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('D'<<0)|('X'<<8)|('T'<<16)|('1'<<24)))
{
encoding = PTI_BC1_RGBA; //alpha or not? Assume yes, and let the drivers decide.
// pad = 8;

View file

@ -2878,6 +2878,33 @@ void PM_Command_f(void)
Con_Printf("%s may not be used from gamecode\n", Cmd_Argv(0));
return;
}
if (!strcmp(act, "sources") || !strcmp(act, "addsource"))
{
#ifdef WEBCLIENT
if (Cmd_Argc() == 2)
{
int i;
for (i = 0; i < numdownloadablelists; i++)
Con_Printf("%s %s\n", downloadablelist[i].url, downloadablelist[i].save?"(explicit)":"(implicit)");
Con_Printf("<%i sources>\n", numdownloadablelists);
}
else
{
PM_AddSubList(Cmd_Argv(2), "", true, true);
PM_WriteInstalledPackages();
}
#endif
}
else if (!strcmp(act, "remsource"))
{
#ifdef WEBCLIENT
PM_RemSubList(Cmd_Argv(2));
PM_WriteInstalledPackages();
#endif
}
else
{
if (!loadedinstalled)
PM_UpdatePackageList(false, false);
@ -2888,6 +2915,8 @@ void PM_Command_f(void)
{
const char *status;
char *markup;
if ((p->flags & DPF_HIDDEN) && !(p->flags & (DPF_MARKED|DPF_ENABLED|DPF_PURGE|DPF_CACHED)))
continue;
if (p->flags & DPF_ENABLED)
markup = S_COLOR_GREEN;
else if (p->flags & DPF_CORRUPT)
@ -3001,28 +3030,6 @@ void PM_Command_f(void)
}
Con_Printf("<end of list>\n");
}
#ifdef WEBCLIENT
else if (!strcmp(act, "sources") || !strcmp(act, "addsource"))
{
if (Cmd_Argc() == 2)
{
int i;
for (i = 0; i < numdownloadablelists; i++)
Con_Printf("%s %s\n", downloadablelist[i].url, downloadablelist[i].save?"(explicit)":"(implicit)");
Con_Printf("<%i sources>\n", numdownloadablelists);
}
else
{
PM_AddSubList(Cmd_Argv(2), "", true, true);
PM_WriteInstalledPackages();
}
}
#endif
else if (!strcmp(act, "remsource"))
{
PM_RemSubList(Cmd_Argv(2));
PM_WriteInstalledPackages();
}
else if (!strcmp(act, "apply"))
{
Con_Printf("Applying package changes\n");
@ -3128,6 +3135,7 @@ void PM_Command_f(void)
}
else
Con_Printf("%s: Unknown action %s\nShould be one of list, show, search, upgrade, revert, add, rem, del, changes, apply, sources, addsource, remsource\n", Cmd_Argv(0), act);
}
}
qboolean PM_FindUpdatedEngine(char *syspath, size_t syspathsize)

View file

@ -297,7 +297,7 @@ struct pendingtextureinfo
PTI_2D,
PTI_3D,
PTI_CUBEMAP, //mips are packed (to make d3d11 happy)
PTI_2D_ARRAY, //looks like a 3d texture, but depth doesn't change.
PTI_2D_ARRAY, //looks like a 3d texture, but depth doesn't change with mips.
PTI_CUBEMAP_ARRAY, //looks like PTI_2D_ARRAY, with depth*6
} type;

View file

@ -1047,6 +1047,7 @@ static void P_ResetToDefaults(part_type_t *ptype)
ptype->rotationstartrand = M_PI-ptype->rotationstartmin;
ptype->spawnchance = 1;
ptype->dl_time = 0;
ptype->dl_lightstyle = -1;
VectorSet(ptype->dl_rgb, 1, 1, 1);
ptype->dl_corona_intensity = 0.25;
ptype->dl_corona_scale = 0.5;
@ -2225,7 +2226,7 @@ parsefluid:
else if (!strcmp(var, "lightcubemap"))
ptype->dl_cubemapnum = atoi(value);
else if (!strcmp(var, "lightstyle"))
ptype->dl_lightstyle = bound(0, atoi(value)+1, 256);
ptype->dl_lightstyle = atoi(value);
else if (!strcmp(var, "lightscales"))
{ //ambient diffuse specular
ptype->dl_scales[0] = atof(value);
@ -2584,7 +2585,7 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
Q_strncatz(outstr, va("lighttime %g\n", ptype->dl_time), outstrlen);
Q_strncatz(outstr, va("lightshadows %g\n", (ptype->flags & PT_NODLSHADOW)?0.0f:1.0f), outstrlen);
Q_strncatz(outstr, va("lightcubemap %i\n", ptype->dl_cubemapnum), outstrlen);
Q_strncatz(outstr, va("lightstyle %i\n", ptype->dl_lightstyle-1), outstrlen);
Q_strncatz(outstr, va("lightstyle %i\n", ptype->dl_lightstyle), outstrlen);
Q_strncatz(outstr, va("lightcorona %g %g\n", ptype->dl_corona_intensity, ptype->dl_corona_scale), outstrlen);
Q_strncatz(outstr, va("lightscales %g %g %g\n", ptype->dl_scales[0], ptype->dl_scales[1], ptype->dl_scales[2]), outstrlen);
}
@ -4431,8 +4432,7 @@ static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t axis[3]
dl->flags |= LFLAG_NOSHADOWS;
if (ptype->dl_cubemapnum)
Q_snprintfz(dl->cubemapname, sizeof(dl->cubemapname), "cubemaps/%i", ptype->dl_cubemapnum);
if (ptype->dl_lightstyle > 0)
dl->style = ptype->dl_lightstyle;
dl->style = ptype->dl_lightstyle;
}
if (ptype->numsounds)
{

View file

@ -1156,7 +1156,7 @@ static void QCBUILTIN PF_R_DynamicLight_Set(pubprogfuncs_t *prinst, struct globa
l->rebuildcache = true;
break;
case lfield_style:
l->style = G_FLOAT(OFS_PARM2)+1;
l->style = G_FLOAT(OFS_PARM2);
break;
case lfield_angles:
VectorCopy(G_VECTOR(OFS_PARM2), l->angles);
@ -1248,7 +1248,7 @@ static void QCBUILTIN PF_R_DynamicLight_Get(pubprogfuncs_t *prinst, struct globa
G_FLOAT(OFS_RETURN) = l->flags;
break;
case lfield_style:
G_FLOAT(OFS_RETURN) = l->style-1;
G_FLOAT(OFS_RETURN) = l->style;
break;
case lfield_angles:
VectorCopy(l->angles, G_VECTOR(OFS_RETURN));
@ -4336,7 +4336,7 @@ static void QCBUILTIN PF_cs_lightstyle (pubprogfuncs_t *prinst, struct globalvar
if (prinst->callargc >= 3) //fte is a quakeworld engine
VectorCopy(G_VECTOR(OFS_PARM2), rgb);
if ((unsigned)stnum >= MAX_LIGHTSTYLES)
if ((unsigned)stnum >= cl_max_lightstyles)
{
Con_Printf ("PF_cs_lightstyle: stnum > MAX_LIGHTSTYLES");
return;
@ -4348,7 +4348,7 @@ static void QCBUILTIN PF_getlightstyle (pubprogfuncs_t *prinst, struct globalvar
{
unsigned int stnum = G_FLOAT(OFS_PARM0);
if (stnum >= MAX_LIGHTSTYLES)
if (stnum >= cl_max_lightstyles)
{
VectorSet(G_VECTOR(OFS_PARM1), 0, 0, 0);
G_INT(OFS_RETURN) = 0;
@ -4366,13 +4366,13 @@ static void QCBUILTIN PF_getlightstylergb (pubprogfuncs_t *prinst, struct global
unsigned int stnum = G_FLOAT(OFS_PARM0);
int value; //could be float, but that would exceed the precision of R_AnimateLight
if (stnum >= MAX_LIGHTSTYLES)
if (stnum >= MAX_NET_LIGHTSTYLES)
{
Con_Printf ("PF_getlightstyle: stnum > MAX_LIGHTSTYLES");
return;
}
if (!cl_lightstyle[stnum].length)
if (stnum < cl_max_lightstyles || !cl_lightstyle[stnum].length)
value = ('m'-'a')*22 * r_lightstylescale.value;
else if (cl_lightstyle[stnum].map[0] == '=')
value = atof(cl_lightstyle[stnum].map+1)*256*r_lightstylescale.value;

View file

@ -606,7 +606,7 @@ static void Surf_BuildDeluxMap (model_t *wmodel, msurface_t *surf, qbyte *dest,
vec_t *bnorm;
vec3_t temp;
int stride = lm->width*lm->pixbytes;
int stride;
if (!dest)
return;
@ -643,7 +643,7 @@ static void Surf_BuildDeluxMap (model_t *wmodel, msurface_t *surf, qbyte *dest,
{
case LM_E5BGR9:
deluxmap = ((surf->samples - wmodel->lightdata)/4)*3 + wmodel->deluxdata;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
for (i=0 ; i<size ; i++)
@ -660,7 +660,7 @@ static void Surf_BuildDeluxMap (model_t *wmodel, msurface_t *surf, qbyte *dest,
break;
case LM_RGB8:
deluxmap = surf->samples - wmodel->lightdata + wmodel->deluxdata;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
for (i=0 ; i<size ; i++)
@ -676,7 +676,7 @@ static void Surf_BuildDeluxMap (model_t *wmodel, msurface_t *surf, qbyte *dest,
break;
case LM_L8:
deluxmap = (surf->samples - wmodel->lightdata)*3 + wmodel->deluxdata;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
for (i=0 ; i<size ; i++)
@ -700,24 +700,75 @@ store:
// bound, invert, and shift
stride -= smax*lm->pixbytes;
bnorm = blocknormals[0];
for (i=0 ; i<tmax ; i++, dest += stride)
switch (lm->fmt)
{
for (j=0 ; j<smax ; j++)
default:
Sys_Error("Bad deluxemap format\n");
break;
case PTI_A2BGR10:
{
temp[0] = bnorm[0];
temp[1] = bnorm[1];
temp[2] = bnorm[2]; //half the effect? so we emulate light's scalecos of 0.5
VectorNormalize(temp);
dest[2] = (temp[0]+1)/2*255;
dest[1] = (temp[1]+1)/2*255;
dest[0] = (temp[2]+1)/2*255;
unsigned int *destl = (void*)dest, r;
dest += lm->pixbytes;
bnorm+=3;
stride = (lm->width-smax);
bnorm = blocknormals[0];
for (i=0 ; i<tmax ; i++, destl += stride)
{
for (j=0 ; j<smax ; j++)
{
temp[0] = bnorm[0];
temp[1] = bnorm[1];
temp[2] = bnorm[2]; //half the effect? so we emulate light's scalecos of 0.5
bnorm+=3;
VectorNormalize(temp);
r = (unsigned int)((temp[0]+1)/2*1023)<<0;
r |= (unsigned int)((temp[1]+1)/2*1023)<<10;
r |= (unsigned int)((temp[2]+1)/2*1023)<<20;
*destl++ = r;
}
}
}
break;
case PTI_BGRX8:
stride = (lm->width-smax)*4;
bnorm = blocknormals[0];
for (i=0 ; i<tmax ; i++, dest += stride)
{
for (j=0 ; j<smax ; j++)
{
temp[0] = bnorm[0];
temp[1] = bnorm[1];
temp[2] = bnorm[2]; //half the effect? so we emulate light's scalecos of 0.5
VectorNormalize(temp);
dest[2] = (temp[0]+1)/2*255;
dest[1] = (temp[1]+1)/2*255;
dest[0] = (temp[2]+1)/2*255;
dest += 4;
bnorm+=3;
}
}
break;
case PTI_RGBX8:
case PTI_RGB8:
stride = (lm->width-smax)*lm->pixbytes;
bnorm = blocknormals[0];
for (i=0 ; i<tmax ; i++, dest += stride)
{
for (j=0 ; j<smax ; j++)
{
temp[0] = bnorm[0];
temp[1] = bnorm[1];
temp[2] = bnorm[2]; //half the effect? so we emulate light's scalecos of 0.5
VectorNormalize(temp);
dest[0] = (temp[0]+1)/2*255;
dest[1] = (temp[1]+1)/2*255;
dest[2] = (temp[2]+1)/2*255;
dest += lm->pixbytes;
bnorm+=3;
}
}
break;
}
}
@ -785,7 +836,7 @@ static void Surf_PackRGB16F(void *result, int r, int g, int b, int one)
((unsigned short*)result)[0] = Surf_GenHalf(r / (float)one);
((unsigned short*)result)[1] = Surf_GenHalf(g / (float)one);
((unsigned short*)result)[2] = Surf_GenHalf(b / (float)one);
((unsigned short*)result)[3] = Surf_GenHalf(1.0);//0x0f<<10; //a standard ieee float should have all but the lead bit set of its exponent, and its mantissa 0.
((unsigned short*)result)[3] = /*Surf_GenHalf(1.0);*/0x0f<<10; //a standard ieee float should have all but the lead bit set of its exponent, and its mantissa 0.
#endif
}
static void Surf_PackRGB32F(void *result, int r, int g, int b, int one)
@ -1416,7 +1467,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
switch(currentmodel->lightmaps.fmt)
{
case LM_E5BGR9:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]]; // 8.8 fraction
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
@ -1436,7 +1487,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
}
break;
case LM_RGB8:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
@ -1457,7 +1508,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
break;
case LM_L8:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ;
maps++)
{
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]]; // 8.8 fraction
@ -1536,7 +1587,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
switch(currentmodel->lightmaps.fmt)
{
case LM_E5BGR9:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_light[maps] = scale; // 8.8 fraction
@ -1550,7 +1601,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
}
break;
case LM_RGB8:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_light[maps] = scale; // 8.8 fraction
@ -1561,7 +1612,7 @@ static void Surf_BuildLightMap (model_t *currentmodel, msurface_t *surf, int map
}
break;
case LM_L8:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_light[maps] = scale; // 8.8 fraction
@ -1713,7 +1764,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
else switch(cl.worldmodel->lightmaps.fmt)
{
case LM_E5BGR9:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]]; // 8.8 fraction
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
@ -1733,7 +1784,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
}
break;
case LM_RGB8:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colourkey;
@ -1754,7 +1805,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
break;
case LM_L8:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ;
maps++)
{
surf->cached_light[maps] = scale = d_lightstylevalue[surf->styles[maps]]; // 8.8 fraction
@ -1818,7 +1869,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
switch(cl.worldmodel->lightmaps.fmt)
{
case LM_E5BGR9:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_light[maps] = scale; // 8.8 fraction
@ -1832,7 +1883,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
}
break;
case LM_RGB8:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_light[maps] = scale; // 8.8 fraction
@ -1843,7 +1894,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
}
break;
case LM_L8:
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
surf->cached_light[maps] = scale; // 8.8 fraction
@ -1920,7 +1971,7 @@ void Surf_RenderDynamicLightmaps (msurface_t *fa)
}
else
{
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && fa->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && fa->styles[maps] != INVALID_LIGHTSTYLE ;
maps++)
if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]
|| cl_lightstyle[fa->styles[maps]].colourkey != fa->cached_colour[maps])
@ -1963,7 +2014,7 @@ static void Surf_RenderDynamicLightmaps_Worker (model_t *wmodel, msurface_t *fa,
}
else
{
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && fa->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && fa->styles[maps] != INVALID_LIGHTSTYLE ;
maps++)
if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]
|| cl_lightstyle[fa->styles[maps]].colourkey != fa->cached_colour[maps])
@ -2934,7 +2985,7 @@ struct webostate_s
void *ebomem;
size_t idxcount;
int numbatches;
int lightstylevalues[MAX_LIGHTSTYLES]; //when using workers that only reprocessing lighting at 10fps, things get too ugly when things go out of sync
int lightstylevalues[MAX_NET_LIGHTSTYLES]; //when using workers that only reprocessing lighting at 10fps, things get too ugly when things go out of sync
vec3_t lastpos;
@ -3270,14 +3321,14 @@ void Surf_DrawWorld (void)
#ifdef Q1BSPS
else if (currentmodel->fromgame == fg_quake || currentmodel->fromgame == fg_halflife)
{
int i = MAX_LIGHTSTYLES;
int i = cl_max_lightstyles;
if (webostate && !webogenerating)
for (i = 0; i < MAX_LIGHTSTYLES; i++)
for (i = 0; i < cl_max_lightstyles; i++)
{
if (webostate->lightstylevalues[i] != d_lightstylevalue[i])
break;
}
if (webostate && i == MAX_LIGHTSTYLES)
if (webostate && i == cl_max_lightstyles)
{
}
else
@ -3304,7 +3355,7 @@ void Surf_DrawWorld (void)
webogenerating->cluster[1] = r_viewcluster2;
webogenerating->pvs.buffer = (qbyte*)(webogenerating+1) + sizeof(webogenerating->batches[0])*(currentmodel->numbatches-1);
webogenerating->pvs.buffersize = currentmodel->pvsbytes;
for (i = 0; i < MAX_LIGHTSTYLES; i++)
for (i = 0; i < cl_max_lightstyles; i++)
webogenerating->lightstylevalues[i] = d_lightstylevalue[i];
Q_strncpyz(webogenerating->dbgid, "webostate", sizeof(webogenerating->dbgid));
COM_AddWork(WG_LOADER, R_GenWorldEBO, webogenerating, NULL, 0, 0);
@ -3630,7 +3681,7 @@ uploadfmt_t Surf_NameToFormat(const char *nam)
return PTI_RGB565; //boo hiss
if (!Q_strcasecmp(nam, "rgba4444") || !Q_strcasecmp(nam, "rgba4"))
return PTI_RGBA4444; //erk
if (!Q_strcasecmp(nam, "rgba5551") || !Q_strcasecmp(nam, "rgba51"))
if (!Q_strcasecmp(nam, "rgba5551") || !Q_strcasecmp(nam, "rgba51") || !Q_strcasecmp(nam, "rgb5a1"))
return PTI_RGBA5551;
if (!Q_strcasecmp(nam, "argb4444"))
return PTI_ARGB4444;
@ -3639,7 +3690,7 @@ uploadfmt_t Surf_NameToFormat(const char *nam)
if (!Q_strcasecmp(nam, "rgbx8") || !Q_strcasecmp(nam, "bgrx8") || !Q_strcasecmp(nam, "rgba8") || !Q_strcasecmp(nam, "bgra8"))
return PTI_BGRX8; //most common formats...
if (!Q_strcasecmp(nam, "rgb8") || !Q_strcasecmp(nam, "bgr8"))
return PTI_RGB8; //generally not recommended
return PTI_RGB8; //generally not recommended (misaligned so the gpu has to compensate)
if (!Q_strcasecmp(nam, "l8"))
return PTI_L8;
if (*nam)
@ -3725,7 +3776,9 @@ int Surf_NewLightmaps(int count, int width, int height, uploadfmt_t fmt, qboolea
Image_BlockSizeForEncoding(fmt, &pixbytes, &pixw, &pixh);
if (pixw != 1 || pixh != 1)
return -1; //compressed formats are unsupported
dfmt = PTI_BGRX8;
dfmt = PTI_A2BGR10; //favour this one, because it tends to be slightly faster.
if (!sh_config.texfmt[dfmt])
dfmt = PTI_BGRX8;
if (!sh_config.texfmt[dfmt])
dfmt = PTI_RGBX8;
if (!sh_config.texfmt[dfmt])
@ -3884,6 +3937,8 @@ void Surf_BuildModelLightmaps (model_t *m)
COM_WorkerPartialSync(webogenerating, &webogeneratingstate, true);
#endif
R_BumpLightstyles(m->lightmaps.maxstyle); //should only really happen with lazy loading
if (m->submodelof && m->fromgame == fg_quake3) //FIXME: should be all bsp formats
{
if (m->submodelof->loadstate != MLS_LOADED)
@ -4083,7 +4138,17 @@ void Surf_BuildLightmaps (void)
extern model_t *mod_known;
extern int mod_numknown;
//make sure the lightstyle values are correct.
int maxstyle;
//make sure the lightstyle values are correct (and be sure that the sizes cover all models).
for (i = 0, maxstyle=0; i < mod_numknown; i++)
{
m = &mod_known[i];
if (m->loadstate == MLS_LOADED)
if (maxstyle < m->lightmaps.maxstyle)
maxstyle = m->lightmaps.maxstyle;
}
R_BumpLightstyles(maxstyle); //should only really happen with lazy loading
R_AnimateLight();
r_framecount = 1; // no dlightcache

View file

@ -531,7 +531,9 @@ typedef struct
{
unsigned int *offsets;
unsigned short *extents;
unsigned char *styles;
unsigned char *styles8;
unsigned short *styles16;
unsigned int stylesperface;
unsigned char *shifts;
unsigned char defaultshift;
} lightmapoverrides_t;
@ -555,7 +557,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], 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.
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, lightstyleindex_t 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);
@ -587,6 +589,7 @@ void R_RegisterRenderer(rendererinfo_t *ri);
void R_AnimateLight (void);
void R_UpdateHDR(vec3_t org);
void R_UpdateLightStyle(unsigned int style, const char *stylestring, float r, float g, float b);
void R_BumpLightstyles(unsigned int maxstyle); //bumps the cl_max_lightstyles array size, if needed.
struct texture_s *R_TextureAnimation (int frame, struct texture_s *base); //mostly deprecated, only lingers for rtlights so world only.
struct texture_s *R_TextureAnimation_Q2 (struct texture_s *base); //mostly deprecated, only lingers for rtlights so world only.
void RQ_Init(void);

View file

@ -68,6 +68,11 @@ void R_ForceSky_f(void)
R_SetSky(Cmd_Argv(1));
}
}
static void QDECL R_Lightmap_Format_Changed(struct cvar_s *var, char *oldvalue)
{
if (qrenderer)
Surf_BuildLightmaps();
}
#ifdef FTE_TARGET_WEB //webgl sucks too much to get a stable framerate without vsync.
cvar_t vid_vsync = CVARAF ("vid_vsync", "1",
@ -231,7 +236,7 @@ cvar_t r_replacemodels = CVARFD ("r_replacemodels", IFMINIMAL("","md3 md2")
cvar_t r_lightmap_nearest = CVARFD ("gl_lightmap_nearest", "0", CVAR_ARCHIVE, "Use nearest sampling for lightmaps. This will give a more blocky look. Meaningless when gl_lightmap_average is enabled.");
cvar_t r_lightmap_average = CVARFD ("gl_lightmap_average", "0", CVAR_ARCHIVE, "Determine lightmap values based upon the center of the polygon. This will give a more buggy look, quite probably.");
cvar_t r_lightmap_format = CVARFD ("r_lightmap_format", "", CVAR_ARCHIVE|CVAR_RENDERERCALLBACK, "Overrides the default texture format used for lightmaps. rgb9e5 is a good choice for HDR.");
cvar_t r_lightmap_format = CVARFCD ("r_lightmap_format", "", CVAR_ARCHIVE, R_Lightmap_Format_Changed, "Overrides the default texture format used for lightmaps. rgb9e5 is a good choice for HDR.");
//otherwise it would defeat the point.
cvar_t scr_allowsnap = CVARF ("scr_allowsnap", "1",

View file

@ -828,6 +828,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MAX_BACKBUFLEN 1200
#define lightstyleindex_t unsigned short
#define INVALID_LIGHTSTYLE ((lightstyleindex_t)(~0u)) //the style that's invalid, signifying to stop adding more.
//
// per-level limits
//
@ -837,7 +840,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//#define MAX_EDICTS ((1<<22)-1) // expandable up to 22 bits
#define MAX_EDICTS ((1<<18)-1) // expandable up to 22 bits
#endif
#define MAX_LIGHTSTYLES 255 // 8bit. 255 = 'invalid', and thus only 0-254 are the valid indexes.
#define MAX_NET_LIGHTSTYLES (INVALID_LIGHTSTYLE+1) // 16bit. the last index MAY be used to signify an invalid lightmap in the bsp, but is still valid for rtlights.
#define MAX_STANDARDLIGHTSTYLES 64
#define MAX_PRECACHE_MODELS 4096 // 14bit.
#define MAX_PRECACHE_SOUNDS 2048 // 14bit.

View file

@ -239,7 +239,7 @@ typedef struct
#else
#define MAXRLIGHTMAPS 1 //max lightmaps mixed by the renderer (rbsp=4, otherwise 1)
#endif
#define MAXQ1LIGHTMAPS 4
#define MAXQ1LIGHTMAPS 16
typedef struct
{
short planenum;
@ -250,7 +250,7 @@ typedef struct
short texinfo;
// lighting info
qbyte styles[MAXQ1LIGHTMAPS];
qbyte styles[4];
int lightofs; // start of [numstyles*surfsize] samples
} dsface_t;
typedef struct
@ -263,7 +263,7 @@ typedef struct
int texinfo;
// lighting info
qbyte styles[MAXQ1LIGHTMAPS];
qbyte styles[4];
int lightofs; // start of [numstyles*surfsize] samples
} dlface_t;

View file

@ -1573,30 +1573,19 @@ Mod_LoadFaces
=================
*/
#ifndef SERVERONLY
static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, qboolean lightofsisdouble, lightmapoverrides_t *overrides)
static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, lump_t *lightlump, qboolean lightofsisdouble, bspx_header_t *bspx)
{
dsface_t *in;
msurface_t *out;
int i, count, surfnum;
int planenum, side;
int ti;
int style;
unsigned short lmshift, lmscale;
char buf[64];
if (overrides->offsets)
lmshift = overrides->defaultshift;
else
{
lmscale = atoi(Mod_ParseWorldspawnKey(mod, "lightmap_scale", buf, sizeof(buf)));
if (!lmscale)
lmshift = LMSHIFT_DEFAULT;
else
{
for(lmshift = 0; lmscale > 1; lmshift++)
lmscale >>= 1;
}
}
lightmapoverrides_t overrides = {0};
overrides.defaultshift = LMSHIFT_DEFAULT;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
@ -1610,6 +1599,21 @@ static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, qboo
mod->surfaces = out;
mod->numsurfaces = count;
Mod_LoadLighting(mod, bspx, mod_base, lightlump, lightofsisdouble, &overrides);
if (overrides.offsets)
lmshift = overrides.defaultshift;
else
{
lmscale = atoi(Mod_ParseWorldspawnKey(mod, "lightmap_scale", buf, sizeof(buf)));
if (!lmscale)
lmshift = LMSHIFT_DEFAULT;
else
{
for(lmshift = 0; lmscale > 1; lmshift++)
lmscale >>= 1;
}
}
for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
{
out->firstedge = LittleLong(in->firstedge);
@ -1642,23 +1646,58 @@ static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, qboo
}
#endif
if (overrides->shifts)
out->lmshift = overrides->shifts[surfnum];
if (overrides.shifts)
out->lmshift = overrides.shifts[surfnum];
else
out->lmshift = lmshift;
CalcSurfaceExtents (mod, out);
if (overrides->extents)
if (overrides.extents)
{
out->extents[0] = overrides->extents[surfnum*2+0];
out->extents[1] = overrides->extents[surfnum*2+1];
out->extents[0] = overrides.extents[surfnum*2+0];
out->extents[1] = overrides.extents[surfnum*2+1];
}
// lighting info
for (i=0 ; i<MAXQ1LIGHTMAPS ; i++)
out->styles[i] = in->styles[i];
if (overrides->offsets)
i = overrides->offsets[surfnum];
if (overrides.styles16)
{
for (i=0 ; i<overrides.stylesperface ; i++)
{
style = overrides.styles16[surfnum*overrides.stylesperface+i];
if (style == 0xffff)
style = INVALID_LIGHTSTYLE;
else if (mod->lightmaps.maxstyle < style)
mod->lightmaps.maxstyle = style;
out->styles[i] = style;
}
}
else if (overrides.styles8)
{
for (i=0 ; i<overrides.stylesperface ; i++)
{
style = overrides.styles8[surfnum*overrides.stylesperface+i];
if (style == 0xff)
style = INVALID_LIGHTSTYLE;
else if (mod->lightmaps.maxstyle < style)
mod->lightmaps.maxstyle = style;
out->styles[i] = style;
}
}
else
{
for (i=0 ; i<4 ; i++)
{
style = in->styles[i];
if (style == 0xff)
style = INVALID_LIGHTSTYLE;
else if (mod->lightmaps.maxstyle < style)
mod->lightmaps.maxstyle = style;
out->styles[i] = style;
}
}
for ( ; i<MAXQ1LIGHTMAPS ; i++)
out->styles[i] = INVALID_LIGHTSTYLE;
if (overrides.offsets)
i = overrides.offsets[surfnum];
else
i = LittleLong(in->lightofs);
if (i == -1)
@ -1679,12 +1718,6 @@ static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, qboo
out->texturemins[i] = -8192;
}
}
if (overrides->extents)
{
for (i=0 ; i<MAXQ1LIGHTMAPS ; i++)
out->styles[i] = overrides->extents[surfnum*4+i];
}
}
return true;
@ -4631,22 +4664,18 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
#ifndef SERVERONLY
default:
{
lightmapoverrides_t overrides = {0};
overrides.defaultshift = LMSHIFT_DEFAULT;
// load into heap
noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header.lumps[Q2LUMP_VERTEXES]);
if (header.version == BSPVERSION_Q2W)
/*noerrors = noerrors &&*/ Mod_LoadVertexNormals(mod, bspx, mod_base, &header.lumps[19]);
noerrors = noerrors && Mod_LoadEdges (mod, mod_base, &header.lumps[Q2LUMP_EDGES], false);
noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[Q2LUMP_SURFEDGES]);
if (noerrors)
Mod_LoadLighting (mod, bspx, mod_base, &header.lumps[Q2LUMP_LIGHTING], header.version == BSPVERSION_Q2W, &overrides);
noerrors = noerrors && CModQ2_LoadSurfaces (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO]);
noerrors = noerrors && CModQ2_LoadPlanes (mod, mod_base, &header.lumps[Q2LUMP_PLANES]);
noerrors = noerrors && CModQ2_LoadTexInfo (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO], loadname);
if (noerrors)
Mod_LoadEntities (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]);
noerrors = noerrors && CModQ2_LoadFaces (mod, mod_base, &header.lumps[Q2LUMP_FACES], header.version == BSPVERSION_Q2W, &overrides);
noerrors = noerrors && CModQ2_LoadFaces (mod, mod_base, &header.lumps[Q2LUMP_FACES], &header.lumps[Q2LUMP_LIGHTING], header.version == BSPVERSION_Q2W, bspx);
noerrors = noerrors && Mod_LoadMarksurfaces (mod, mod_base, &header.lumps[Q2LUMP_LEAFFACES], false);
noerrors = noerrors && CModQ2_LoadVisibility (mod, mod_base, &header.lumps[Q2LUMP_VISIBILITY]);
noerrors = noerrors && CModQ2_LoadBrushSides (mod, mod_base, &header.lumps[Q2LUMP_BRUSHSIDES]);

View file

@ -5651,7 +5651,7 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
{
if (br->faces[j].relight && dorelight)
{
qbyte styles[4] = {0,255,255,255};
lightstyleindex_t styles[4] = {0,INVALID_LIGHTSTYLE,INVALID_LIGHTSTYLE,INVALID_LIGHTSTYLE};
int texsize[2] = {br->faces[j].lmextents[0]-1, br->faces[j].lmextents[1]-1};
vec2_t exactmins, exactmaxs;
int m, k;

View file

@ -1952,7 +1952,8 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
//surface code needs to know the overrides.
overrides->offsets = offsets;
overrides->extents = extents;
overrides->styles = styles;
overrides->styles8 = styles;
overrides->stylesperface = 4;
overrides->shifts = shifts;
//we're now using this amount of data.
@ -2178,12 +2179,25 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
if (size != loadmodel->numsurfaces * sizeof(int))
overrides->offsets = NULL;
}
if (!overrides->styles)
{
if (!overrides->styles8 && !overrides->styles16)
{ //16bit per-face lightmap styles index
int size;
overrides->styles = BSPX_FindLump(bspx, mod_base, "LMSTYLE", &size);
if (size != loadmodel->numsurfaces * sizeof(qbyte)*MAXQ1LIGHTMAPS)
overrides->styles = NULL;
overrides->styles16 = BSPX_FindLump(bspx, mod_base, "LMSTYLE16", &size);
overrides->stylesperface = size / (sizeof(*overrides->styles16)*loadmodel->numsurfaces); //rounding issues will be caught on the next line...
if (!overrides->stylesperface || size != loadmodel->numsurfaces * sizeof(*overrides->styles16)*overrides->stylesperface)
overrides->styles16 = NULL;
else if (overrides->stylesperface > MAXQ1LIGHTMAPS)
Con_Printf(CON_WARNING "LMSTYLE16 lump provides %i styles, only the first %i will be used.\n", overrides->stylesperface, MAXQ1LIGHTMAPS);
}
if (!overrides->styles8 && !overrides->styles16)
{ //16bit per-face lightmap styles index
int size;
overrides->styles8 = BSPX_FindLump(bspx, mod_base, "LMSTYLE", &size);
overrides->stylesperface = size / (sizeof(*overrides->styles8)*loadmodel->numsurfaces); //rounding issues will be caught on the next line...
if (!overrides->stylesperface || size != loadmodel->numsurfaces * sizeof(*overrides->styles8)*overrides->stylesperface)
overrides->styles8 = NULL;
else if (overrides->stylesperface > MAXQ1LIGHTMAPS)
Con_Printf(CON_WARNING "LMSTYLE lump provides %i styles, only the first %i will be used.\n", overrides->stylesperface, MAXQ1LIGHTMAPS);
}
}
@ -4042,8 +4056,8 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
out->firstedge = LittleLong(inl->firstedge);
out->numedges = LittleLong(inl->numedges);
tn = LittleLong (inl->texinfo);
for (i=0 ; i<MAXQ1LIGHTMAPS ; i++)
out->styles[i] = inl->styles[i];
for (i=0 ; i<countof(out->styles) ; i++)
out->styles[i] = (i >= countof(inl->styles) || inl->styles[i]>=MAX_NET_LIGHTSTYLES || inl->styles[i]==255)?INVALID_LIGHTSTYLE:inl->styles[i];
lofs = LittleLong(inl->lightofs);
inl++;
}
@ -4054,8 +4068,8 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
out->firstedge = LittleLong(ins->firstedge);
out->numedges = LittleShort(ins->numedges);
tn = LittleShort (ins->texinfo);
for (i=0 ; i<MAXQ1LIGHTMAPS ; i++)
out->styles[i] = ins->styles[i];
for (i=0 ; i<countof(out->styles) ; i++)
out->styles[i] = (i >= countof(ins->styles) || ins->styles[i]>=MAX_NET_LIGHTSTYLES || ins->styles[i]==255)?INVALID_LIGHTSTYLE:ins->styles[i];
lofs = LittleLong(ins->lightofs);
ins++;
}
@ -4081,9 +4095,19 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
out->lmshift = lmshift;
if (overrides.offsets)
lofs = overrides.offsets[surfnum];
if (overrides.styles)
for (i=0 ; i<MAXRLIGHTMAPS ; i++)
out->styles[i] = overrides.styles[surfnum*4+i];
if (overrides.styles16)
{
for (i=0 ; i<countof(out->styles) ; i++)
out->styles[i] = (i>=overrides.stylesperface)?INVALID_LIGHTSTYLE:overrides.styles16[surfnum*overrides.stylesperface+i];
}
else if (overrides.styles8)
{
for (i=0 ; i<countof(out->styles) ; i++)
out->styles[i] = (i>=overrides.stylesperface)?INVALID_LIGHTSTYLE:((overrides.styles8[surfnum*overrides.stylesperface+i]==255)?~0u:overrides.styles8[surfnum*overrides.stylesperface+i]);
}
for (i=0 ; i<countof(out->styles) && out->styles[i] != INVALID_LIGHTSTYLE; i++)
if (loadmodel->lightmaps.maxstyle < out->styles[i])
loadmodel->lightmaps.maxstyle = out->styles[i];
CalcSurfaceExtents (loadmodel, out);
if (lofs != (unsigned int)-1)

View file

@ -140,7 +140,7 @@ typedef struct batch_s
image_t *envmap;
short lightmap[MAXRLIGHTMAPS]; /*used for shader lightmap textures*/
unsigned char lmlightstyle[MAXRLIGHTMAPS];
lightstyleindex_t lmlightstyle[MAXRLIGHTMAPS];
unsigned char vtlightstyle[MAXRLIGHTMAPS];
unsigned int maxmeshes; /*not used by backend*/
@ -444,7 +444,7 @@ typedef struct msurface_s
//static lighting
int lightmaptexturenums[MAXRLIGHTMAPS]; //rbsp+fbsp formats have multiple lightmaps
qbyte styles[MAXQ1LIGHTMAPS];
lightstyleindex_t styles[MAXQ1LIGHTMAPS];
qbyte vlstyles[MAXRLIGHTMAPS];
int cached_light[MAXQ1LIGHTMAPS]; // values currently used in lightmap
int cached_colour[MAXQ1LIGHTMAPS]; // values currently used in lightmap
@ -1026,6 +1026,7 @@ typedef struct model_s
int width; //x size of lightmaps
int height; //y size of lightmaps
int surfstyles; //numbers of style per surface.
int maxstyle; //highest (valid) style used (cl_max_lightstyles must be 1+ higher).
enum {
//vanilla used byte values, with 255 being a value of about 2.
//float/hdr formats use 1 to mean 1, however.

View file

@ -28,13 +28,25 @@ extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_lightmaps;
extern cvar_t r_hdr_irisadaptation, r_hdr_irisadaptation_multiplier, r_hdr_irisadaptation_minvalue, r_hdr_irisadaptation_maxvalue, r_hdr_irisadaptation_fade_down, r_hdr_irisadaptation_fade_up;
int r_dlightframecount;
int d_lightstylevalue[256]; // 8.8 fraction of base light value
int d_lightstylevalue[MAX_NET_LIGHTSTYLES]; // 8.8 fraction of base light value
void R_BumpLightstyles(unsigned int maxstyle)
{
int style = cl_max_lightstyles;
if (maxstyle >= style)
{
Z_ReallocElements((void**)&cl_lightstyle, &cl_max_lightstyles, maxstyle+1, sizeof(*cl_lightstyle));
for (; style < cl_max_lightstyles; style++)
VectorSet(cl_lightstyle[style].colours, 1,1,1);
}
}
void R_UpdateLightStyle(unsigned int style, const char *stylestring, float r, float g, float b)
{
if (style >= MAX_LIGHTSTYLES)
if (style >= MAX_NET_LIGHTSTYLES)
return;
R_BumpLightstyles(style);
if (!stylestring)
stylestring = "";
@ -109,7 +121,7 @@ void R_AnimateLight (void)
i = (int)f;
f -= i; //this can require updates at 1000 times a second.. Depends on your framerate of course
for (j=0 ; j<MAX_LIGHTSTYLES ; j++)
for (j=0 ; j<cl_max_lightstyles ; j++)
{
int v1, v2, vd;
if (!cl_lightstyle[j].length)
@ -301,9 +313,9 @@ static qboolean R_BuildDlightMesh(dlight_t *light, float colscale, float radscal
rad *= a;
rad *= 0.33;
}
if (light->style)
if (light->style>=0 && light->style < countof(d_lightstylevalue))
{
colscale *= d_lightstylevalue[light->style-1]/255.0f;
colscale *= d_lightstylevalue[light->style]/255.0f;
}
VectorSubtract (light->origin, r_origin, v);
@ -527,11 +539,11 @@ void R_GenDlightMesh(struct batch_s *batch)
int lightflags = batch->surf_count;
VectorCopy(l->color, colour);
if (l->style)
if (l->style>=0 && l->style < cl_max_lightstyles)
{
colour[0] *= cl_lightstyle[l->style-1].colours[0] * d_lightstylevalue[l->style-1]/255.0f;
colour[1] *= cl_lightstyle[l->style-1].colours[1] * d_lightstylevalue[l->style-1]/255.0f;
colour[2] *= cl_lightstyle[l->style-1].colours[2] * d_lightstylevalue[l->style-1]/255.0f;
colour[0] *= cl_lightstyle[l->style].colours[0] * d_lightstylevalue[l->style]/255.0f;
colour[1] *= cl_lightstyle[l->style].colours[1] * d_lightstylevalue[l->style]/255.0f;
colour[2] *= cl_lightstyle[l->style].colours[2] * d_lightstylevalue[l->style]/255.0f;
}
else
{
@ -1127,7 +1139,7 @@ qboolean R_ImportRTLights(const char *entlump)
dl->flags |= LFLAG_REALTIMEMODE;
dl->flags |= (pflags & PFLAGS_CORONA)?LFLAG_FLASHBLEND:0;
dl->flags |= (pflags & PFLAGS_NOSHADOW)?LFLAG_NOSHADOWS:0;
dl->style = style+1;
dl->style = style;
VectorCopy(colourscales, dl->lightcolourscales);
//handle spotlights.
@ -1348,7 +1360,7 @@ qboolean R_LoadRTLights(void)
else
dl->cubetexture = r_nulltex;
dl->style = style+1;
dl->style = style;
dl->customstyle = (*customstyle)?Z_StrDup(customstyle):NULL;
}
file = end+1;
@ -1402,7 +1414,7 @@ static void R_SaveRTLights_f(void)
"%i",
(light->flags & LFLAG_NOSHADOWS)?"!":"", light->origin[0], light->origin[1], light->origin[2],
light->radius, light->color[0], light->color[1], light->color[2],
light->style-1);
light->style);
if (ver > 0)
VFS_PRINTF(f, " \"%s\" %f %f %f %f", light->cubemapname, light->corona, ang[0], ang[1], ang[2]);
if (ver > 1)
@ -1457,7 +1469,7 @@ void R_StaticEntityToRTLight(int i)
dl->flags |= (state->lightpflags & PFLAGS_NOSHADOW)?LFLAG_NOSHADOWS:0;
if (state->lightpflags & PFLAGS_CORONA)
dl->corona = 1;
dl->style = state->lightstyle+1;
dl->style = state->lightstyle;
if (state->lightpflags & PFLAGS_FULLDYNAMIC)
{
dl->lightcolourscales[0] = r_editlights_import_ambient.value;
@ -1612,7 +1624,7 @@ static int R_EditLight(dlight_t *dl, const char *cmd, int argc, const char *x, c
else if (!strcmp(cmd, "radiusscale") || !strcmp(cmd, "sizescale"))
dl->radius *= atof(x);
else if (!strcmp(cmd, "style"))
dl->style = atoi(x)+1; //fte's styles are internally 1-based, with 0 being a null style that ignores lightstyles entirely, which admittedly isn't often used.
dl->style = atoi(x);
else if (!strcmp(cmd, "stylestring"))
{
Z_Free(dl->customstyle);
@ -1690,7 +1702,7 @@ void R_EditLights_DrawInfo(void)
,dl->origin[0],dl->origin[1],dl->origin[2]
,dl->angles[0],dl->angles[1],dl->angles[2]
,dl->color[0],dl->color[1],dl->color[2]
,dl->radius, dl->corona, dl->style-1, dl->customstyle?dl->customstyle:"---"
,dl->radius, dl->corona, dl->style, dl->customstyle?dl->customstyle:"---"
,((dl->flags&LFLAG_NOSHADOWS)?"no":"yes"), dl->cubemapname, dl->coronascale
,dl->lightcolourscales[0], dl->lightcolourscales[1], dl->lightcolourscales[2]
,((dl->flags&LFLAG_NORMALMODE)?"yes":"no"), ((dl->flags&LFLAG_REALTIMEMODE)?"yes":"no")
@ -1878,7 +1890,7 @@ static void R_EditLights_Edit_f(void)
Con_Printf("Colour : ^[%f %f %f\\type\\r_editlights_edit avel %g %g %g^]\n", dl->color[0],dl->color[1],dl->color[2], dl->color[0],dl->color[1],dl->color[2]);
Con_Printf("Radius : ^[%f\\type\\r_editlights_edit radius %g^]\n", dl->radius, dl->radius);
Con_Printf("Corona : ^[%f\\type\\r_editlights_edit corona %g^]\n", dl->corona, dl->corona);
Con_Printf("Style : ^[%i\\type\\r_editlights_edit style %i^]\n", dl->style-1, dl->style-1);
Con_Printf("Style : ^[%i\\type\\r_editlights_edit style %i^]\n", dl->style, dl->style);
Con_Printf("Style String : ^[%s\\type\\r_editlights_edit stylestring %s^]\n", dl->customstyle?dl->customstyle:"---", dl->customstyle?dl->customstyle:"");
Con_Printf("Shadows : ^[%s\\type\\r_editlights_edit shadows %s^]\n", ((dl->flags&LFLAG_NOSHADOWS)?"no":"yes"), ((dl->flags&LFLAG_NOSHADOWS)?"no":"yes"));
Con_Printf("Cubemap : ^[\"%s\"\\type\\r_editlights_edit cubemap \"%s\"^]\n", dl->cubemapname, dl->cubemapname);
@ -1968,7 +1980,7 @@ static void R_EditLights_Spawn_f(void)
VectorCopy(r_editlights_cursor, dl->origin);
dl->radius = 200;
dl->style = 1; //0... gah. match DP's results.
dl->style = 0; //styled, but mostly static (we could use -1, but mneh).
dl->lightcolourscales[0] = 0;
dl->lightcolourscales[1] = 1;
dl->lightcolourscales[2] = 1;
@ -2161,7 +2173,7 @@ static char *r_editlights_current_style(void)
return "";
dl = &cl_dlights[i];
Q_snprintfz (macro_buf, sizeof(macro_buf), "%i", dl->style-1);
Q_snprintfz (macro_buf, sizeof(macro_buf), "%i", dl->style);
return macro_buf;
}
static char *r_editlights_current_shadows(void)
@ -2509,7 +2521,7 @@ static int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
{
case LM_E5BGR9:
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)<<2;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
unsigned int l = *(unsigned int*)lightmap;
scale = d_lightstylevalue[surf->styles[maps]];
@ -2522,7 +2534,7 @@ static int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
break;
case LM_RGB8:
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
r += max3(lightmap[0],lightmap[1],lightmap[2]) * scale;
@ -2531,7 +2543,7 @@ static int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
break;
case LM_L8:
lightmap += dt * ((surf->extents[0]>>surf->lmshift)+1) + ds;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
r += *lightmap * scale;
@ -2683,7 +2695,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)<<2;
deluxmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)<<4;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
unsigned int lm = *(unsigned int*)lightmap;
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
@ -2708,7 +2720,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
deluxmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
@ -2731,7 +2743,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds);
deluxmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
@ -2758,7 +2770,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
{
case LM_E5BGR9:
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)<<2;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
unsigned int lm = *(unsigned int*)lightmap;
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
@ -2774,7 +2786,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
break;
case LM_RGB8:
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]*overbright;
@ -2788,7 +2800,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t
break;
case LM_L8:
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds);
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]*overbright;

View file

@ -3791,11 +3791,11 @@ void Sh_CalcPointLight(vec3_t point, vec3_t light)
colour[0] = dl->color[0];
colour[1] = dl->color[1];
colour[2] = dl->color[2];
if (dl->style)
if (dl->style>=0 && dl->style<cl_max_lightstyles)
{
colour[0] *= cl_lightstyle[dl->style-1].colours[0] * d_lightstylevalue[dl->style-1]/255.0f;
colour[1] *= cl_lightstyle[dl->style-1].colours[1] * d_lightstylevalue[dl->style-1]/255.0f;
colour[2] *= cl_lightstyle[dl->style-1].colours[2] * d_lightstylevalue[dl->style-1]/255.0f;
colour[0] *= cl_lightstyle[dl->style].colours[0] * d_lightstylevalue[dl->style]/255.0f;
colour[1] *= cl_lightstyle[dl->style].colours[1] * d_lightstylevalue[dl->style]/255.0f;
colour[2] *= cl_lightstyle[dl->style].colours[2] * d_lightstylevalue[dl->style]/255.0f;
}
else
{
@ -3924,11 +3924,11 @@ void Sh_DrawLights(qbyte *vis)
colour[1] *= strength;
colour[2] *= strength;
}
if (dl->style)
if (dl->style>=0 && dl->style < cl_max_lightstyles)
{
colour[0] *= cl_lightstyle[dl->style-1].colours[0] * d_lightstylevalue[dl->style-1]/255.0f;
colour[1] *= cl_lightstyle[dl->style-1].colours[1] * d_lightstylevalue[dl->style-1]/255.0f;
colour[2] *= cl_lightstyle[dl->style-1].colours[2] * d_lightstylevalue[dl->style-1]/255.0f;
colour[0] *= cl_lightstyle[dl->style].colours[0] * d_lightstylevalue[dl->style]/255.0f;
colour[1] *= cl_lightstyle[dl->style].colours[1] * d_lightstylevalue[dl->style]/255.0f;
colour[2] *= cl_lightstyle[dl->style].colours[2] * d_lightstylevalue[dl->style]/255.0f;
}
else
{

View file

@ -322,7 +322,6 @@ extern unsigned int r_viewcontents;
int r_viewarea;
extern int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; //q2
extern texture_t *r_notexture_mip;
extern int d_lightstylevalue[256]; // 8.8 fraction of base light value
extern texid_t netgraphtexture; // netgraph texture
extern shader_t *netgraphshader;

View file

@ -778,7 +778,7 @@ static unsigned int PackE5BRG9(vec3_t rgb)
LightFace
============
*/
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)
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, lightstyleindex_t 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;
@ -827,7 +827,7 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_s
i = 0;
#ifndef UTILITY
for (; surf_styles[i] != 255 && i < MAXQ1LIGHTMAPS; i++)
for (; surf_styles[i] != INVALID_LIGHTSTYLE && i < MAXQ1LIGHTMAPS; i++)
{
l->lightstyles[i] = surf_styles[i];
memset(&l->lightmaps[i], 0, sizeof(l->lightmaps[i][0])*l->numsurfpt);
@ -836,7 +836,7 @@ void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_s
#endif
l->numlightstyles = i;
for ( ; i<MAXQ1LIGHTMAPS ; i++)
l->lightstyles[i] = 255;
l->lightstyles[i] = INVALID_LIGHTSTYLE;
//
// cast all lights

View file

@ -107,6 +107,7 @@ static cvar_t sv_addon[MAXADDONS];
static char cvargroup_progs[] = "Progs variables";
static evalc_t evalc_idealpitch, evalc_pitch_speed;
static void PR_Lightstyle_f(void);
qboolean ssqc_deprecated_warned;
int pr_teamfield;
@ -859,11 +860,14 @@ void PR_Deinit(void)
sv.world.progs = NULL;
svprogfuncs=NULL;
for (i = 0; i < MAX_LIGHTSTYLES; i++)
for (i = 0; i < sv.maxlightstyles; i++)
{
BZ_Free((void*)sv.strings.lightstyles[i]);
sv.strings.lightstyles[i] = NULL;
BZ_Free((void*)sv.lightstyles[i].str);
sv.lightstyles[i].str = NULL;
}
BZ_Free(sv.lightstyles);
sv.lightstyles = NULL;
sv.maxlightstyles = 0;
}
World_Destroy(&sv.world);
@ -1547,6 +1551,8 @@ void PR_Init(void)
Cmd_AddCommand ("extensionlist_ssqc", PR_SVExtensionList_f);
Cmd_AddCommand ("pr_dumpplatform", PR_DumpPlatform_f);
Cmd_AddCommand ("sv_lightstyle", PR_Lightstyle_f);
/*
#ifdef _DEBUG
Cmd_AddCommand ("svtestprogs", QCLibTest);
@ -4649,7 +4655,7 @@ void QCBUILTIN PF_applylightstyle(int style, const char *val, vec3_t rgb)
client_t *client;
int j;
if (style < 0 || style >= MAX_LIGHTSTYLES)
if (style < 0 || style >= MAX_NET_LIGHTSTYLES)
{
Con_Printf("WARNING: Bad lightstyle %i.\n", style);
return;
@ -4657,14 +4663,16 @@ void QCBUILTIN PF_applylightstyle(int style, const char *val, vec3_t rgb)
if (strlen(val) >= 64)
Con_Printf("WARNING: Style string is longer than standard (%i). Some clients could crash.\n", 63);
if (style+1 > sv.maxlightstyles)
Z_ReallocElements((void**)&sv.lightstyles, &sv.maxlightstyles, style+1, sizeof(*sv.lightstyles));
// change the string in sv
if (sv.strings.lightstyles[style])
BZ_Free((void*)sv.strings.lightstyles[style]);
sv.strings.lightstyles[style] = Z_StrDup(val);
if (sv.lightstyles[style].str)
BZ_Free((void*)sv.lightstyles[style].str);
sv.lightstyles[style].str = Z_StrDup(val);
#ifdef PEXT_LIGHTSTYLECOL
VectorCopy(rgb, sv.lightstylecolours[style]);
VectorCopy(rgb, sv.lightstyles[style].colours);
#endif
// send message to all clients on this server
@ -4675,58 +4683,13 @@ void QCBUILTIN PF_applylightstyle(int style, const char *val, vec3_t rgb)
{
if (client->controller)
continue;
if ( client->state == cs_spawned )
{
if (style >= MAX_STANDARDLIGHTSTYLES) //only bug out clients if the styles are needed
if (!*val)
continue;
#ifdef PEXT_LIGHTSTYLECOL
if ((client->fteprotocolextensions & PEXT_LIGHTSTYLECOL) && (rgb[0] != 1 || rgb[1] != 1 || rgb[2] != 1))
{
ClientReliableWrite_Begin (client, svcfte_lightstylecol, 3+6+strlen(val)+1);
ClientReliableWrite_Byte (client, style);
ClientReliableWrite_Char (client, 0x87);
ClientReliableWrite_Short (client, rgb[0]*1024);
ClientReliableWrite_Short (client, rgb[1]*1024);
ClientReliableWrite_Short (client, rgb[2]*1024);
ClientReliableWrite_String (client, val);
}
else
#endif
{
ClientReliableWrite_Begin (client, svc_lightstyle, strlen(val)+3);
ClientReliableWrite_Byte (client, style);
ClientReliableWrite_String (client, val);
}
}
if (client->state == cs_spawned)
SV_SendLightstyle(client, NULL, style, false);
}
#ifdef MVD_RECORDING
if (sv.mvdrecording)
{
if (style < MAX_STANDARDLIGHTSTYLES || *val)
{
sizebuf_t *msg = MVDWrite_Begin(dem_all, 0, 3+6+strlen(val)+1);
#ifdef PEXT_LIGHTSTYLECOL
if ((demo.recorder.fteprotocolextensions & PEXT_LIGHTSTYLECOL) && (rgb[0] != 1 || rgb[1] != 1 || rgb[2] != 1))
{
MSG_WriteByte (msg, svcfte_lightstylecol);
MSG_WriteByte (msg, style);
MSG_WriteChar (msg, 0x87);
MSG_WriteShort (msg, rgb[0]*1024);
MSG_WriteShort (msg, rgb[1]*1024);
MSG_WriteShort (msg, rgb[2]*1024);
MSG_WriteString (msg, val);
}
else
#endif
{
MSG_WriteByte (msg, svc_lightstyle);
MSG_WriteByte (msg, style);
MSG_WriteString (msg, val);
}
}
}
SV_SendLightstyle(&demo.recorder, NULL, style, true);
#endif
}
@ -4754,35 +4717,65 @@ static void QCBUILTIN PF_lightstyle (pubprogfuncs_t *prinst, struct globalvars_s
PF_applylightstyle(style, val, rgb);
}
static void PR_Lightstyle_f(void)
{
int style = atoi(Cmd_Argv(1));
if (svs.gametype != GT_PROGS && svs.gametype != GT_Q1QVM)
Con_TPrintf ("not supported in the current game mode.\n");
else if (!SV_MayCheat())
Con_TPrintf ("Please set sv_cheats 1 and restart the map first.\n");
else if (Cmd_Argc() <= 2)
{
if (style >= 0 && style < sv.maxlightstyles && Cmd_Argc() >= 2)
Con_Printf("Style %i: %s %g %g %g\n", style, sv.lightstyles[style].str, sv.lightstyles[style].colours[0], sv.lightstyles[style].colours[1], sv.lightstyles[style].colours[2]);
else for (style = 0; style < sv.maxlightstyles; style++)
if (sv.lightstyles[style].str)
Con_Printf("Style %i: %s %g %g %g\n", style, sv.lightstyles[style].str, sv.lightstyles[style].colours[0], sv.lightstyles[style].colours[1], sv.lightstyles[style].colours[2]);
}
else
{
vec3_t rgb = {1,1,1};
if (Cmd_Argc() > 5)
{
rgb[0] = atof(Cmd_Argv(3));
rgb[1] = atof(Cmd_Argv(4));
rgb[2] = atof(Cmd_Argv(5));
}
else if (Cmd_Argc() > 3)
rgb[0] = rgb[1] = rgb[2] = atof(Cmd_Argv(3));
PF_applylightstyle(style, Cmd_Argv(2), rgb);
}
}
static void QCBUILTIN PF_getlightstyle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int style = G_FLOAT(OFS_PARM0);
if (style >= countof(sv.strings.lightstyles))
if (style >= sv.maxlightstyles)
{
VectorSet(G_VECTOR(OFS_PARM1), 0, 0, 0);
G_INT(OFS_RETURN) = 0;
}
else
{
VectorCopy(sv.lightstylecolours[style], G_VECTOR(OFS_PARM1));
if (!sv.strings.lightstyles[style])
VectorCopy(sv.lightstyles[style].colours, G_VECTOR(OFS_PARM1));
if (!sv.lightstyles[style].str)
G_INT(OFS_RETURN) = 0;
else
RETURN_TSTRING(sv.strings.lightstyles[style]);
RETURN_TSTRING(sv.lightstyles[style].str);
}
}
static void QCBUILTIN PF_getlightstylergb (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int style = G_FLOAT(OFS_PARM0);
int value;
if (!sv.strings.lightstyles[style])
if (style >= sv.maxlightstyles || !sv.lightstyles[style].str)
value = ('m'-'a')*22;
else if (sv.strings.lightstyles[style][0] == '=')
value = atof(sv.strings.lightstyles[style]+1)*256;
else if (sv.lightstyles[style].str[0] == '=')
value = atof(sv.lightstyles[style].str+1)*256;
else
value = sv.strings.lightstyles[style][max(0,(int)(sv.time*10)) % strlen(sv.strings.lightstyles[style])] - 'a';
VectorScale(sv.lightstylecolours[style], value*(1.0/256), G_VECTOR(OFS_RETURN));
value = sv.lightstyles[style].str[max(0,(int)(sv.time*10)) % strlen(sv.lightstyles[style].str)] - 'a';
VectorScale(sv.lightstyles[style].colours, value*(1.0/256), G_VECTOR(OFS_RETURN));
}
#ifdef HEXEN2
@ -4790,12 +4783,12 @@ static void QCBUILTIN PF_lightstylevalue (pubprogfuncs_t *prinst, struct globalv
{
int style;
style = G_FLOAT(OFS_PARM0);
if(style < 0 || style >= MAX_LIGHTSTYLES || !sv.strings.lightstyles[style])
if(style < 0 || style >= sv.maxlightstyles || !sv.lightstyles[style].str || !*sv.lightstyles[style].str)
{
G_FLOAT(OFS_RETURN) = 0;
return;
}
G_FLOAT(OFS_RETURN) = *sv.strings.lightstyles[style] - 'a';
G_FLOAT(OFS_RETURN) = *sv.lightstyles[style].str - 'a';
}
static void QCBUILTIN PF_lightstylestatic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)

View file

@ -253,8 +253,8 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldentity(tag_entity,NULL)\
comfieldfloat(tag_index,NULL)\
comfieldfloat(skeletonindex,"This object serves as a container for the skeletal bone states used to override the animation data.") /*FTE_CSQC_SKELETONOBJECTS*/\
comfieldvector(colormod,"Provides a colour tint for the entity.")\
comfieldvector(glowmod,NULL)\
comfieldvector(colormod,"Provides a colour tint for the entity (does not affect fullbrights).")\
comfieldvector(glowmod,"Scaler for an entity's fullbright textures.")\
comfieldvector(gravitydir,"Specifies the direction in which gravity acts. Must be normalised. '0 0 0' also means down. Use '0 0 1' if you want the player to be able to run on ceilings.")\
comfieldfunction(camera_transform,".vector(vector org, vector ang)", "Provides portal transform information for portal surfaces attached to this entity. Also used to open up pvs in ssqc.")\
comfieldfloat(pmove_flags,NULL)/*EXT_CSQC_1*/\
@ -294,9 +294,9 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldentity(viewmodelforclient,"This entity will be sent only to the player named by this field, and this entity will be attached to the player's view as an additional weapon model.")/*DP_ENT_VIEWMODEL*/\
comfieldentity(exteriormodeltoclient,"This entity will be invisible to the player named by this field, except in mirrors or mirror-like surfaces, where it will be visible as normal. It may still cast shadows as normal, and generate lights+particles, depending on client settings. Does not affect how other players see the entity.")\
svextqcfield_clientcamera\
comfieldfloat(glow_size,NULL)\
comfieldfloat(glow_color,NULL)\
comfieldfloat(glow_trail,NULL)\
comfieldfloat(glow_size,"Some outdated particle trail thing.")\
comfieldfloat(glow_color,"Some outdated particle trail thing.")\
comfieldfloat(glow_trail,"Some outdated particle trail thing.")\
comfieldfloat(traileffectnum,"This should be set to the result of particleeffectnum, in order to attach a custom trail effect to an entity as it moves.")/*DP_ENT_TRAILEFFECTNUM*/\
comfieldfloat(emiteffectnum,"This should be set to the result of particleeffectnum, in order to continually spawn particles in the direction that this entity faces.")/*DP_ENT_TRAILEFFECTNUM*/\
/*comfieldfloat(baseframe,"Specifies the current frame(group) to use for the lower (numerically) bones of a skeletal model. The basebone field specifies the bone where the regular frame field takes over.")*/ /*FTESS_QC_BASEFRAME*/\
@ -350,9 +350,9 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(entnum,"This is the number of the entity that the ssqc is using.") \
comfieldfloat(frame2,"This is typically the old frame of the entity. if lerpfrac is 1, .frame will be ignored and .frame2 will be used solely. lerpfrac 0.5 will give an even 50/50 blend.") /*EXT_CSQC_1*/\
comfieldfloat(frame2time,".frame2 equivelent of frame1time.") /*EXT_CSQC_1*/\
comfieldfloat(lerpfrac,"The weight of .frame2. A value of 0 means the entity will animate using only .frame, while 1 would exclusively be .frame2. As this value is incremented, more of frame2 will be used. If you wish to use .frame2 as the 'old' frame, it is generally recommended to start this field with the value 1, to decrement it by frametime, and when it drops below 0 add 1 to it and update .frame2 and .frame to lerp into the new frame.") /*EXT_CSQC_1*/\
comfieldfloat(lerpfrac,"The weight of .frame2 (with the weight of .frame being inferred). A value of 0 normally means the entity will animate using only .frame, while 1 would exclusively be .frame2. As this value is incremented, more of frame2 will be used. If you wish to use .frame2 as the 'old' frame, it is generally recommended to start this field with the value 1, to decrement it by frametime, and when it drops below 0 add 1 to it and update .frame2 and .frame to lerp into the new frame.") /*EXT_CSQC_1*/\
frame34fields \
comfieldfloat(renderflags,NULL)\
comfieldfloat(renderflags,"Matches to the RF_* flags, read during addentity/addentities.")\
comfieldfloat(forceshader,"Contains a shader handle used to replace all surfaces upon the entity.")/*FTE_CSQC_SHADERS*/\
\
comfieldfloat(baseframe2,"See basebone") /*FTE_CSQC_BASEFRAME*/\

View file

@ -97,20 +97,24 @@ pbool PDECL SV_ExtendedSaveData(pubprogfuncs_t *progfuncs, void *loadctx, const
{ //lightstyle N "STYLESTRING" 1 1 1
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
idx = atoi(token);
if (idx >= countof(sv.strings.lightstyles))
return false; //unsupported index.
if (idx >= sv.maxlightstyles)
{
if (idx >= MAX_NET_LIGHTSTYLES)
return false; //unsupported index.
Z_ReallocElements((void**)&sv.lightstyles, &sv.maxlightstyles, idx+1, sizeof(*sv.lightstyles));
}
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_STRING)return false;
if (sv.strings.lightstyles[idx])
Z_Free((char*)sv.strings.lightstyles[idx]);
sv.strings.lightstyles[idx] = Z_StrDup(token);
sv.lightstylecolours[idx][0] = sv.lightstylecolours[idx][1] = sv.lightstylecolours[idx][2] = 1.0;
if (sv.lightstyles[idx].str)
Z_Free((char*)sv.lightstyles[idx].str);
sv.lightstyles[idx].str = Z_StrDup(token);
sv.lightstyles[idx].colours[0] = sv.lightstyles[idx].colours[1] = sv.lightstyles[idx].colours[2] = 1.0;
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
sv.lightstylecolours[idx][0] = atof(token);
sv.lightstyles[idx].colours[0] = atof(token);
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
sv.lightstylecolours[idx][1] = atof(token);
sv.lightstyles[idx].colours[1] = atof(token);
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
sv.lightstylecolours[idx][2] = atof(token);
sv.lightstyles[idx].colours[2] = atof(token);
}
else if (!strcmp(token, "model_precache") || !strcmp(token, "model"))
{ //model_precache N "MODELNAME"
@ -352,18 +356,21 @@ static qboolean SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
// load the light styles
lstyles = 64;
if (lstyles > sv.maxlightstyles)
Z_ReallocElements((void**)&sv.lightstyles, &sv.maxlightstyles, lstyles, sizeof(*sv.lightstyles));
for (i=0 ; i<lstyles ; i++)
{
VFS_GETS(f, str, sizeof(str));
if (sv.strings.lightstyles[i])
Z_Free((char*)sv.strings.lightstyles[i]);
sv.strings.lightstyles[i] = Z_StrDup(str);
if (sv.lightstyles[i].str)
Z_Free((char*)sv.lightstyles[i].str);
sv.lightstyles[i].str = Z_StrDup(str);
sv.lightstyles[i].colours[0] = sv.lightstyles[i].colours[1] = sv.lightstyles[i].colours[2] = 1;
}
for (; i < MAX_LIGHTSTYLES; i++)
for (; i < sv.maxlightstyles; i++)
{
if (sv.strings.lightstyles[i])
Z_Free((char*)sv.strings.lightstyles[i]);
sv.strings.lightstyles[i] = NULL;
if (sv.lightstyles[i].str)
Z_Free((char*)sv.lightstyles[i].str);
sv.lightstyles[i].str = NULL;
}
//model names are pointers to vm-accessible memory. as that memory is going away, we need to destroy and recreate, which requires preserving them.
@ -564,8 +571,8 @@ static qboolean SV_LegacySavegame (const char *savename, qboolean verbose)
// write the light styles (only 64 are saved in legacy saved games)
for (i=0 ; i < 64; i++)
{
if (sv.strings.lightstyles[i] && *sv.strings.lightstyles[i])
VFS_PRINTF(f, "%s\n", sv.strings.lightstyles[i]);
if (i < sv.maxlightstyles && sv.lightstyles[i].str && *sv.lightstyles[i].str)
VFS_PRINTF(f, "%s\n", sv.lightstyles[i].str);
else
VFS_PRINTF(f,"m\n");
}
@ -584,10 +591,10 @@ static qboolean SV_LegacySavegame (const char *savename, qboolean verbose)
*/
VFS_PUTS(f, "/*\n");
VFS_PUTS(f, "// FTE extended savegame\n");
for (i=0 ; i < countof(sv.strings.lightstyles); i++)
{ //yes, repeat styles 0-63 again, for some reason, but only list ones that are not empty.
if (sv.strings.lightstyles[i])
VFS_PRINTF(f, "sv.lightstyles %i %s\n", i, sv.strings.lightstyles[i]);
for (i=0 ; i < sv.maxlightstyles; i++)
{ //yes, repeat styles 0-63 again, but only list ones that are not empty.
if (sv.lightstyles[i].str)
VFS_PRINTF(f, "sv.lightstyles %i %s\n", i, sv.lightstyles[i].str);
}
for (i=1 ; i < countof(sv.strings.model_precache); i++)
{
@ -931,27 +938,28 @@ qboolean SV_LoadLevelCache(const char *savename, const char *level, const char *
// load the light styles
VFS_GETS(f, str, sizeof(str));
numstyles = atoi(str);
if (numstyles > MAX_LIGHTSTYLES)
if (numstyles > MAX_NET_LIGHTSTYLES)
{
VFS_CLOSE (f);
Con_Printf ("load failed - invalid number of lightstyles\n");
return false;
}
for (i = 0; i<MAX_LIGHTSTYLES ; i++)
for (i = 0; i<sv.maxlightstyles ; i++)
{
if (sv.strings.lightstyles[i])
BZ_Free((void*)sv.strings.lightstyles[i]);
sv.strings.lightstyles[i] = NULL;
if (sv.lightstyles[i].str)
BZ_Free((void*)sv.lightstyles[i].str);
sv.lightstyles[i].str = NULL;
}
Z_ReallocElements((void**)&sv.lightstyles, &sv.maxlightstyles, numstyles, sizeof(*sv.lightstyles));
for (i=0 ; i<numstyles ; i++)
{
VFS_GETS(f, str, sizeof(str));
sv.strings.lightstyles[i] = Z_StrDup(str);
sv.lightstyles[i].str = Z_StrDup(str);
}
for ( ; i<MAX_LIGHTSTYLES ; i++)
for ( ; i<sv.maxlightstyles ; i++)
{
sv.strings.lightstyles[i] = Z_StrDup("");
sv.lightstyles[i].str = Z_StrDup("");
}
modelpos = VFS_TELL(f);
@ -1270,10 +1278,10 @@ void SV_SaveLevelCache(const char *savedir, qboolean dontharmgame)
VFS_PRINTF (f, "%f\n", sv.time);
// write the light styles
VFS_PRINTF (f, "%i\n",MAX_LIGHTSTYLES);
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
VFS_PRINTF (f, "%u\n",(unsigned)sv.maxlightstyles);
for (i=0 ; i<sv.maxlightstyles ; i++)
{
VFS_PRINTF (f, "%s\n", sv.strings.lightstyles[i]?sv.strings.lightstyles[i]:"");
VFS_PRINTF (f, "%s\n", sv.lightstyles[i].str?sv.lightstyles[i].str:"");
}
for (i=1 ; i<MAX_PRECACHE_MODELS ; i++)
@ -1310,9 +1318,9 @@ void SV_SaveLevelCache(const char *savedir, qboolean dontharmgame)
if (version >= CACHEGAME_VERSION_VERBOSE)
{
char buf[8192];
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
if (sv.strings.lightstyles[i])
VFS_PRINTF (f, "lightstyle %i %s %f %f %f\n", i, COM_QuotedString(sv.strings.lightstyles[i], buf, sizeof(buf), false), sv.lightstylecolours[i][0], sv.lightstylecolours[i][1], sv.lightstylecolours[i][2]);
for (i=0 ; i<sv.maxlightstyles ; i++)
if (sv.lightstyles[i].str)
VFS_PRINTF (f, "lightstyle %i %s %f %f %f\n", i, COM_QuotedString(sv.lightstyles[i].str, buf, sizeof(buf), false), sv.lightstyles[i].colours[0], sv.lightstyles[i].colours[1], sv.lightstyles[i].colours[2]);
for (i=1 ; i<MAX_PRECACHE_MODELS ; i++)
if (sv.strings.model_precache[i] && *sv.strings.model_precache[i])
VFS_PRINTF (f, "model %i %s\n", i, COM_QuotedString(sv.strings.model_precache[i], buf, sizeof(buf), false));
@ -1562,6 +1570,8 @@ void SV_Savegame (const char *savename, qboolean mapchange)
V_RenderView (false);
okay = true;
}
if (R2D_Flush)
R2D_Flush();
//okay, we drew something, we're good to save a screeny.
if (okay)

View file

@ -158,12 +158,16 @@ typedef struct
const char *model_precache[MAX_PRECACHE_MODELS]; // NULL terminated
const char *particle_precache[MAX_SSPARTICLESPRE]; // NULL terminated
const char *sound_precache[MAX_PRECACHE_SOUNDS]; // NULL terminated
const char *lightstyles[MAX_LIGHTSTYLES];
};
const char *ptrs[1];
} strings;
qboolean stringsalloced; //if true, we need to free the string pointers safely rather than just memsetting them to 0
vec3_t lightstylecolours[MAX_LIGHTSTYLES];
struct
{
const char *str; //double dynamic. urgh, but allows it to be nice and long.
vec3_t colours;
} *lightstyles;
size_t maxlightstyles; //limited to MAX_NET_LIGHTSTYLES
#ifdef HEXEN2
char h2miditrack[MAX_QPATH];
@ -1304,6 +1308,7 @@ void SV_ClearQCStats(void);
void SV_SendClientMessages (void);
void SV_SendLightstyle(client_t *cl, sizebuf_t *forcemsg, int style, qboolean initial);
void VARGS SV_Multicast (vec3_t origin, multicast_t to);
#define FULLDIMENSIONMASK 0xffffffff
void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int with, int without);

View file

@ -1825,30 +1825,8 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
}
// send all current light styles
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
{
if (i >= MAX_STANDARDLIGHTSTYLES)
if (!sv.strings.lightstyles[i])
continue;
#ifdef PEXT_LIGHTSTYLECOL
if ((demo.recorder.fteprotocolextensions & PEXT_LIGHTSTYLECOL) && (sv.lightstylecolours[i][0]!=1||sv.lightstylecolours[i][1]!=1||sv.lightstylecolours[i][2]!=1) && sv.strings.lightstyles[i])
{
MSG_WriteByte (&buf, svcfte_lightstylecol);
MSG_WriteByte (&buf, (unsigned char)i);
MSG_WriteByte (&buf, 0x87);
MSG_WriteShort(&buf, sv.lightstylecolours[i][0]*1024);
MSG_WriteShort(&buf, sv.lightstylecolours[i][1]*1024);
MSG_WriteShort(&buf, sv.lightstylecolours[i][2]*1024);
MSG_WriteString (&buf, sv.strings.lightstyles[i]);
}
else
#endif
{
MSG_WriteByte (&buf, svc_lightstyle);
MSG_WriteByte (&buf, (unsigned char)i);
MSG_WriteString (&buf, sv.strings.lightstyles[i]);
}
}
for (i=0 ; i<sv.maxlightstyles || i < MAX_STANDARDLIGHTSTYLES; i++)
SV_SendLightstyle(&demo.recorder, &buf, i, true);
//invalidate stats+players somehow
for (i = 0; i < MAX_CLIENTS; i++)

View file

@ -1492,6 +1492,104 @@ void QDECL SVQ1_StartSound (float *origin, wedict_t *wentity, int channel, const
SV_StartSound(NUM_FOR_EDICT(svprogfuncs, entity), origin, velocity, entity->xv->dimension_seen, channel, sample, volume, attenuation, pitchadj, timeofs, chflags);
}
void SV_SendLightstyle(client_t *cl, sizebuf_t *forcemsg, int style, qboolean initial)
{
sizebuf_t *msg;
const char *stylestring = (style < sv.maxlightstyles)?sv.lightstyles[style].str:NULL;
float *stylecolor = (style < sv.maxlightstyles)?sv.lightstyles[style].colours:vec3_origin;
int flags = 0;
int sz;
//don't crash old clients unless there's a good reason to do so.
//new clients are expected to reinitialise their styles to empty on map changes.
if (style >= MAX_STANDARDLIGHTSTYLES && initial && !stylestring)
return;
if (style > 255)
flags |= 0x40;
if (stylestring && (stylecolor[0]!=1||stylecolor[1]!=1||stylecolor[2]!=1))
{
if (stylecolor[0]!=0)
{
flags |= 1;
if (stylecolor[0]!=1)
flags |= 0x80|7;
}
if (stylecolor[1]!=0)
{
flags |= 2;
if (stylecolor[1]!=1)
flags |= 0x80|7;
}
if (stylecolor[2]!=0)
{
flags |= 4;
if (stylecolor[2]!=1)
flags |= 0x80|7;
}
}
else
flags |= 7;
//flags |= 0x08;
//flags |= 0x10;
//flags |= 0x20;
if (!(cl->fteprotocolextensions & PEXT_LIGHTSTYLECOL))
{ //if they don't support it then just drop the extra colours, so long as it still makes sense.
if ((flags & ~0x87u) || (ISNQCLIENT(cl) && !ISDPCLIENT(cl) && !cl->fteprotocolextensions2))
{
char *text = va("//ls %i \"%s\" %g %g %g\n", style, sv.lightstyles[style].str, sv.lightstyles[style].colours[0], sv.lightstyles[style].colours[1], sv.lightstyles[style].colours[2]);
if (forcemsg)
msg = forcemsg;
else
msg = ClientReliable_StartWrite(cl, 2+strlen(text));
MSG_WriteByte (msg, svc_stufftext);
MSG_WriteString (msg, text);
if (!forcemsg)
ClientReliable_FinishWrite(cl);
return; //erk, can't handle this!
}
flags = 7;
}
if (forcemsg)
msg = forcemsg;
else
{
sz = 2;
if (flags != 7)
sz+=1;
if (flags & 0x40)
sz+=1;
if (flags & 0x80u)
sz+=3*2; //rough overestimate
sz += (stylestring?strlen(stylestring):0) + 1;
msg = ClientReliable_StartWrite(cl, sz);
}
MSG_WriteByte(msg, (flags != 7)?svcfte_lightstylecol:svc_lightstyle);
MSG_WriteByte (msg, style&0xffu);
if (flags != 7)
MSG_WriteByte(msg, flags);
if (flags & 0x40) //16bit style indexes
MSG_WriteByte (msg, style>>8);
if (flags & 0x80u)
{ //rich style tints
if (flags & 1)
MSG_WriteShort (msg, bound(-0x7fff, stylecolor[0]*1024, 0x7fff));
if (flags & 2)
MSG_WriteShort (msg, bound(-0x7fff, stylecolor[1]*1024, 0x7fff));
if (flags & 4)
MSG_WriteShort (msg, bound(-0x7fff, stylecolor[2]*1024, 0x7fff));
}
MSG_WriteString (msg, stylestring);
if (!forcemsg)
ClientReliable_FinishWrite(cl);
}
/*
===============================================================================

View file

@ -38,7 +38,7 @@ void QDECL SV_NQPhysicsUpdate(cvar_t *var, char *oldvalue)
{
if (!strcmp(var->string, "auto") || !strcmp(var->string, ""))
{ //prediction requires nq physics, so use it by default in multiplayer.
if (progstype == PROG_QW || (!isDedicated && sv.allocated_client_slots > 1))
if (progstype <= PROG_QW || (!isDedicated && sv.allocated_client_slots > 1))
var->ival = 0;
else
var->ival = 1;
@ -1855,7 +1855,7 @@ void SVQW_Spawn_f (void)
#endif
// send all current light styles
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
for (i=0 ; i<sv.maxlightstyles ; i++)
{
#ifdef SERVER_DEMO_PLAYBACK
if (sv.democausesreconnect)
@ -1869,31 +1869,7 @@ void SVQW_Spawn_f (void)
}
else
#endif
{
if (i >= MAX_STANDARDLIGHTSTYLES)
if (!sv.strings.lightstyles[i])
continue;
#ifdef PEXT_LIGHTSTYLECOL
if ((host_client->fteprotocolextensions & PEXT_LIGHTSTYLECOL) && (sv.lightstylecolours[i][0]!=1||sv.lightstylecolours[i][1]!=1||sv.lightstylecolours[i][2]!=1) && sv.strings.lightstyles[i])
{
ClientReliableWrite_Begin (host_client, svcfte_lightstylecol,
10 + (sv.strings.lightstyles[i] ? strlen(sv.strings.lightstyles[i]) : 1));
ClientReliableWrite_Byte (host_client, (char)i);
ClientReliableWrite_Char (host_client, 0x87);
ClientReliableWrite_Short (host_client, sv.lightstylecolours[i][0]*1024);
ClientReliableWrite_Short (host_client, sv.lightstylecolours[i][1]*1024);
ClientReliableWrite_Short (host_client, sv.lightstylecolours[i][2]*1024);
ClientReliableWrite_String (host_client, sv.strings.lightstyles[i]);
}
else
#endif
{
ClientReliableWrite_Begin (host_client, svc_lightstyle,
3 + (sv.strings.lightstyles[i] ? strlen(sv.strings.lightstyles[i]) : 1));
ClientReliableWrite_Byte (host_client, (char)i);
ClientReliableWrite_String (host_client, sv.strings.lightstyles[i]);
}
}
SV_SendLightstyle(host_client, NULL, i, true);
}
#ifdef HLSERVER
@ -5683,16 +5659,8 @@ static void SVNQ_Spawn_f (void)
#endif
// send all current light styles
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
{
if (i >= MAX_STANDARDLIGHTSTYLES && host_client->protocol != SCP_DARKPLACES7)
break; //dp7 clients support more lightstyles.
ClientReliableWrite_Begin (host_client, svc_lightstyle,
3 + (sv.strings.lightstyles[i] ? strlen(sv.strings.lightstyles[i]) : 1));
ClientReliableWrite_Byte (host_client, (char)i);
ClientReliableWrite_String (host_client, sv.strings.lightstyles[i]);
}
for (i=0 ; i<sv.maxlightstyles ; i++)
SV_SendLightstyle(host_client, NULL, i, true);
// set up the edict
ent = host_client->edict;

View file

@ -262,7 +262,7 @@ int VID_ShouldSwitchToFullscreen(void)
//this is confounded by escape bringing up the menu. <ESC>GRR IT CHANGED MODE!<options>WTF IT CHANGED AGAIN FUCKING PIECE OF SHIT!.
//annoying, but that's web browsers for you. the best thing we can do is to not regrab until they next click while actually back in the game.
extern cvar_t vid_fullscreen;
return !!vid_fullscreen.value && (!Key_Dest_Has(kdm_console | kdm_cwindows | kdm_emenu) || !Key_MouseShouldBeFree());
return !!vid_fullscreen.value && !Key_MouseShouldBeFree();
}
qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
{

View file

@ -77,14 +77,12 @@ static rbeplugfuncs_t *rbefuncs;
static void World_Bullet_RunCmd(world_t *world, rbecommandqueue_t *cmd);
static cvar_t *physics_bullet_enable;
static cvar_t *physics_bullet_maxiterationsperframe;
static cvar_t *physics_bullet_framerate;
static cvar_t *pr_meshpitch;
void World_Bullet_Init(void)
{
physics_bullet_enable = cvarfuncs->GetNVFDG("physics_bullet_enable", "1", 0, "", "Bullet");
physics_bullet_maxiterationsperframe = cvarfuncs->GetNVFDG("physics_bullet_maxiterationsperframe", "10", 0, "FIXME: should be 1 when CCD is working properly.", "Bullet");
physics_bullet_framerate = cvarfuncs->GetNVFDG("physics_bullet_framerate", "60", 0, "Bullet physics run at a fixed framerate in order to preserve numerical stability (interpolation is used to smooth out the result). Higher framerates are of course more demanding.", "Bullet");
pr_meshpitch = cvarfuncs->GetNVFDG("r_meshpitch", "-1", 0, "", "Bullet");
@ -1713,9 +1711,6 @@ static void QDECL World_Bullet_Start(world_t *world)
if (world->rbe)
return; //no thanks, we already have one. somehow.
if (!physics_bullet_enable->value)
return;
ctx = reinterpret_cast<bulletcontext_t*>(BZ_Malloc(sizeof(*ctx)));
memset(ctx, 0, sizeof(*ctx));
ctx->gworld = world;

View file

@ -28,7 +28,7 @@ This is equivelent to the information stored in a .lit file (sans header), and m
Presence of this lump permits omitting the regular mono lightmap to save space, but doing so will harm compatibility.
LIGHTING_E5BGR9:
(applies to fte)
(applies to fte, parsed by qss only as a fallback)
This is a more advanced alternative to RGBLIGHTING.
Each luxel is a E5BGR9 int32 packed value (ie: on little-endian machines, the exponent is the high 5 bits), resulting in what is effectively a memory-efficient floating point rgb value.
This lightmap format virtually removes all oversaturation limits, and promises greater precision in dark areas too.
@ -38,7 +38,7 @@ Lighting values are always assumed to be linear.
LIGHTINGDIR:
(applies to fte)
This lump contains surface-space light directions (read: deluxemap), equivelent to fte's .lux file, or dp's .dlit files (sans header).
This lump contains averaged surface-space light directions (read: deluxemap), equivelent to fte's .lux file, or dp's .dlit files (sans header).
(as unorm values, these need to be biased before use).
If bumpmaps or specular maps are not available then the effects of this may not be significant/noticable.
@ -55,7 +55,13 @@ This allows a bsp to contain both scaled surfaces and unscaled ones, without loo
LMSTYLE:
(applies to fte, qss)
This replaces the four lightstyle indexes of each surface lump entry. Should only be used in conjunction with LMSHIFT.
This replaces the four lightstyle indexes of each surface lump entry. Normally only makes sense when used in conjunction with LMSHIFT.
LMSTYLE16:
(applies to fte, qss)
An upgrade for the LMSTYLE lump, potentially giving up to 65k lightstyles.
Additionally, the number of styles per face is variable, and must be inferred by the lump size vs surface count.
Both of these tweeks make it useful even without LMSHIFT.
VERTEXNORMALS:
(applies to fte)