mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 12:01:25 +00:00
fix some nq-server issues.
make trying to close the window shut down properly while debugging. added r_softwarebanding cvar to approximate 8bit software rendering. fix issue with invalid skeletal lerps. external q3 lightmaps now uses IF_NOMIPMAP and respects gl_lightmap_nearest. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4838 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
052cba731d
commit
09196f3d14
26 changed files with 384 additions and 106 deletions
|
@ -635,7 +635,7 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
|
|||
news->u.q1.msec = 0;
|
||||
}
|
||||
|
||||
if (!(predbits & UFP_VIEWANGLE) || (cls.fteprotocolextensions2 & PEXT2_PREDINFO))
|
||||
if (!(predbits & UFP_VIEWANGLE) || !(cls.fteprotocolextensions2 & PEXT2_PREDINFO))
|
||||
{
|
||||
news->u.q1.vangle[0] = ANGLE2SHORT(news->angles[0]);
|
||||
news->u.q1.vangle[1] = ANGLE2SHORT(news->angles[1]);
|
||||
|
|
|
@ -4028,7 +4028,9 @@ void CL_ParseStatic (int version)
|
|||
|
||||
// copy it to the current state
|
||||
ent->model = cl.model_precache[es.modelindex];
|
||||
memset(&ent->framestate, 0, sizeof(ent->framestate));
|
||||
ent->framestate.g[FS_REG].frame[0] = ent->framestate.g[FS_REG].frame[1] = es.frame;
|
||||
ent->framestate.g[FS_REG].lerpweight[0] = 1;
|
||||
ent->skinnum = es.skinnum;
|
||||
ent->drawflags = es.hexen2flags;
|
||||
|
||||
|
|
|
@ -2813,6 +2813,8 @@ static void Image_GenerateMips(struct pendingtextureinfo *mips, unsigned int fla
|
|||
|
||||
switch(mips->encoding)
|
||||
{
|
||||
case PTI_R8:
|
||||
return;
|
||||
case PTI_RGBA8:
|
||||
case PTI_RGBX8:
|
||||
case PTI_BGRA8:
|
||||
|
@ -3296,9 +3298,39 @@ static void Image_ChangeFormat(struct pendingtextureinfo *mips, uploadfmt_t orig
|
|||
return; //blurgh
|
||||
|
||||
//if that format isn't supported/desired, try converting it.
|
||||
if (sh_config.texfmt[PTI_RGBX8])
|
||||
if (sh_config.texfmt[mips->encoding])
|
||||
return;
|
||||
|
||||
if (mips->encoding == PTI_R8)
|
||||
{
|
||||
if (sh_config.texfmt[PTI_BGRX8]) //bgra8 is typically faster when supported.
|
||||
mips->encoding = PTI_BGRX8;
|
||||
else if (sh_config.texfmt[PTI_BGRX8])
|
||||
mips->encoding = PTI_RGBX8;
|
||||
else if (sh_config.texfmt[PTI_BGRA8])
|
||||
mips->encoding = PTI_BGRA8;
|
||||
else
|
||||
mips->encoding = PTI_RGBA8;
|
||||
for (mip = 0; mip < mips->mipcount; mip++)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int *out;
|
||||
unsigned char *in;
|
||||
in = mips->mip[mip].data;
|
||||
out = BZ_Malloc(mips->mip[mip].width*mips->mip[mip].height*sizeof(*out));
|
||||
for (i = 0; i < mips->mip[mip].width*mips->mip[mip].height; i++)
|
||||
out[i] = in[i] * 0x01010101;
|
||||
if (mips->mip[mip].needfree)
|
||||
BZ_Free(in);
|
||||
mips->mip[mip].data = out;
|
||||
mips->mip[mip].needfree = true;
|
||||
mips->mip[mip].datasize = mips->mip[mip].width*mips->mip[mip].height*sizeof(*out);
|
||||
}
|
||||
|
||||
if (sh_config.texfmt[mips->encoding])
|
||||
return;
|
||||
}
|
||||
|
||||
//should we just use 5551 always?
|
||||
if (mips->encoding == PTI_RGBX8 || mips->encoding == PTI_BGRX8)
|
||||
{
|
||||
|
@ -3318,6 +3350,7 @@ static void Image_ChangeFormat(struct pendingtextureinfo *mips, uploadfmt_t orig
|
|||
}
|
||||
}
|
||||
else*/
|
||||
if (sh_config.texfmt[PTI_RGB565])
|
||||
{
|
||||
for (mip = 0; mip < mips->mipcount; mip++)
|
||||
Image_8888to565(mips->mip[mip].data, mips->mip[mip].data, mips->mip[mip].width, mips->mip[mip].height, mips->encoding == PTI_BGRX8);
|
||||
|
@ -3410,6 +3443,9 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
|
|||
case TF_BGRA32:
|
||||
mips->encoding = PTI_BGRA8;
|
||||
break;
|
||||
case TF_LUM8:
|
||||
mips->encoding = PTI_R8;
|
||||
break;
|
||||
case TF_SOLID8:
|
||||
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
|
||||
if (sh_config.texfmt[PTI_BGRX8])
|
||||
|
@ -4184,6 +4220,7 @@ image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned
|
|||
pb = 4*256;
|
||||
b = 1;
|
||||
break;
|
||||
case TF_LUM8:
|
||||
case TF_SOLID8:
|
||||
case TF_TRANS8:
|
||||
case TF_TRANS8_FULLBRIGHT:
|
||||
|
|
|
@ -2691,6 +2691,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
|
|||
ent.playerindex = -1;
|
||||
ent.skinnum = mods->skingroup;
|
||||
ent.shaderTime = realtime;
|
||||
ent.framestate.g[FS_REG].lerpweight[0] = 1;
|
||||
ent.framestate.g[FS_REG].frame[0] = mods->framegroup;
|
||||
ent.framestate.g[FS_REG].frametime[0] = realtime - mods->framechangetime;
|
||||
ent.framestate.g[FS_REG].frametime[1] = realtime - mods->framechangetime;
|
||||
|
|
|
@ -16,7 +16,8 @@ typedef enum
|
|||
SKEL_RELATIVE, //relative to parent.
|
||||
SKEL_ABSOLUTE, //relative to model. doesn't blend very well.
|
||||
SKEL_INVERSE_RELATIVE, //pre-inverted. faster than regular relative but has weirdness with skeletal objects. blends okay.
|
||||
SKEL_INVERSE_ABSOLUTE //final renderable type.
|
||||
SKEL_INVERSE_ABSOLUTE, //final renderable type.
|
||||
SKEL_IDENTITY //PANIC
|
||||
} skeltype_t;
|
||||
|
||||
#ifdef HALFLIFEMODELS
|
||||
|
@ -274,6 +275,9 @@ struct pendingtextureinfo
|
|||
//floating point formats
|
||||
PTI_RGBA16F,
|
||||
PTI_RGBA32F,
|
||||
//small formats.
|
||||
PTI_R8,
|
||||
PTI_RG8,
|
||||
//compressed formats
|
||||
PTI_S3RGB1,
|
||||
PTI_S3RGBA1,
|
||||
|
@ -341,11 +345,12 @@ typedef struct
|
|||
} srect_t;
|
||||
|
||||
typedef struct texnums_s {
|
||||
texid_t base;
|
||||
texid_t bump;
|
||||
texid_t specular;
|
||||
texid_t upperoverlay;
|
||||
texid_t loweroverlay;
|
||||
texid_t base; //regular diffuse texture. may have alpha if surface is transparent
|
||||
texid_t bump; //normalmap. height values packed in alpha.
|
||||
texid_t specular; //specular lighting values.
|
||||
texid_t upperoverlay; //diffuse texture for the upper body(shirt colour). no alpha channel. added to base.rgb
|
||||
texid_t loweroverlay; //diffuse texture for the lower body(trouser colour). no alpha channel. added to base.rgb
|
||||
texid_t paletted; //8bit paletted data, just because.
|
||||
texid_t fullbright;
|
||||
} texnums_t;
|
||||
|
||||
|
|
|
@ -2712,6 +2712,11 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo
|
|||
csqc_deprecated("runplayerphysics with no ent");
|
||||
return;
|
||||
}
|
||||
if (ent->readonly)
|
||||
{
|
||||
csqc_deprecated("runplayerphysics called on read-only entity");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cl.worldmodel)
|
||||
return; //urm..
|
||||
|
|
|
@ -322,6 +322,7 @@ extern qboolean msg_suppress_1; // suppresses resolution and cache size consol
|
|||
#if !defined(SERVERONLY) && !defined(CLIENTONLY)
|
||||
extern qboolean isDedicated;
|
||||
#endif
|
||||
extern qboolean wantquit; //flagged if we want to force a quit, safely breaking out of any modal stuff
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ extern cvar_t r_stains;
|
|||
extern cvar_t r_loadlits;
|
||||
extern cvar_t r_stainfadetime;
|
||||
extern cvar_t r_stainfadeammount;
|
||||
extern cvar_t gl_lightmap_nearest;
|
||||
|
||||
static int lightmap_shift;
|
||||
int Surf_LightmapShift (model_t *model)
|
||||
|
@ -2607,7 +2608,7 @@ int Surf_NewExternalLightmaps(int count, char *filepattern, qboolean deluxe)
|
|||
|
||||
Q_snprintfz(nname, sizeof(nname), filepattern, i - numlightmaps);
|
||||
|
||||
TEXASSIGN(lightmap[i]->lightmap_texture, R_LoadHiResTexture(nname, NULL, 0));
|
||||
TEXASSIGN(lightmap[i]->lightmap_texture, R_LoadHiResTexture(nname, NULL, (gl_lightmap_nearest.ival?IF_NEAREST:IF_LINEAR)|IF_NOMIPMAP));
|
||||
if (lightmap[i]->lightmap_texture->status == TEX_LOADING)
|
||||
COM_WorkerPartialSync(lightmap[i]->lightmap_texture, &lightmap[i]->lightmap_texture->status, TEX_LOADING);
|
||||
lightmap[i]->width = lightmap[i]->lightmap_texture->width;
|
||||
|
|
|
@ -127,6 +127,7 @@ cvar_t r_part_rain = CVARFD ("r_part_rain", "0",
|
|||
"Enable particle effects to emit off of surfaces. Mainly used for weather or lava/slime effects.");
|
||||
cvar_t r_skyboxname = SCVARF ("r_skybox", "",
|
||||
CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
|
||||
cvar_t r_softwarebanding = CVARFD ("r_softwarebanding", "0", CVAR_SHADERSYSTEM | CVAR_RENDERERLATCH, "Utilise the Quake colormap in order to emulate 8bit software rendering. This results in banding as well as other artifacts that some believe adds character. Also forces nearest sampling on affected surfaces (palette indicies do not interpolate well).");
|
||||
cvar_t r_speeds = SCVAR ("r_speeds", "0");
|
||||
cvar_t r_stainfadeammount = SCVAR ("r_stainfadeammount", "1");
|
||||
cvar_t r_stainfadetime = SCVAR ("r_stainfadetime", "1");
|
||||
|
@ -622,6 +623,7 @@ void Renderer_Init(void)
|
|||
Cvar_Register (&r_mirroralpha, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_skyboxname, GRAPHICALNICETIES);
|
||||
Cbuf_AddText("alias sky r_skybox\n", RESTRICT_LOCAL); /*alternative name for users*/
|
||||
Cvar_Register (&r_softwarebanding, GRAPHICALNICETIES);
|
||||
|
||||
Cvar_Register(&r_dodgytgafiles, "Bug fixes");
|
||||
Cvar_Register(&r_dodgypcxfiles, "Bug fixes");
|
||||
|
|
|
@ -2037,6 +2037,7 @@ void Sys_SendKeyEvents (void)
|
|||
HANDLE input = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (!PeekNamedPipe(input, NULL, 0, NULL, &avail, NULL))
|
||||
{
|
||||
wantquit = true;
|
||||
Cmd_ExecuteString("quit force", RESTRICT_LOCAL);
|
||||
}
|
||||
else if (avail)
|
||||
|
|
|
@ -622,6 +622,20 @@ const float *Alias_ConvertBoneData(skeltype_t sourcetype, const float *sourcedat
|
|||
sourcedata = dest;
|
||||
sourcetype = SKEL_INVERSE_ABSOLUTE;
|
||||
}
|
||||
|
||||
if (sourcetype == SKEL_IDENTITY)
|
||||
{ //we can 'convert' identity matricies to anything. but we only want to do this when everything else is bad, because there really is no info here
|
||||
float *dest = (sourcedata == destbuffer)?destbufferalt:destbuffer;
|
||||
memset(dest, 0, bonecount*12*sizeof(float));
|
||||
for (i = 0; i < bonecount; i++)
|
||||
{ //is this right? does it matter?
|
||||
dest[i*12+0] = 1;
|
||||
dest[i*12+5] = 1;
|
||||
dest[i*12+10] = 1;
|
||||
}
|
||||
sourcedata = dest;
|
||||
sourcetype = desttype; //panic
|
||||
}
|
||||
|
||||
if (sourcetype != desttype)
|
||||
Sys_Error("Alias_ConvertBoneData: %i->%i not supported\n", (int)sourcetype, (int)desttype);
|
||||
|
@ -1137,6 +1151,9 @@ static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, struct framestateregion
|
|||
galiasgroup_t *g;
|
||||
unsigned int b;
|
||||
float totalweight = 0;
|
||||
|
||||
lerps->skeltype = SKEL_IDENTITY; //sometimes nothing else is valid.
|
||||
|
||||
for (b = 0; b < FRAME_BLENDS; b++)
|
||||
{
|
||||
if (fs->lerpweight[b])
|
||||
|
@ -1165,7 +1182,7 @@ static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, struct framestateregion
|
|||
frame2=(frame2>g->numposes-1)?g->numposes-1:frame2;
|
||||
}
|
||||
|
||||
if (!l)
|
||||
if (lerps->skeltype == SKEL_IDENTITY)
|
||||
lerps->skeltype = g->skeltype;
|
||||
else if (lerps->skeltype != g->skeltype)
|
||||
continue; //oops, can't cope with mixed blend types
|
||||
|
@ -1685,6 +1702,12 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
|
|||
meshcache.ent = e;
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!e->framestate.g[FS_REG].lerpweight[0] && !e->framestate.g[FS_REG].lerpweight[1] && !e->framestate.g[FS_REG].lerpweight[2] && !e->framestate.g[FS_REG].lerpweight[3])
|
||||
Con_Printf("Entity with no lerp info\n");
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SERVERONLY
|
||||
mesh->trneighbors = inf->ofs_trineighbours;
|
||||
mesh->normals_array = meshcache.norm;
|
||||
|
|
|
@ -104,6 +104,7 @@ qboolean static_registered = true; // only for startup check, then set
|
|||
|
||||
qboolean msg_suppress_1 = false;
|
||||
int isPlugin; //if 2, we qcdebug to external program
|
||||
qboolean wantquit;
|
||||
|
||||
void COM_Path_f (void);
|
||||
void COM_Dir_f (void);
|
||||
|
@ -5018,6 +5019,8 @@ void COM_Init (void)
|
|||
{
|
||||
qbyte swaptest[2] = {1,0};
|
||||
|
||||
wantquit = false;
|
||||
|
||||
// set the qbyte swapping variables in a portable manner
|
||||
if ( *(short *)swaptest == 1)
|
||||
{
|
||||
|
|
|
@ -112,7 +112,7 @@ void QCLoadBreakpoints(const char *vmname, const char *progsname)
|
|||
printf("qcreloaded \"%s\" \"%s\"\n", vmname, progsname);
|
||||
fflush(stdout);
|
||||
INS_UpdateGrabs(false, false);
|
||||
while(debuggerresume == -1)
|
||||
while(debuggerresume == -1 && !wantquit)
|
||||
{
|
||||
Sleep(10);
|
||||
Sys_SendKeyEvents();
|
||||
|
@ -236,6 +236,7 @@ qboolean QCExternalDebuggerCommand(char *text)
|
|||
if (sv.state)
|
||||
Cbuf_AddText("restart\n", RESTRICT_LOCAL);
|
||||
#endif
|
||||
Host_EndGame("Reloading QC");
|
||||
}
|
||||
else if (!strncmp(text, "qcbreakpoint ", 13))
|
||||
{
|
||||
|
@ -273,6 +274,8 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int
|
|||
#if defined(_WIN32) && !defined(SERVERONLY) && !defined(FTE_SDL)
|
||||
if (isPlugin >= 2)
|
||||
{
|
||||
if (wantquit)
|
||||
return DEBUG_TRACE_ABORT;
|
||||
if (!*filename || !line || !*line) //don't try editing an empty line, it won't work
|
||||
return DEBUG_TRACE_OFF;
|
||||
Sys_SendKeyEvents();
|
||||
|
@ -295,7 +298,7 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int
|
|||
Con_Footerf(false, "^bDebugging: %s", reason);
|
||||
else
|
||||
Con_Footerf(false, "^bDebugging");
|
||||
while(debuggerresume == -1)
|
||||
while(debuggerresume == -1 && !wantquit)
|
||||
{
|
||||
Sleep(10);
|
||||
Sys_SendKeyEvents();
|
||||
|
@ -316,6 +319,8 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int
|
|||
*line = debuggerresumeline;
|
||||
debuggerinstance = NULL;
|
||||
debuggerfile = NULL;
|
||||
if (wantquit)
|
||||
return DEBUG_TRACE_ABORT;
|
||||
return debuggerresume;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1163,6 +1163,12 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
|
|||
else
|
||||
t = missing_texture;
|
||||
break;
|
||||
case T_GEN_PALETTED:
|
||||
if (shaderstate.curtexnums && TEXLOADED(shaderstate.curtexnums->paletted))
|
||||
t = shaderstate.curtexnums->paletted;
|
||||
else
|
||||
t = missing_texture;
|
||||
break;
|
||||
case T_GEN_NORMALMAP:
|
||||
t = (shaderstate.curtexnums && TEXLOADED(shaderstate.curtexnums->bump))?shaderstate.curtexnums->bump:missing_texture_normal;
|
||||
break;
|
||||
|
@ -5171,6 +5177,7 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
|
|||
#endif
|
||||
shaderstate.identitylighting = 1;
|
||||
shaderstate.identitylightmap = shaderstate.identitylighting / (1<<gl_overbright.ival);
|
||||
shaderstate.identitylightmap =1;
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
if (r_lightprepass.ival)
|
||||
|
|
|
@ -233,16 +233,16 @@ static void GL_Texturemode_Apply(GLenum targ, unsigned int flags)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((filter[1] && !(flags & IF_NEAREST)) || (flags & IF_LINEAR))
|
||||
if ((filter[1]))// && !(flags & IF_NEAREST)) || (flags & IF_LINEAR))
|
||||
{
|
||||
if (filter[0])
|
||||
if (filter[0] && !(flags & IF_NEAREST) || (flags & IF_LINEAR))
|
||||
min = GL_LINEAR_MIPMAP_LINEAR;
|
||||
else
|
||||
min = GL_NEAREST_MIPMAP_LINEAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filter[0])
|
||||
if (filter[0] && !(flags & IF_NEAREST) || (flags & IF_LINEAR))
|
||||
min = GL_LINEAR_MIPMAP_NEAREST;
|
||||
else
|
||||
min = GL_NEAREST_MIPMAP_NEAREST;
|
||||
|
@ -448,7 +448,7 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
|
|||
if (targ != GL_TEXTURE_CUBE_MAP_ARB && (tex->flags & IF_MIPCAP))
|
||||
{
|
||||
qglTexParameteri(targ, GL_TEXTURE_BASE_LEVEL, min(mips->mipcount-1, gl_mipcap_min));
|
||||
qglTexParameteri(targ, GL_TEXTURE_MAX_LEVEL, min(mips->mipcount, gl_mipcap_max));
|
||||
qglTexParameteri(targ, GL_TEXTURE_MAX_LEVEL, min(mips->mipcount-1, gl_mipcap_max));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
extern cvar_t r_shadow_bumpscale_basetexture;
|
||||
extern cvar_t r_replacemodels;
|
||||
extern cvar_t gl_lightmap_average;
|
||||
extern cvar_t r_softwarebanding;
|
||||
cvar_t mod_loadentfiles = CVAR("sv_loadentfiles", "1");
|
||||
cvar_t mod_external_vis = CVARD("mod_external_vis", "1", "Attempt to load .vis patches for quake maps, allowing transparent water to work properly.");
|
||||
cvar_t mod_warnmodels = CVARD("mod_warnmodels", "1", "Warn if any models failed to load. Set to 0 if your mod is likely to lack optional models (like its in development)."); //set to 0 for hexen2 and its otherwise-spammy-as-heck demo.
|
||||
|
@ -1397,6 +1398,7 @@ void Mod_FinishTexture(texture_t *tx)
|
|||
#define LMT_FULLBRIGHT 2
|
||||
#define LMT_BUMP 4
|
||||
#define LMT_SPEC 8
|
||||
#define LMT_PALETTED 16
|
||||
static void Mod_LoadMiptex(model_t *loadmodel, char *loadname, texture_t *tx, miptex_t *mt, int maps)
|
||||
{
|
||||
#ifndef SERVERONLY
|
||||
|
@ -1455,6 +1457,12 @@ static void Mod_LoadMiptex(model_t *loadmodel, char *loadname, texture_t *tx, mi
|
|||
mipheight = tx->height;
|
||||
}
|
||||
|
||||
if (maps & LMT_PALETTED)
|
||||
{
|
||||
snprintf(altname, sizeof(altname)-1, "%s_pal", mt->name);
|
||||
tx->texnums.paletted = R_LoadReplacementTexture(altname, loadname, ((*mt->name == '{')?0:IF_NOALPHA)|IF_MIPCAP|IF_NEAREST, mipbase, mipwidth, mipheight, TF_LUM8);
|
||||
}
|
||||
|
||||
if (maps & LMT_DIFFUSE)
|
||||
{
|
||||
tx->texnums.base = R_LoadReplacementTexture(mt->name, loadname, ((*mt->name == '{')?0:IF_NOALPHA)|IF_MIPCAP, mipbase, mipwidth, mipheight, (*mt->name == '{')?TF_TRANS8:TF_SOLID8);
|
||||
|
@ -1580,7 +1588,11 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
|||
#ifndef SERVERONLY
|
||||
if (qrenderer != QR_NONE)
|
||||
{
|
||||
maps |= LMT_DIFFUSE;
|
||||
//FIXME: we really need to handle this stuff better, but the shader isn't known yet.
|
||||
if (r_softwarebanding.ival)
|
||||
maps |= LMT_PALETTED;
|
||||
// else
|
||||
maps |= LMT_DIFFUSE;
|
||||
if (r_fb_bmodels.ival)
|
||||
maps |= LMT_FULLBRIGHT;
|
||||
if (r_loadbumpmapping || (r_waterstyle.ival > 1 && *tx->name == '*'))
|
||||
|
|
|
@ -48,7 +48,7 @@ sh_config_t sh_config;
|
|||
cvar_t r_vertexlight = CVARFD("r_vertexlight", "0", CVAR_SHADERSYSTEM, "Hack loaded shaders to remove detail pass and lightmap sampling for faster rendering.");
|
||||
extern cvar_t r_glsl_offsetmapping_reliefmapping;
|
||||
extern cvar_t r_deluxemapping;
|
||||
extern cvar_t r_fastturb, r_fastsky, r_skyboxname;
|
||||
extern cvar_t r_fastturb, r_fastsky, r_skyboxname, r_softwarebanding;
|
||||
extern cvar_t r_drawflat;
|
||||
extern cvar_t r_shaderblobs;
|
||||
|
||||
|
@ -652,6 +652,26 @@ static int Shader_SetImageFlags(shader_t *shader, shaderpass_t *pass, char **nam
|
|||
return flags;
|
||||
}
|
||||
|
||||
texid_t R_LoadColourmapImage(void)
|
||||
{
|
||||
unsigned int w = 256, h = VID_GRADES-1;
|
||||
unsigned int x;
|
||||
unsigned int data[256*(VID_GRADES-1)];
|
||||
qbyte *colourmappal = (qbyte *)FS_LoadMallocFile ("gfx/colormap.lmp", NULL);
|
||||
if (colourmappal)
|
||||
{
|
||||
for (x = 0; x < sizeof(data)/sizeof(data[0]); x++)
|
||||
data[x] = d_8to24rgbtable[colourmappal[x]];
|
||||
}
|
||||
else
|
||||
{ //erk
|
||||
for (x = 0; x < sizeof(data)/sizeof(data[0]); x++)
|
||||
data[x] = d_8to24rgbtable[x & 0xff];
|
||||
}
|
||||
BZ_Free(colourmappal);
|
||||
return R_LoadTexture("$colourmap", w, h, TF_RGBA32, data, IF_NOMIPMAP|IF_NOPICMIP|IF_NEAREST|IF_NOGAMMA|IF_CLAMP);
|
||||
}
|
||||
|
||||
static texid_t Shader_FindImage ( char *name, int flags )
|
||||
{
|
||||
if (parsestate.mode == SPM_DOOM3)
|
||||
|
@ -670,6 +690,8 @@ static texid_t Shader_FindImage ( char *name, int flags )
|
|||
{
|
||||
if (!Q_stricmp (name, "$whiteimage"))
|
||||
return r_whiteimage;
|
||||
if (!Q_stricmp (name, "$colourmap"))
|
||||
return R_LoadColourmapImage();
|
||||
}
|
||||
if (flags & IF_RENDERTARGET)
|
||||
return R2D_RT_Configure(name, 0, 0, TF_INVALID);
|
||||
|
@ -2068,6 +2090,11 @@ static qboolean Shaderpass_MapGen (shader_t *shader, shaderpass_t *pass, char *t
|
|||
pass->texgen = T_GEN_DIFFUSE;
|
||||
shader->flags |= SHADER_HASDIFFUSE;
|
||||
}
|
||||
else if (!Q_stricmp (tname, "$paletted"))
|
||||
{
|
||||
pass->texgen = T_GEN_PALETTED;
|
||||
shader->flags |= SHADER_HASPALETTED;
|
||||
}
|
||||
else if (!Q_stricmp (tname, "$normalmap"))
|
||||
{
|
||||
pass->texgen = T_GEN_NORMALMAP;
|
||||
|
@ -3797,6 +3824,9 @@ done:;
|
|||
|
||||
if (pass->texgen != T_GEN_ANIMMAP && pass->texgen != T_GEN_SINGLEMAP && pass->texgen != T_GEN_VIDEOMAP)
|
||||
weight += 1000;
|
||||
|
||||
if ((pass->texgen == T_GEN_ANIMMAP || pass->texgen == T_GEN_SINGLEMAP) && pass->anim_frames[0] && *pass->anim_frames[0]->ident == '$')
|
||||
weight += 1500;
|
||||
|
||||
if (weight < bestweight)
|
||||
{
|
||||
|
@ -4042,6 +4072,17 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
|
|||
TEXASSIGN(shader->defaulttextures.base, tn->base);
|
||||
}
|
||||
|
||||
if (!TEXVALID(shader->defaulttextures.paletted))
|
||||
{
|
||||
/*dlights/realtime lighting needs some stuff*/
|
||||
// if (!TEXVALID(tn->paletted) && *shader->mapname)// && (shader->flags & SHADER_HASDIFFUSE))
|
||||
// tn->paletted = R_LoadHiResTexture(shader->mapname, NULL, 0);
|
||||
// if (!TEXVALID(tn->paletted))
|
||||
// tn->paletted = R_LoadHiResTexture(imagename, subpath, (*imagename=='{')?0:IF_NOALPHA);
|
||||
|
||||
TEXASSIGN(shader->defaulttextures.paletted, tn->paletted);
|
||||
}
|
||||
|
||||
COM_StripExtension(imagename, imagename, sizeof(imagename));
|
||||
|
||||
if (!TEXVALID(shader->defaulttextures.bump))
|
||||
|
@ -4667,6 +4708,34 @@ void Shader_DefaultBSPQ1(const char *shortname, shader_t *s, const void *args)
|
|||
);
|
||||
}
|
||||
|
||||
if (!builtin && r_softwarebanding.ival)
|
||||
{
|
||||
/*alpha bended*/
|
||||
builtin = (
|
||||
"{\n"
|
||||
"program defaultwall#EIGHTBIT\n"
|
||||
"{\n"
|
||||
"map $paletted\n"//$diffuse\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
"map $lightmap\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
"map $normalmap\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
"map $deluxmap\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
"map $colourmap\n"//$fullbright\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
"map $specular\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
|
||||
if (builtin)
|
||||
Shader_DefaultScript(shortname, s, builtin);
|
||||
else
|
||||
|
|
|
@ -2255,6 +2255,7 @@ LONG WINAPI GLMainWndProc (
|
|||
MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES)
|
||||
{
|
||||
Cbuf_AddText("\nquit\n", RESTRICT_LOCAL);
|
||||
wantquit = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -1057,9 +1057,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#ifdef LIGHTSTYLED\n"
|
||||
//we could use an offset, but that would still need to be per-surface which would break batches
|
||||
//fixme: merge attributes?
|
||||
"varying vec2 lm, lm2, lm3, lm4;\n"
|
||||
"varying vec2 lm0, lm1, lm2, lm3;\n"
|
||||
"#else\n"
|
||||
"varying vec2 lm;\n"
|
||||
"varying vec2 lm0;\n"
|
||||
"#endif\n"
|
||||
|
||||
"#ifdef VERTEX_SHADER\n"
|
||||
|
@ -1085,11 +1085,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"eyevector.z = dot(eyeminusvertex, v_normal.xyz);\n"
|
||||
"#endif\n"
|
||||
"tc = v_texcoord;\n"
|
||||
"lm = v_lmcoord;\n"
|
||||
"lm0 = v_lmcoord;\n"
|
||||
"#ifdef LIGHTSTYLED\n"
|
||||
"lm2 = v_lmcoord2;\n"
|
||||
"lm3 = v_lmcoord3;\n"
|
||||
"lm4 = v_lmcoord4;\n"
|
||||
"lm1 = v_lmcoord2;\n"
|
||||
"lm2 = v_lmcoord3;\n"
|
||||
"lm3 = v_lmcoord4;\n"
|
||||
"#endif\n"
|
||||
"gl_Position = ftetransform();\n"
|
||||
"}\n"
|
||||
|
@ -1097,28 +1097,44 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
|
||||
|
||||
"#ifdef FRAGMENT_SHADER\n"
|
||||
|
||||
//samplers
|
||||
"uniform sampler2D s_t0; //diffuse\n"
|
||||
"uniform sampler2D s_t1; //lightmap0\n"
|
||||
"#define s_diffuse s_t0\n"
|
||||
"#define s_lightmap0 s_t1\n"
|
||||
"#define s_normalmap s_t2\n"
|
||||
"#define s_delux0 s_t3\n"
|
||||
"#define s_fullbright s_t4\n"
|
||||
"#define s_specular s_t5\n"
|
||||
"#define s_lightmap1 s_t6\n"
|
||||
"#define s_lightmap2 s_t7\n"
|
||||
"#define s_lightmap3 s_t8\n"
|
||||
"#define s_delux1 s_t9\n"
|
||||
"#define s_delux2 s_t10\n"
|
||||
"#define s_delux3 s_t11\n"
|
||||
"#define s_paletted s_diffuse\n"
|
||||
"#define s_colourmap s_fullbright\n"
|
||||
|
||||
"uniform sampler2D s_diffuse;\n"
|
||||
"uniform sampler2D s_lightmap0;\n"
|
||||
"#if defined(BUMP) && (defined(OFFSETMAPPING) || defined(DELUXE) || defined(SPECULAR))\n"
|
||||
"uniform sampler2D s_t2; //normal.rgb+height.a\n"
|
||||
"uniform sampler2D s_normalmap;\n"
|
||||
"#endif\n"
|
||||
"#ifdef DELUXE\n"
|
||||
"uniform sampler2D s_t3; //deluxe0\n"
|
||||
"uniform sampler2D s_delux0;\n"
|
||||
"#endif\n"
|
||||
"#ifdef FULLBRIGHT\n"
|
||||
"uniform sampler2D s_t4; //fullbright\n"
|
||||
"#if defined(FULLBRIGHT) || defined(EIGHTBIT)\n"
|
||||
"uniform sampler2D s_fullbright;\n"
|
||||
"#endif\n"
|
||||
"#ifdef SPECULAR\n"
|
||||
"uniform sampler2D s_t5; //specular\n"
|
||||
"uniform sampler2D s_specular;\n"
|
||||
"#endif\n"
|
||||
"#ifdef LIGHTSTYLED\n"
|
||||
"uniform sampler2D s_t6; //lightmap1\n"
|
||||
"uniform sampler2D s_t7; //lightmap2\n"
|
||||
"uniform sampler2D s_t8; //lightmap3\n"
|
||||
"uniform sampler2D s_t9; //deluxe1\n"
|
||||
"uniform sampler2D s_t10; //deluxe2\n"
|
||||
"uniform sampler2D s_t11; //deluxe3\n"
|
||||
"uniform sampler2D s_lightmap1;\n"
|
||||
"uniform sampler2D s_lightmap2;\n"
|
||||
"uniform sampler2D s_lightmap3;\n"
|
||||
"uniform sampler2D s_delux1;\n"
|
||||
"uniform sampler2D s_delux2;\n"
|
||||
"uniform sampler2D s_delux3;\n"
|
||||
"#endif\n"
|
||||
|
||||
"#ifdef LIGHTSTYLED\n"
|
||||
|
@ -1137,15 +1153,24 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"{\n"
|
||||
//adjust texture coords for offsetmapping
|
||||
"#ifdef OFFSETMAPPING\n"
|
||||
"vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);\n"
|
||||
"vec2 tcoffsetmap = offsetmap(s_normalmap, tc, eyevector);\n"
|
||||
"#define tc tcoffsetmap\n"
|
||||
"#endif\n"
|
||||
|
||||
"#if defined(EIGHTBIT) && !defined(LIGHTSTYLED)\n"
|
||||
//optional: round the lightmap coords to ensure all pixels within a texel have different lighting values either. it just looks wrong otherwise.
|
||||
//don't bother if its lightstyled, such cases will have unpredictable correlations anyway.
|
||||
//FIXME: this rounding is likely not correct with respect to software rendering. oh well.
|
||||
"vec2 lmcoord0 = floor(lm0 * 256.0*8.0)/(256.0*8.0);\n"
|
||||
"#define lm0 lmcoord0\n"
|
||||
"#endif\n"
|
||||
|
||||
|
||||
//yay, regular texture!
|
||||
"gl_FragColor = texture2D(s_t0, tc);\n"
|
||||
"gl_FragColor = texture2D(s_diffuse, tc);\n"
|
||||
|
||||
"#if defined(BUMP) && (defined(DELUXE) || defined(SPECULAR))\n"
|
||||
"vec3 norm = normalize(texture2D(s_t2, tc).rgb - 0.5);\n"
|
||||
"vec3 norm = normalize(texture2D(s_normalmap, tc).rgb - 0.5);\n"
|
||||
"#elif defined(SPECULAR) || defined(DELUXE)\n"
|
||||
"vec3 norm = vec3(0, 0, 1); //specular lighting expects this to exist.\n"
|
||||
"#endif\n"
|
||||
|
@ -1154,29 +1179,30 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#ifdef LIGHTSTYLED\n"
|
||||
"vec3 lightmaps;\n"
|
||||
"#ifdef DELUXE\n"
|
||||
"lightmaps = texture2D(s_t1, lm ).rgb * e_lmscale[0].rgb * dot(norm, texture2D(s_t3, lm ).rgb);\n"
|
||||
"lightmaps += texture2D(s_t6, lm2).rgb * e_lmscale[1].rgb * dot(norm, texture2D(s_t9, lm2).rgb);\n"
|
||||
"lightmaps += texture2D(s_t7, lm3).rgb * e_lmscale[2].rgb * dot(norm, texture2D(s_t10, lm3).rgb);\n"
|
||||
"lightmaps += texture2D(s_t8, lm4).rgb * e_lmscale[3].rgb * dot(norm, texture2D(s_t11,lm4).rgb);\n"
|
||||
"lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_delux0, lm0).rgb-0.5);\n"
|
||||
"lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_delux1, lm1).rgb-0.5);\n"
|
||||
"lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_delux2, lm2).rgb-0.5);\n"
|
||||
"lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_delux3, lm3).rgb-0.5);\n"
|
||||
"#else\n"
|
||||
"lightmaps = texture2D(s_t1, lm ).rgb * e_lmscale[0].rgb;\n"
|
||||
"lightmaps += texture2D(s_t6, lm2).rgb * e_lmscale[1].rgb;\n"
|
||||
"lightmaps += texture2D(s_t7, lm3).rgb * e_lmscale[2].rgb;\n"
|
||||
"lightmaps += texture2D(s_t8, lm4).rgb * e_lmscale[3].rgb;\n"
|
||||
"lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb;\n"
|
||||
"lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb;\n"
|
||||
"lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb;\n"
|
||||
"lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb;\n"
|
||||
"#endif\n"
|
||||
"#else\n"
|
||||
"vec3 lightmaps = (texture2D(s_t1, lm) * e_lmscale).rgb;\n"
|
||||
"vec3 lightmaps = (texture2D(s_lightmap0, lm0) * e_lmscale).rgb;\n"
|
||||
//modulate by the bumpmap dot light
|
||||
"#ifdef DELUXE\n"
|
||||
"lightmaps *= dot(norm, 2.0*(texture2D(s_t3, lm).rgb-0.5));\n"
|
||||
"lightmaps *= dot(norm, 2.0*(texture2D(s_delux0, lm0).rgb-0.5));\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
|
||||
//add in specular, if applicable.
|
||||
"#ifdef SPECULAR\n"
|
||||
"vec4 specs = texture2D(s_t5, tc);\n"
|
||||
"vec4 specs = texture2D(s_specular, tc);\n"
|
||||
"#ifdef DELUXE\n"
|
||||
//not lightstyled...
|
||||
"vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_t3, lm).rgb-0.5)); //this norm should be the deluxemap info instead\n"
|
||||
"vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_delux0, lm).rgb-0.5)); //this norm should be the deluxemap info instead\n"
|
||||
"#else\n"
|
||||
"vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead\n"
|
||||
"#endif\n"
|
||||
|
@ -1189,13 +1215,23 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"gl_FragColor.rgb += spec * specs.rgb;\n"
|
||||
"#endif\n"
|
||||
|
||||
"#ifdef EIGHTBIT //FIXME: with this extra flag, half the permutations are redundant.\n"
|
||||
"lightmaps *= 0.5; //counter the fact that the colourmap contains overbright values and logically ranges from 0 to 2 intead of to 1.\n"
|
||||
"float pal = texture2D(s_diffuse, tc).r; //the palette index. hopefully not interpolated.\n"
|
||||
"lightmaps -= 1.0 / 128.0; //software rendering appears to round down, so make sure we favour the lower values instead of rounding to the nearest\n"
|
||||
"gl_FragColor.r = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.r)).r; //do 3 lookups. this is to cope with lit files, would be a waste to not support those.\n"
|
||||
"gl_FragColor.g = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.g)).g; //its not very softwarey, but re-palettizing is ugly.\n"
|
||||
"gl_FragColor.b = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.b)).b; //without lits, it should be identical.\n"
|
||||
"#else\n"
|
||||
//now we have our diffuse+specular terms, modulate by lightmap values.
|
||||
"gl_FragColor.rgb *= lightmaps.rgb;\n"
|
||||
|
||||
//add on the fullbright
|
||||
"#ifdef FULLBRIGHT\n"
|
||||
"gl_FragColor.rgb += texture2D(s_t4, tc).rgb;\n"
|
||||
"gl_FragColor.rgb += texture2D(s_fullbright, tc).rgb;\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
|
||||
|
||||
//entity modifiers
|
||||
"gl_FragColor = gl_FragColor * e_colourident;\n"
|
||||
|
|
|
@ -255,6 +255,7 @@ typedef struct shaderpass_s {
|
|||
T_GEN_UPPEROVERLAY, //texture's default personal colour
|
||||
T_GEN_LOWEROVERLAY, //texture's default team colour
|
||||
T_GEN_FULLBRIGHT, //texture's default fullbright overlay
|
||||
T_GEN_PALETTED, //texture's original paletted data (8bit)
|
||||
|
||||
T_GEN_CURRENTRENDER,//copy the current screen to a texture, and draw that
|
||||
|
||||
|
@ -544,6 +545,7 @@ struct shader_s
|
|||
SHADER_NOSHADOWS = 1 << 25, //don't cast shadows
|
||||
SHADER_HASFULLBRIGHT = 1 << 26, //needs a fullbright texture, if possible.
|
||||
SHADER_HASDIFFUSE = 1 << 27, //has a T_GEN_DIFFUSE pass
|
||||
SHADER_HASPALETTED = 1 << 28, //has a T_GEN_PALETTED pass
|
||||
} flags;
|
||||
|
||||
program_t *prog;
|
||||
|
|
|
@ -8614,6 +8614,19 @@ static void QCBUILTIN PF_globalstat(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
#endif
|
||||
}
|
||||
|
||||
//void(float num, float type, void *ptr) pointerstat
|
||||
static void QCBUILTIN PF_pointerstat(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int num = G_FLOAT(OFS_PARM0);
|
||||
int type = G_FLOAT(OFS_PARM1);
|
||||
int addr = G_INT(OFS_PARM2);
|
||||
int size = (type == ev_vector)?sizeof(vec3_t):sizeof(float);
|
||||
if (addr < 0 || addr+size >= prinst->stringtablesize)
|
||||
prinst->RunError(prinst, "QCVM address %#x is not valid.", addr);
|
||||
else
|
||||
SV_QCStatPtr(type, prinst->stringtable+addr, num);
|
||||
}
|
||||
|
||||
//EXT_CSQC_1
|
||||
static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -8624,6 +8637,13 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
|
|||
extern cvar_t sv_gravity;
|
||||
edict_t *ent = G_EDICT(prinst, OFS_PARM0);
|
||||
edict_t *touched;
|
||||
|
||||
if (ent->readonly)
|
||||
{
|
||||
Con_Printf("runplayerphysics called on read-only entity");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pr_global_ptrs->clientcommandframe)
|
||||
pmove.sequence = *pr_global_ptrs->clientcommandframe;
|
||||
else
|
||||
|
@ -9443,7 +9463,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
|
||||
//EXT_CSQC
|
||||
{"clientstat", PF_clientstat, 0, 0, 0, 232, D("void(float num, float type, .__variant fld)", "Specifies what data to use in order to send various stats, in a client-specific way.\n'num' should be a value between 32 and 127, other values are reserved.\n'type' must be set to one of the EV_* constants, one of EV_FLOAT, EV_STRING, EV_INTEGER, EV_ENTITY.\nfld must be a reference to the field used, each player will be sent only their own copy of these fields.")}, //EXT_CSQC
|
||||
{"globalstat", PF_globalstat, 0, 0, 0, 233, D("void(float num, float type, string name)", "Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, name however, is the name of the global to read in the form of a string.")}, //EXT_CSQC_1 actually
|
||||
{"globalstat", PF_globalstat, 0, 0, 0, 233, D("void(float num, float type, string name)", "Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, name however, is the name of the global to read in the form of a string (pass \"foo\").")}, //EXT_CSQC_1 actually
|
||||
{"pointerstat", PF_pointerstat, 0, 0, 0, 0, D("void(float num, float type, __variant *address)", "Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, address however, is the address of the variable you would like to use (pass &foo).")},
|
||||
//END EXT_CSQC
|
||||
{"isbackbuffered", PF_isbackbuffered, 0, 0, 0, 234, D("float(entity player)", "Returns if the given player's network buffer will take multiple network frames in order to clear. If this builtin returns non-zero, you should delay or reduce the amount of reliable (and also unreliable) data that you are sending to that client.")},
|
||||
{"rotatevectorsbyangle",PF_rotatevectorsbyangles,0,0, 0, 235, "void(vector angle)"}, // #235
|
||||
|
|
|
@ -581,6 +581,7 @@ typedef struct client_s
|
|||
//note, nq is nq+
|
||||
} protocol;
|
||||
|
||||
unsigned int lastruncmd; //for non-qw physics. timestamp they were last run, so switching between physics modes isn't a (significant) cheat
|
||||
//speed cheat testing
|
||||
#define NEWSPEEDCHEATPROT
|
||||
int msecs;
|
||||
|
|
|
@ -2316,16 +2316,15 @@ void World_Physics_Frame(world_t *w)
|
|||
}
|
||||
else
|
||||
{
|
||||
float newt;
|
||||
float delt;
|
||||
unsigned int newt;
|
||||
unsigned int delt;
|
||||
newt = sv.time*1000;
|
||||
delt = newt - svs.clients[i-1].msecs;
|
||||
if (delt > 1000/77.0 || delt < -10)
|
||||
delt = newt - svs.clients[i-1].lastruncmd;
|
||||
if (delt > (int)(1000/77.0) || delt < -10)
|
||||
{
|
||||
float ft = host_frametime;
|
||||
host_client = &svs.clients[i-1];
|
||||
sv_player = svs.clients[i-1].edict;
|
||||
svs.clients[i-1].msecs = newt;
|
||||
SV_PreRunCmd();
|
||||
#ifndef NEWSPEEDCHEATPROT
|
||||
svs.clients[i-1].last_check = 0;
|
||||
|
|
|
@ -1559,15 +1559,15 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
|
|||
if (nqjunk)
|
||||
{
|
||||
MSG_WriteShort (msg, ent->v->health);
|
||||
MSG_WriteByte (msg, ent->v->currentammo);
|
||||
MSG_WriteByte (msg, ent->v->ammo_shells);
|
||||
MSG_WriteByte (msg, ent->v->ammo_nails);
|
||||
MSG_WriteByte (msg, ent->v->ammo_rockets);
|
||||
MSG_WriteByte (msg, ent->v->ammo_cells);
|
||||
MSG_WriteByte (msg, min(ent->v->currentammo, 255));
|
||||
MSG_WriteByte (msg, min(ent->v->ammo_shells, 255));
|
||||
MSG_WriteByte (msg, min(ent->v->ammo_nails, 255));
|
||||
MSG_WriteByte (msg, min(ent->v->ammo_rockets, 255));
|
||||
MSG_WriteByte (msg, min(ent->v->ammo_cells, 255));
|
||||
|
||||
if (standard_quake)
|
||||
{
|
||||
MSG_WriteByte (msg, ent->v->weapon);
|
||||
MSG_WriteByte (msg, (unsigned int)ent->v->weapon & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1618,7 +1618,8 @@ void SV_QCStatEval(int type, char *name, evalc_t *field, eval_t *global, int sta
|
|||
|
||||
for (i = 0; i < numqcstats; i++)
|
||||
{
|
||||
if (qcstats[i].statnum == statnum)
|
||||
//strings use a different namespace.
|
||||
if (qcstats[i].statnum == statnum && ((qcstats[i].type == ev_string||qcstats[i].type == -ev_string) == (type == ev_string||type == -ev_string)))
|
||||
break;
|
||||
}
|
||||
if (i == numqcstats)
|
||||
|
@ -2756,6 +2757,7 @@ void SV_SendClientMessages (void)
|
|||
if (c->nextservertimeupdate > pt + 6)
|
||||
c->nextservertimeupdate = 0;
|
||||
|
||||
c->netchan.cleartime = realtime - 100;
|
||||
c->netchan.nqunreliableonly = !c->send_message;
|
||||
c->datagram.cursize = 0;
|
||||
if (!c->send_message && c->nextservertimeupdate < pt)
|
||||
|
|
|
@ -4642,7 +4642,11 @@ void Cmd_Observe_f (void)
|
|||
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
|
||||
}
|
||||
else
|
||||
{
|
||||
sv_player->v->movetype = MOVETYPE_NOCLIP;
|
||||
sv_player->v->model = 0;
|
||||
sv_player->v->modelindex = 0;
|
||||
}
|
||||
sv.spawned_observer_slots++;
|
||||
|
||||
// send notification to all clients
|
||||
|
@ -4854,12 +4858,10 @@ void SVNQ_Spawn_f (void)
|
|||
ClientReliableWrite_Long (host_client, pr_global_struct->killed_monsters);
|
||||
}
|
||||
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_signonnum);
|
||||
MSG_WriteByte (&host_client->netchan.message, 3);
|
||||
|
||||
ClientReliableWrite_Begin (host_client, svc_signonnum, 2);
|
||||
ClientReliableWrite_Byte (host_client, 3);
|
||||
|
||||
host_client->send_message = true;
|
||||
|
||||
}
|
||||
void SVNQ_Begin_f (void)
|
||||
{
|
||||
|
@ -4984,7 +4986,7 @@ void SVNQ_PreSpawn_f (void)
|
|||
host_client->prespawn_idx = 0;
|
||||
|
||||
if (sv_mapcheck.value)
|
||||
Con_Printf("Warning: %s does cannot be applied to NQ clients.\n", sv_mapcheck.name); //as you can fake it in a client anyway, this is hardly a significant issue.
|
||||
Con_Printf("Warning: %s cannot be enforced on NQ clients.\n", sv_mapcheck.name); //as you can fake it in a client anyway, this is hardly a significant issue.
|
||||
}
|
||||
|
||||
host_client->send_message = true;
|
||||
|
@ -5852,6 +5854,10 @@ void SV_PreRunCmd(void)
|
|||
playertouch = BZ_Malloc((playertouchmax>>3)+1);
|
||||
}
|
||||
memset(playertouch, 0, playertouchmax>>3);
|
||||
|
||||
//timestamp it, so things can't go weird
|
||||
if (host_client)
|
||||
host_client->lastruncmd = sv.time * 1000;
|
||||
}
|
||||
void SV_RunCmdCleanup(void)
|
||||
{
|
||||
|
|
|
@ -19,9 +19,9 @@ varying vec2 tc;
|
|||
#ifdef LIGHTSTYLED
|
||||
//we could use an offset, but that would still need to be per-surface which would break batches
|
||||
//fixme: merge attributes?
|
||||
varying vec2 lm, lm2, lm3, lm4;
|
||||
varying vec2 lm0, lm1, lm2, lm3;
|
||||
#else
|
||||
varying vec2 lm;
|
||||
varying vec2 lm0;
|
||||
#endif
|
||||
|
||||
#ifdef VERTEX_SHADER
|
||||
|
@ -47,11 +47,11 @@ void main ()
|
|||
eyevector.z = dot(eyeminusvertex, v_normal.xyz);
|
||||
#endif
|
||||
tc = v_texcoord;
|
||||
lm = v_lmcoord;
|
||||
lm0 = v_lmcoord;
|
||||
#ifdef LIGHTSTYLED
|
||||
lm2 = v_lmcoord2;
|
||||
lm3 = v_lmcoord3;
|
||||
lm4 = v_lmcoord4;
|
||||
lm1 = v_lmcoord2;
|
||||
lm2 = v_lmcoord3;
|
||||
lm3 = v_lmcoord4;
|
||||
#endif
|
||||
gl_Position = ftetransform();
|
||||
}
|
||||
|
@ -59,28 +59,44 @@ void main ()
|
|||
|
||||
|
||||
#ifdef FRAGMENT_SHADER
|
||||
|
||||
//samplers
|
||||
uniform sampler2D s_t0; //diffuse
|
||||
uniform sampler2D s_t1; //lightmap0
|
||||
#define s_diffuse s_t0
|
||||
#define s_lightmap0 s_t1
|
||||
#define s_normalmap s_t2
|
||||
#define s_delux0 s_t3
|
||||
#define s_fullbright s_t4
|
||||
#define s_specular s_t5
|
||||
#define s_lightmap1 s_t6
|
||||
#define s_lightmap2 s_t7
|
||||
#define s_lightmap3 s_t8
|
||||
#define s_delux1 s_t9
|
||||
#define s_delux2 s_t10
|
||||
#define s_delux3 s_t11
|
||||
#define s_paletted s_diffuse
|
||||
#define s_colourmap s_fullbright
|
||||
|
||||
uniform sampler2D s_diffuse;
|
||||
uniform sampler2D s_lightmap0;
|
||||
#if defined(BUMP) && (defined(OFFSETMAPPING) || defined(DELUXE) || defined(SPECULAR))
|
||||
uniform sampler2D s_t2; //normal.rgb+height.a
|
||||
uniform sampler2D s_normalmap;
|
||||
#endif
|
||||
#ifdef DELUXE
|
||||
uniform sampler2D s_t3; //deluxe0
|
||||
uniform sampler2D s_delux0;
|
||||
#endif
|
||||
#ifdef FULLBRIGHT
|
||||
uniform sampler2D s_t4; //fullbright
|
||||
#if defined(FULLBRIGHT) || defined(EIGHTBIT)
|
||||
uniform sampler2D s_fullbright;
|
||||
#endif
|
||||
#ifdef SPECULAR
|
||||
uniform sampler2D s_t5; //specular
|
||||
uniform sampler2D s_specular;
|
||||
#endif
|
||||
#ifdef LIGHTSTYLED
|
||||
uniform sampler2D s_t6; //lightmap1
|
||||
uniform sampler2D s_t7; //lightmap2
|
||||
uniform sampler2D s_t8; //lightmap3
|
||||
uniform sampler2D s_t9; //deluxe1
|
||||
uniform sampler2D s_t10; //deluxe2
|
||||
uniform sampler2D s_t11; //deluxe3
|
||||
uniform sampler2D s_lightmap1;
|
||||
uniform sampler2D s_lightmap2;
|
||||
uniform sampler2D s_lightmap3;
|
||||
uniform sampler2D s_delux1;
|
||||
uniform sampler2D s_delux2;
|
||||
uniform sampler2D s_delux3;
|
||||
#endif
|
||||
|
||||
#ifdef LIGHTSTYLED
|
||||
|
@ -99,15 +115,24 @@ void main ()
|
|||
{
|
||||
//adjust texture coords for offsetmapping
|
||||
#ifdef OFFSETMAPPING
|
||||
vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);
|
||||
vec2 tcoffsetmap = offsetmap(s_normalmap, tc, eyevector);
|
||||
#define tc tcoffsetmap
|
||||
#endif
|
||||
|
||||
#if defined(EIGHTBIT) && !defined(LIGHTSTYLED)
|
||||
//optional: round the lightmap coords to ensure all pixels within a texel have different lighting values either. it just looks wrong otherwise.
|
||||
//don't bother if its lightstyled, such cases will have unpredictable correlations anyway.
|
||||
//FIXME: this rounding is likely not correct with respect to software rendering. oh well.
|
||||
vec2 lmcoord0 = floor(lm0 * 256.0*8.0)/(256.0*8.0);
|
||||
#define lm0 lmcoord0
|
||||
#endif
|
||||
|
||||
|
||||
//yay, regular texture!
|
||||
gl_FragColor = texture2D(s_t0, tc);
|
||||
gl_FragColor = texture2D(s_diffuse, tc);
|
||||
|
||||
#if defined(BUMP) && (defined(DELUXE) || defined(SPECULAR))
|
||||
vec3 norm = normalize(texture2D(s_t2, tc).rgb - 0.5);
|
||||
vec3 norm = normalize(texture2D(s_normalmap, tc).rgb - 0.5);
|
||||
#elif defined(SPECULAR) || defined(DELUXE)
|
||||
vec3 norm = vec3(0, 0, 1); //specular lighting expects this to exist.
|
||||
#endif
|
||||
|
@ -116,29 +141,30 @@ void main ()
|
|||
#ifdef LIGHTSTYLED
|
||||
vec3 lightmaps;
|
||||
#ifdef DELUXE
|
||||
lightmaps = texture2D(s_t1, lm ).rgb * e_lmscale[0].rgb * dot(norm, texture2D(s_t3, lm ).rgb);
|
||||
lightmaps += texture2D(s_t6, lm2).rgb * e_lmscale[1].rgb * dot(norm, texture2D(s_t9, lm2).rgb);
|
||||
lightmaps += texture2D(s_t7, lm3).rgb * e_lmscale[2].rgb * dot(norm, texture2D(s_t10, lm3).rgb);
|
||||
lightmaps += texture2D(s_t8, lm4).rgb * e_lmscale[3].rgb * dot(norm, texture2D(s_t11,lm4).rgb);
|
||||
lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_delux0, lm0).rgb-0.5);
|
||||
lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_delux1, lm1).rgb-0.5);
|
||||
lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_delux2, lm2).rgb-0.5);
|
||||
lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_delux3, lm3).rgb-0.5);
|
||||
#else
|
||||
lightmaps = texture2D(s_t1, lm ).rgb * e_lmscale[0].rgb;
|
||||
lightmaps += texture2D(s_t6, lm2).rgb * e_lmscale[1].rgb;
|
||||
lightmaps += texture2D(s_t7, lm3).rgb * e_lmscale[2].rgb;
|
||||
lightmaps += texture2D(s_t8, lm4).rgb * e_lmscale[3].rgb;
|
||||
lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb;
|
||||
lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb;
|
||||
lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb;
|
||||
lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb;
|
||||
#endif
|
||||
#else
|
||||
vec3 lightmaps = (texture2D(s_t1, lm) * e_lmscale).rgb;
|
||||
vec3 lightmaps = (texture2D(s_lightmap0, lm0) * e_lmscale).rgb;
|
||||
//modulate by the bumpmap dot light
|
||||
#ifdef DELUXE
|
||||
lightmaps *= dot(norm, 2.0*(texture2D(s_t3, lm).rgb-0.5));
|
||||
lightmaps *= dot(norm, 2.0*(texture2D(s_delux0, lm0).rgb-0.5));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//add in specular, if applicable.
|
||||
#ifdef SPECULAR
|
||||
vec4 specs = texture2D(s_t5, tc);
|
||||
vec4 specs = texture2D(s_specular, tc);
|
||||
#ifdef DELUXE
|
||||
//not lightstyled...
|
||||
vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_t3, lm).rgb-0.5)); //this norm should be the deluxemap info instead
|
||||
vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_delux0, lm).rgb-0.5)); //this norm should be the deluxemap info instead
|
||||
#else
|
||||
vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead
|
||||
#endif
|
||||
|
@ -151,13 +177,23 @@ void main ()
|
|||
gl_FragColor.rgb += spec * specs.rgb;
|
||||
#endif
|
||||
|
||||
#ifdef EIGHTBIT //FIXME: with this extra flag, half the permutations are redundant.
|
||||
lightmaps *= 0.5; //counter the fact that the colourmap contains overbright values and logically ranges from 0 to 2 intead of to 1.
|
||||
float pal = texture2D(s_diffuse, tc).r; //the palette index. hopefully not interpolated.
|
||||
lightmaps -= 1.0 / 128.0; //software rendering appears to round down, so make sure we favour the lower values instead of rounding to the nearest
|
||||
gl_FragColor.r = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.r)).r; //do 3 lookups. this is to cope with lit files, would be a waste to not support those.
|
||||
gl_FragColor.g = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.g)).g; //its not very softwarey, but re-palettizing is ugly.
|
||||
gl_FragColor.b = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.b)).b; //without lits, it should be identical.
|
||||
#else
|
||||
//now we have our diffuse+specular terms, modulate by lightmap values.
|
||||
gl_FragColor.rgb *= lightmaps.rgb;
|
||||
|
||||
//add on the fullbright
|
||||
#ifdef FULLBRIGHT
|
||||
gl_FragColor.rgb += texture2D(s_t4, tc).rgb;
|
||||
gl_FragColor.rgb += texture2D(s_fullbright, tc).rgb;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//entity modifiers
|
||||
gl_FragColor = gl_FragColor * e_colourident;
|
||||
|
|
Loading…
Reference in a new issue