software banding: fix player skins.

try to get game controller defaults a little closer to QS.
mess with r_dynamic 2 a little, to more closely match vanilla.
fix under-lighting bug on models. added extra model lighting pathway for greater vanilla compat, as part of software-banding.
fix proquake-client compat issue.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5192 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2018-01-03 04:40:06 +00:00
parent c1392378f2
commit a6ac015c5b
26 changed files with 363 additions and 158 deletions

View File

@ -295,7 +295,13 @@ void CL_DecayLights (void)
continue;
}
dl->radius -= frametime*dl->decay;
if (r_dynamic.ival == 2)
{ //don't decay quite so fast, this should aproximate winquake a bit better.
dl->die -= frametime * 0.5;
dl->radius -= frametime*dl->decay * 0.5;
}
else
dl->radius -= frametime*dl->decay;
if (dl->radius < 0)
{
if (i==rtlights_first)

View File

@ -5279,10 +5279,13 @@ static void CL_SetStatMovevar(int pnum, int stat, int ivalue, float value)
movevars.stepheight = value;
break;
case STAT_MOVEVARS_TICRATE: //cl_maxfps limiter hint
if (value <= 0)
cls.maxfps = 1.0/value;
else
cls.maxfps = 72;
if (cls.protocol == CP_NETQUAKE && CPNQ_IS_DP)
{
if (value <= 0)
cls.maxfps = 1.0/value;
else
cls.maxfps = 72;
}
break;
case STAT_MOVEFLAGS:
// movevars.flags = ivalue;

View File

@ -1393,7 +1393,7 @@ qboolean CSQC_UseGamecodeLoadingScreen(void);
void CSQC_Shutdown(void);
qboolean CSQC_StuffCmd(int lplayernum, char *cmd, char *cmdend);
void CSQC_MapEntityEdited(int modelindex, int idx, const char *newe);
qboolean CSQC_LoadResource(char *resname, char *restype);
//qboolean CSQC_LoadResource(char *resname, char *restype);
qboolean CSQC_ParsePrint(char *message, int printlevel);
qboolean CSQC_ParseGamePacket(int seat);
qboolean CSQC_CenterPrint(int seat, const char *cmd);

View File

@ -4779,7 +4779,7 @@ static void Image_ChangeFormat(struct pendingtextureinfo *mips, unsigned int fla
mips->mip[mip].needfree = true;
for (i = 0; i < mips->mip[mip].width*mips->mip[mip].height; i++, in+=4)
out[i] = GetPaletteIndex(in[0], in[1], in[2]);
out[i] = GetPaletteIndexNoFB(in[0], in[1], in[2]);
if (needfree)
BZ_Free(needfree);

View File

@ -78,10 +78,10 @@ static cvar_t joy_advaxis[6] =
#define ADVAXISDESC (const char *)"Provides a way to remap each joystick/controller axis.\nShould be set to one of: moveforward, moveback, lookup, lookdown, turnleft, turnright, moveleft, moveright, moveup, movedown, rollleft, rollright"
CVARCD("joyadvaxisx", "turnright", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisy", "lookup", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisz", "moveup", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisz", "", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisr", "moveright", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisu", "moveforward", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisv", "rollright", joyaxiscallback, ADVAXISDESC)
CVARCD("joyadvaxisv", "", joyaxiscallback, ADVAXISDESC)
};
static cvar_t joy_advaxisscale[6] =
{

View File

@ -2704,20 +2704,20 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
//gamepad buttons should get fallbacks out of the box, even if they're not initially listed on the binds menu.
//these may be redefined later...
case K_GP_LEFT_SHOULDER: dc = "impulse 12"; goto defaultedbind; //matches QS's default.cfg
case K_GP_RIGHT_SHOULDER: dc = "impulse 10"; goto defaultedbind; //matches QS's default.cfg
case K_GP_LEFT_TRIGGER: dc = "+jump"; goto defaultedbind; //matches QS's default.cfg
case K_GP_RIGHT_TRIGGER: dc = "+attack"; goto defaultedbind; //matches QS's default.cfg
case K_GP_START: dc = "togglemenu"; goto defaultedbind;
case K_GP_A: dc = "+button4"; goto defaultedbind;
case K_GP_B: dc = "+button3"; goto defaultedbind;
case K_GP_LEFT_SHOULDER:
case K_GP_X: dc = "+attack"; goto defaultedbind;
case K_GP_RIGHT_SHOULDER:
case K_GP_Y: dc = "+jump"; goto defaultedbind;
case K_GP_BACK: dc = "impulse 10"; goto defaultedbind;
case K_GP_DPAD_UP: dc = "+forward"; goto defaultedbind;
case K_GP_DPAD_DOWN: dc = "+back"; goto defaultedbind;
case K_GP_DPAD_LEFT: dc = "+moveleft"; goto defaultedbind;
case K_GP_DPAD_RIGHT: dc = "+moveright"; goto defaultedbind;
case K_GP_LEFT_TRIGGER: dc = "+left"; goto defaultedbind;
case K_GP_RIGHT_TRIGGER: dc = "+right"; goto defaultedbind;
case K_GP_LEFT_THUMB: dc = "toggleconsole"; goto defaultedbind;
case K_GP_UNKNOWN:
case K_GP_RIGHT_THUMB:

View File

@ -491,7 +491,7 @@ static void PClassic_DrawParticles(void)
// Vector4Set(cl_strisvertc[cl_numstrisvert+1],1,1,1,1);
// Vector4Set(cl_strisvertc[cl_numstrisvert+2],1,1,1,1);
Vector4Set(cl_strisvertc[cl_numstrisvert+0], ((p->rgb&0xff)>>0)/256.0, ((p->rgb&0xff00)>>8)/256.0, ((p->rgb&0xff0000)>>16)/256.0, ((p->type == pt_fire && !r_part_classic_opaque.ival)?((6 - p->ramp) *0.166666):1.0));
Vector4Set(cl_strisvertc[cl_numstrisvert+0], ((p->rgb&0xff)>>0)/255.0, ((p->rgb&0xff00)>>8)/255.0, ((p->rgb&0xff0000)>>16)/255.0, ((p->type == pt_fire && !r_part_classic_opaque.ival)?((6 - p->ramp) *0.166666):1.0));
Vector4Copy(cl_strisvertc[cl_numstrisvert+0], cl_strisvertc[cl_numstrisvert+1]);
Vector4Copy(cl_strisvertc[cl_numstrisvert+0], cl_strisvertc[cl_numstrisvert+2]);

View File

@ -173,6 +173,7 @@ typedef struct {
blendmode_t blendmode;
shader_t *shader;
qboolean nearest;
float scalefactor;
float invscalefactor;
@ -914,7 +915,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
memset(&tn, 0, sizeof(tn));
if (*ptype->texname)
{
tn.base = R_LoadHiResTexture(ptype->texname, "particles", IF_LOADNOW | IF_NOMIPMAP|(ptype->looks.premul?IF_PREMULTIPLYALPHA:0)); //mipmapping breaks particlefont stuff
tn.base = R_LoadHiResTexture(ptype->texname, "particles", IF_LOADNOW | IF_NOMIPMAP|(ptype->looks.nearest?IF_NEAREST:IF_LINEAR)|(ptype->looks.premul?IF_PREMULTIPLYALPHA:0)); //mipmapping breaks particlefont stuff
if (tn.base && tn.base->status == TEX_LOADING)
COM_WorkerPartialSync(tn.base, &tn.base->status, TEX_LOADING);
}
@ -1245,8 +1246,11 @@ void P_ParticleEffect_f(void)
else
Cbuf_InsertText(buf, Cmd_ExecLevel, true);
}
else if (!strcmp(var, "texture"))
else if (!strcmp(var, "texture") || !strcmp(var, "linear_texture") || !strcmp(var, "nearest_texture") || !strcmp(var, "nearesttexture"))
{
Q_strncpyz(ptype->texname, value, sizeof(ptype->texname));
ptype->looks.nearest = !strncmp(var, "nearest", 7);
}
else if (!strcmp(var, "tcoords"))
{
float tscale;
@ -2383,7 +2387,7 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
if (*ptype->texname || all)
{ //note: particles don't really know if the shader was embedded or not. the shader system handles all that.
//this means that you'll really need to use external shaders for this to work.
Q_strncatz(outstr, va("texture \"%s\"\n", ptype->texname), outstrlen);
Q_strncatz(outstr, va("%stexture \"%s\"\n", ptype->looks.nearest?"nearest_":"", ptype->texname), outstrlen);
Q_strncatz(outstr, va("tcoords %g %g %g %g %g %i %g\n", ptype->s1, ptype->t1, ptype->s2, ptype->t2, 1.0f, ptype->randsmax, ptype->texsstride), outstrlen);
}

View File

@ -145,7 +145,7 @@ extern sfx_t *cl_sfx_r_exp3;
\
globalfunction(event_sound, "CSQC_Event_Sound"); \
globalfunction(serversound, "CSQC_ServerSound");/*obsolete, use event_sound*/ \
globalfunction(loadresource, "CSQC_LoadResource");/*EXT_CSQC_1*/ \
/*globalfunction(loadresource, "CSQC_LoadResource");*//*EXT_CSQC_1*/ \
globalfunction(parse_tempentity, "CSQC_Parse_TempEntity");/*EXT_CSQC_ABSOLUTLY_VILE*/ \
\
globalfunction(mapentityedited, "CSQC_MapEntityEdited");\
@ -3172,7 +3172,7 @@ static void QCBUILTIN PF_cs_sendevent (pubprogfuncs_t *prinst, struct globalvars
else if (argtypes[i] == 'i')
{
MSG_WriteByte(&cls.netchan.message, ev_integer);
MSG_WriteFloat(&cls.netchan.message, G_FLOAT(OFS_PARM2+i*3));
MSG_WriteLong(&cls.netchan.message, G_INT(OFS_PARM2+i*3));
}
else if (argtypes[i] == 'v')
{
@ -8027,7 +8027,7 @@ void CSQC_MapEntityEdited(int modelindex, int idx, const char *newe)
PR_ExecuteProgram (csqcprogs, csqcg.mapentityedited);
}
qboolean CSQC_LoadResource(char *resname, char *restype)
/*qboolean CSQC_LoadResource(char *resname, char *restype)
{
void *pr_globals;
if (!csqcprogs || !csqcg.loadresource)
@ -8040,7 +8040,7 @@ qboolean CSQC_LoadResource(char *resname, char *restype)
PR_ExecuteProgram (csqcprogs, csqcg.loadresource);
return !!G_FLOAT(OFS_RETURN);
}
}*/
qboolean CSQC_Parse_Damage(int seat, float save, float take, vec3_t source)
{

View File

@ -605,7 +605,7 @@ void QCBUILTIN PF_CL_drawsubpic (pubprogfuncs_t *prinst, struct globalvars_s *pr
mpic_t *p;
p = R2D_SafeCachePic(picname);
if (!p)
if (!p || !R_GetShaderSizes(p, NULL, NULL, false))
p = R2D_SafePicFromWad(picname);
r2d_be_flags = PF_SelectDPDrawFlag(flag);

View File

@ -105,6 +105,32 @@ qbyte GetPaletteIndex(int red, int green, int blue)
return best;
}
}
qbyte GetPaletteIndexNoFB(int red, int green, int blue)
{
//slow, horrible method.
{
int i, best=15;
int bestdif=256*256*256, curdif;
extern qbyte *host_basepal;
qbyte *pa;
#define _abs(x) ((x)*(x))
pa = host_basepal;
for (i = 0; i < 256 - vid.fullbright; i++, pa+=3)
{
curdif = _abs(red - pa[0]) + _abs(green - pa[1]) + _abs(blue - pa[2]);
if (curdif < bestdif)
{
if (curdif<1)
return i;
bestdif = curdif;
best = i;
}
}
return best;
}
}
void R2D_Shutdown(void)
{

View File

@ -519,7 +519,7 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
local[1] -= surf->texturemins[1];
if (r_dynamic.ival == 2)
r = g = b = 128;
r = g = b = 256;
else
{
r = cl_dlights[lnum].color[0]*128;

View File

@ -224,6 +224,12 @@ void V_StopPitchDrift (playerview_t *pv)
pv->pitchvel = 0;
}
void V_CenterView_f(void)
{
int pnum = CL_TargettedSplit(false);
V_StartPitchDrift(&cl.playerview[pnum]);
}
/*
===============
V_DriftPitch
@ -2354,7 +2360,7 @@ void V_Init (void)
Cmd_AddCommand ("bf", V_BonusFlash_f);
Cmd_AddCommand ("df", V_DarkFlash_f);
Cmd_AddCommand ("wf", V_WhiteFlash_f);
// Cmd_AddCommand ("centerview", V_StartPitchDrift);
Cmd_AddCommand ("centerview", V_CenterView_f);
Cvar_Register (&v_centermove, VIEWVARS);
Cvar_Register (&v_centerspeed, VIEWVARS);

View File

@ -257,7 +257,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MD5MODELS //doom3 models
#define ZYMOTICMODELS //zymotic skeletal models.
#define DPMMODELS //darkplaces model format (which I've never seen anyone use)
#define PSKMODELS //PSK model format (ActorX stuff from UT, though not the format the game itself uses)
// #define PSKMODELS //PSK model format (ActorX stuff from UT, though not the format the game itself uses)
#define HALFLIFEMODELS //halflife model support (experimental)
#define INTERQUAKEMODELS
#define RAGDOLL
@ -299,6 +299,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define DECOMPRESS_ETC2 //decompress etc2(core in gles3/gl4.3) if the graphics driver doesn't support it (eg d3d or crappy gpus with vulkan).
// #define DECOMPRESS_S3TC //allows bc1-3 to work even when drivers don't support it. This is probably only an issue on mobile chips. WARNING: not entirely sure if all patents expired yet...
#define DECOMPRESS_RGTC //bc4+bc5
//would be nice to have BPTC decompression too, for gl<4.2, d3d9, or d3d11_level10, but frankly its overcomplicated. I'm not going to bother with ASTC either.
#ifndef RTLIGHTS
#define RTLIGHTS //realtime lighting
#endif

View File

@ -816,16 +816,33 @@ void R_LightArrays(const entity_t *entity, vecV_t *coords, avec4_t *colours, int
{
l = DotProduct(normals[i], entity->light_dir);
#ifdef SSE_INTRINSICS
vl = _mm_load1_ps(&l);
vr = _mm_mul_ss(va,vl);
vr = _mm_add_ss(vr,vs);
if (l < 0)
{
_mm_storeu_ps(colours[i], va);
//stomp on colour[i][3] (will be set to 1)
}
else
{
vl = _mm_load1_ps(&l);
vr = _mm_mul_ss(va,vl);
vr = _mm_add_ss(vr,vs);
_mm_storeu_ps(colours[i], vr);
//stomp on colour[i][3] (will be set to 1)
_mm_storeu_ps(colours[i], vr);
//stomp on colour[i][3] (will be set to 1)
}
#else
colours[i][0] = l*lr[0]+la[0];
colours[i][1] = l*lr[1]+la[1];
colours[i][2] = l*lr[2]+la[2];
if (l < 0)
{ //don't over-shade the dark side of the mesh.
colours[i][0] = la[0];
colours[i][1] = la[1];
colours[i][2] = la[2];
}
else
{
colours[i][0] = l*lr[0]+la[0];
colours[i][1] = l*lr[1]+la[1];
colours[i][2] = l*lr[2]+la[2];
}
#endif
}
}
@ -5883,7 +5900,6 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
}
gmdl = ZG_Malloc(&mod->memgroup, sizeof(*gmdl)*num_matt);
Mod_DefaultMesh(gmdl, mod->name, 0);
/*bones!*/
bones = ZG_Malloc(&mod->memgroup, sizeof(galiasbone_t) * num_boneinfo);
@ -6104,6 +6120,7 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
{
#endif
//common to all builds
Mod_DefaultMesh(&gmdl[i], mod->name, i);
gmdl[i].ofsanimations = group;
gmdl[i].numanimations = num_animinfo;

View File

@ -3041,7 +3041,7 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
/*quake requires a few settings for compatibility*/
#define EZQUAKECOMPETITIVE "set ruleset_allow_fbmodels 1\n"
#define QRPCOMPAT "cl_cursor_scale 0.2\ncl_cursor_bias_x 7.5\ncl_cursor_bias_y 0.8"
#define QRPCOMPAT "set cl_cursor_scale 0.2\nset cl_cursor_bias_x 7.5\nset cl_cursor_bias_y 0.8"
#define QCFG "set com_parseutf8 0\nset allow_download_refpackages 0\nset sv_bigcoords \"\"\nmap_autoopenportals 1\n" "sv_port "STRINGIFY(PORT_QWSERVER)" "STRINGIFY(PORT_NQSERVER)"\n" ZFIXHACK EZQUAKECOMPETITIVE QRPCOMPAT
//nehahra has to be weird with extra cvars, and buggy fullbrights.
#define NEHCFG QCFG "set nospr32 0\nset cutscene 1\nalias startmap_sp \"map nehstart\"\nr_fb_bmodels 0\nr_fb_models 0\n"

View File

@ -320,6 +320,14 @@ void Huff_EmitByte(int ch, qbyte *buffer, int *count);
#define PROTOCOL_VERSION_BJP2 10001
#define PROTOCOL_VERSION_BJP3 10002
#define MOD_PROQUAKE 1
//#define MOD_PROQUAKE_VERSION (10*3.1) //password feature added
//#define MOD_PROQUAKE_VERSION (10*3.2) //first 'cheatfree'
#define MOD_PROQUAKE_VERSION (10*3.3) //no real changes, but w/e, this is the highest we can claim without having serverside issues.
//#define MOD_PROQUAKE_VERSION (10*3.4) //added nat wait weirdness that's redundant and breaks the whole single-port thing by using two ports on the client too. *sigh*.
//#define MOD_PROQUAKE_VERSION (10*3.5) //optional cheatfree encryption
//#define MOD_PROQUAKE_VERSION (10*4.51) //current version
/*RMQ protocol flags*/
#define RMQFL_SHORTANGLE (1 << 1)
#define RMQFL_FLOATANGLE (1 << 2)

View File

@ -1010,6 +1010,63 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
cm->texnum.specular = shader->defaulttextures->specular;
cm->texnum.reflectcube = shader->defaulttextures->reflectcube;
cm->texnum.reflectmask = shader->defaulttextures->reflectmask;
cm->texnum.paletted = shader->defaulttextures->paletted;
#ifdef HEXEN2 //too lazy to do this
if (h2playertranslations && pc)
;
else
#endif
if (r_softwarebanding)
{
qbyte *pixels8 = (void*)pixels;
qbyte *out8;
for (i=0 ; i<256 ; i++)
translate32[i] = i;
//fancy colours are not supported here. try to aproximate them.
if (tc >= 16)
tc = GetPaletteIndexNoFB((tc>>16)&0xff, (tc>>8)&0xff, (tc>>0)&0xff)/16;
if (bc >= 16)
bc = GetPaletteIndexNoFB((bc>>16)&0xff, (bc>>8)&0xff, (bc>>0)&0xff)/16;
for (i = 0; i < 16; i++)
{
if (tc < 8)
translate32[TOP_RANGE+i] = (tc<<4)+i;
else
translate32[TOP_RANGE+i] = (tc<<4)+15-i;
if (bc < 8)
translate32[BOTTOM_RANGE+i] = (bc<<4)+i;
else
translate32[BOTTOM_RANGE+i] = (bc<<4)+15-i;
}
fracstep = tinwidth*0x10000/scaled_width;
for (i=0, out8=pixels8 ; i<scaled_height ; i++, out8 += scaled_width)
{
inrow = original + inwidth*(i*inheight/scaled_height);
frac = fracstep >> 1;
for (j=0 ; j<scaled_width ; j+=4)
{
out8[j] = translate32[inrow[frac>>16]];
frac += fracstep;
out8[j+1] = translate32[inrow[frac>>16]];
frac += fracstep;
out8[j+2] = translate32[inrow[frac>>16]];
frac += fracstep;
out8[j+3] = translate32[inrow[frac>>16]];
frac += fracstep;
}
}
cm->texnum.paletted = R_LoadTexture(va("paletted$%x$%x$%i$%i$%i$%s", tc, bc, cm->skinnum, subframe, pc, cm->name),
scaled_width, scaled_height, TF_LUM8, pixels8, IF_NEAREST|IF_NOMIPMAP);
}
/*if (!h2playertranslations)
{
qboolean valid = false;
@ -1313,118 +1370,187 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
lightdir[2] = 1;
}
if (!r_vertexdlights.ival && r_dynamic.ival > 0)
{
float *org = e->origin;
if (e->flags & RF_WEAPONMODEL)
org = r_refdef.vieworg;
//don't do world lights, although that might be funny
for (i=rtlights_first; i<RTL_FIRST; i++)
{
if (cl_dlights[i].radius)
{
VectorSubtract (org,
cl_dlights[i].origin,
dist);
add = cl_dlights[i].radius - Length(dist);
#ifdef RTLIGHTS
//if world lighting is on, there may be no lightmap influence even if r_dynamic is on.
if (r_shadow_realtime_world.ival)
add *= r_shadow_realtime_world_lightmaps.value;
#endif
if (add > 0)
{
ambientlight[0] += add * cl_dlights[i].color[0];
ambientlight[1] += add * cl_dlights[i].color[1];
ambientlight[2] += add * cl_dlights[i].color[2];
//ZOID models should be affected by dlights as well
shadelight[0] += add * cl_dlights[i].color[0];
shadelight[1] += add * cl_dlights[i].color[1];
shadelight[2] += add * cl_dlights[i].color[2];
}
}
}
}
m = max(max(ambientlight[0], ambientlight[1]), ambientlight[2]);
if (m > 255)
{
ambientlight[0] *= 255.0/m;
ambientlight[1] *= 255.0/m;
ambientlight[2] *= 255.0/m;
}
m = max(max(shadelight[0], shadelight[1]), shadelight[2]);
if (m > 128)
{
shadelight[0] *= 128.0/m;
shadelight[1] *= 128.0/m;
shadelight[2] *= 128.0/m;
}
//MORE HUGE HACKS! WHEN WILL THEY CEASE!
// clamp lighting so it doesn't overbright as much
// ZOID: never allow players to go totally black
if (clmodel->engineflags & MDLF_PLAYER)
{
float fb = r_fullbrightSkins.value;
if (fb > cls.allow_fbskins)
fb = cls.allow_fbskins;
if (fb < 0)
fb = 0;
if (fb)
{
extern cvar_t r_fb_models;
if (fb >= 1 && r_fb_models.value)
{
ambientlight[0] = ambientlight[1] = ambientlight[2] = 1;
shadelight[0] = shadelight[1] = shadelight[2] = 1;
e->light_known = 2;
return e->light_known-1;
}
else
{
for (i = 0; i < 3; i++)
{
ambientlight[i] = max(ambientlight[i], 8 + fb * 120);
shadelight[i] = max(shadelight[i], 8 + fb * 120);
}
}
}
for (i = 0; i < 3; i++)
{
if (ambientlight[i] < 8)
ambientlight[i] = 8;
}
}
for (i = 0; i < 3; i++)
{
if (ambientlight[i] > 128)
ambientlight[i] = 128;
shadelight[i] /= 200.0/255;
ambientlight[i] /= 200.0/255;
}
if ((e->model->flags & MF_ROTATE) && cl.hexen2pickups)
{
shadelight[0] = shadelight[1] = shadelight[2] =
ambientlight[0] = ambientlight[1] = ambientlight[2] = 128+sin(cl.servertime*4)*64;
}
#ifdef HEXEN2
if ((e->drawflags & MLS_MASK) == MLS_ABSLIGHT)
{
shadelight[0] = shadelight[1] = shadelight[2] = e->abslight;
ambientlight[0] = ambientlight[1] = ambientlight[2] = e->abslight;
}
else
#endif
if (r_softwarebanding)
{
//mimic software rendering as closely as possible
lightdir[2] = 0; //horizontal light only.
VectorMA(vec3_origin, 0.5, shadelight, ambientlight);
VectorCopy(ambientlight, shadelight);
if (!r_vertexdlights.ival && r_dynamic.ival > 0)
{
float *org = e->origin;
if (e->flags & RF_WEAPONMODEL)
org = r_refdef.vieworg;
//don't do world lights, although that might be funny
for (i=rtlights_first; i<RTL_FIRST; i++)
{
if (cl_dlights[i].radius)
{
VectorSubtract (org,
cl_dlights[i].origin,
dist);
add = cl_dlights[i].radius - Length(dist);
#ifdef RTLIGHTS
if (r_shadow_realtime_world.ival) //if world lighting is on, there may be no lightmap influence even if r_dynamic is on.
add *= r_shadow_realtime_world_lightmaps.value;
#endif
if (add > 0)
{
if (r_dynamic.ival == 2)
{
ambientlight[0] += add * 2;
ambientlight[1] += add * 2;
ambientlight[2] += add * 2;
}
else
{
ambientlight[0] += add * cl_dlights[i].color[0];
ambientlight[1] += add * cl_dlights[i].color[1];
ambientlight[2] += add * cl_dlights[i].color[2];
}
}
}
}
}
for (i = 0; i < 3; i++)
{
if (ambientlight[i] > 128)
ambientlight[i] = 128;
if (ambientlight[i] + shadelight[i] > 192)
shadelight[i] = 192 - ambientlight[i];
}
}
else
{
if (!r_vertexdlights.ival && r_dynamic.ival > 0)
{
float *org = e->origin;
if (e->flags & RF_WEAPONMODEL)
org = r_refdef.vieworg;
//don't do world lights, although that might be funny
for (i=rtlights_first; i<RTL_FIRST; i++)
{
if (cl_dlights[i].radius)
{
VectorSubtract (org,
cl_dlights[i].origin,
dist);
add = cl_dlights[i].radius - Length(dist);
#ifdef RTLIGHTS
if (r_shadow_realtime_world.ival) //if world lighting is on, there may be no lightmap influence even if r_dynamic is on.
add *= r_shadow_realtime_world_lightmaps.value;
#endif
if (add > 0)
{
if (r_dynamic.ival == 2)
{
ambientlight[0] += add * 2;
ambientlight[1] += add * 2;
ambientlight[2] += add * 2;
//ZOID models should be affected by dlights as well
shadelight[0] += add * 2;
shadelight[1] += add * 2;
shadelight[2] += add * 2;
}
else
{
ambientlight[0] += add * cl_dlights[i].color[0];
ambientlight[1] += add * cl_dlights[i].color[1];
ambientlight[2] += add * cl_dlights[i].color[2];
//ZOID models should be affected by dlights as well
shadelight[0] += add * cl_dlights[i].color[0];
shadelight[1] += add * cl_dlights[i].color[1];
shadelight[2] += add * cl_dlights[i].color[2];
}
}
}
}
}
m = max(max(ambientlight[0], ambientlight[1]), ambientlight[2]);
if (m > 255)
{
ambientlight[0] *= 255.0/m;
ambientlight[1] *= 255.0/m;
ambientlight[2] *= 255.0/m;
}
m = max(max(shadelight[0], shadelight[1]), shadelight[2]);
if (m > 128)
{
shadelight[0] *= 128.0/m;
shadelight[1] *= 128.0/m;
shadelight[2] *= 128.0/m;
}
//MORE HUGE HACKS! WHEN WILL THEY CEASE!
// clamp lighting so it doesn't overbright as much
// ZOID: never allow players to go totally black
if (clmodel->engineflags & MDLF_PLAYER)
{
float fb = r_fullbrightSkins.value;
if (fb > cls.allow_fbskins)
fb = cls.allow_fbskins;
if (fb < 0)
fb = 0;
if (fb)
{
extern cvar_t r_fb_models;
if (fb >= 1 && r_fb_models.value)
{
ambientlight[0] = ambientlight[1] = ambientlight[2] = 1;
shadelight[0] = shadelight[1] = shadelight[2] = 1;
e->light_known = 2;
return e->light_known-1;
}
else
{
for (i = 0; i < 3; i++)
{
ambientlight[i] = max(ambientlight[i], 8 + fb * 120);
shadelight[i] = max(shadelight[i], 8 + fb * 120);
}
}
}
for (i = 0; i < 3; i++)
{
if (ambientlight[i] < 8)
ambientlight[i] = 8;
}
}
for (i = 0; i < 3; i++)
{
if (ambientlight[i] > 128)
ambientlight[i] = 128;
shadelight[i] /= 200.0/255;
ambientlight[i] /= 200.0/255;
}
if ((e->model->flags & MF_ROTATE) && cl.hexen2pickups)
{
shadelight[0] = shadelight[1] = shadelight[2] =
ambientlight[0] = ambientlight[1] = ambientlight[2] = 128+sin(cl.servertime*4)*64;
}
}
if (e->flags & RF_WEAPONMODEL)
{
vec3_t temp;
@ -1458,8 +1584,16 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
VectorScale(shadelight, scale, shadelight);
}
VectorMA(ambientlight, 0.5, shadelight, e->light_avg);
VectorSubtract(shadelight, ambientlight, e->light_range);
if (r_softwarebanding)
{ //overbright the models.
VectorScale(ambientlight, 2, e->light_avg);
VectorScale(shadelight, 2, e->light_range);
}
else
{ //calculate average and range, to allow for negative lighting dotproducts
VectorMA(ambientlight, 0.5, shadelight, e->light_avg);
VectorSubtract(shadelight, ambientlight, e->light_range);
}
e->light_known = 1;
return e->light_known-1;

View File

@ -2583,7 +2583,7 @@ static void GenerateColourMods(const shaderpass_t *pass)
shaderstate.pendingcolourpointer = NULL;
return;
}
if (r_nolightdir.ival)
if (r_nolightdir.ival || (!shaderstate.curentity->light_range[0] && !shaderstate.curentity->light_range[1] && !shaderstate.curentity->light_range[2]))
{
VectorCopy(shaderstate.curentity->light_avg, shaderstate.pendingcolourflat);
shaderstate.pendingcolourflat[3] = shaderstate.curentity->shaderRGBAf[3];

View File

@ -1860,7 +1860,7 @@ void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse,
res_dir[1] = r[4];
res_dir[2] = -r[5];
if (!res_dir[0] && !res_dir[1] && !res_dir[2])
res_dir[1] = res_dir[2] = 1;
res_dir[0] = res_dir[2] = 1;
VectorNormalize(res_dir);
}

View File

@ -2773,8 +2773,7 @@ qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int psl)
#ifdef USE_EGL
case PSL_EGL:
visinfo = &vinfodef;
if (!x11.pXMatchVisualInfo(vid_dpy, scrnum, info->bpp, TrueColor, visinfo))
// if (!x11.pXMatchVisualInfo(vid_dpy, scrnum, DefaultDepth(vid_dpy, scrnum), TrueColor, &visinfo))
if (!x11.pXMatchVisualInfo(vid_dpy, scrnum, info->bpp?info->bpp:DefaultDepth(vid_dpy, scrnum), TrueColor, visinfo))
{
Sys_Error("Couldn't choose visual for EGL\n");
}
@ -2791,8 +2790,7 @@ qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int psl)
#ifdef VKQUAKE
case PSL_VULKAN:
visinfo = &vinfodef;
if (!x11.pXMatchVisualInfo(vid_dpy, scrnum, info->bpp, TrueColor, visinfo))
// if (!x11.pXMatchVisualInfo(vid_dpy, scrnum, DefaultDepth(vid_dpy, scrnum), TrueColor, &visinfo))
if (!x11.pXMatchVisualInfo(vid_dpy, scrnum, info->bpp?info->bpp:DefaultDepth(vid_dpy, scrnum), TrueColor, visinfo))
{
Sys_Error("Couldn't choose visual for vulkan\n");
}

View File

@ -970,7 +970,6 @@ static qboolean VID_SetWindowedMode (rendererstate_t *info)
int i;
HDC hdc;
int wwidth, wheight, pleft, ptop, pwidth, pheight;
RECT rect;
modestate = MS_WINDOWED;
@ -1034,7 +1033,7 @@ static qboolean VID_SetWindowedMode (rendererstate_t *info)
WindowRect = centerrect(pleft, ptop, pwidth, pheight, wwidth, wheight);
if (!sys_parentwindow)
AdjustWindowRectEx(&rect, WindowStyle, FALSE, 0);
AdjustWindowRectEx(&WindowRect, WindowStyle, FALSE, 0);
// Create the DIB window
if (WinNT)

View File

@ -1090,6 +1090,7 @@ qboolean GL_Init(rendererstate_t *info, void *(*getglfunction) (char *name));
#endif
qbyte GetPaletteIndex(int red, int green, int blue);
qbyte GetPaletteIndexNoFB(int red, int green, int blue);
int Mod_ReadFlagsFromMD1(char *name, int md3version);
/*

View File

@ -2829,7 +2829,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"float d = dot(n,e_light_dir);\n"
"if (d < 0.0) //vertex shader. this might get ugly, but I don't really want to make it per vertex.\n"
"d = 0.0; //this avoids the dark side going below the ambient level.\n"
"light = e_light_ambient + (dot(n,e_light_dir)*e_light_mul);\n"
"light = e_light_ambient + (d*e_light_mul);\n"
//FIXME: Software rendering imitation should possibly push out normals by half a pixel or something to approximate software's over-estimation of distant model sizes (small models are drawn using JUST their verticies using the nearest pixel, which results in larger meshes)
"#ifdef TESS\n"
"normal = n;\n"
@ -2993,7 +2995,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//FIXME: with this extra flag, half the permutations are redundant.
"lightlev *= 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_paletted, tc).r; //the palette index. hopefully not interpolated.\n"
"lightlev -= 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"
// lightlev -= 1.0 / 128.0; //software rendering appears to round down, so make sure we favour the lower values instead of rounding to the nearest
"col.r = texture2D(s_colourmap, vec2(pal, 1.0-lightlev.r)).r; //do 3 lookups. this is to cope with lit files, would be a waste to not support those.\n"
"col.g = texture2D(s_colourmap, vec2(pal, 1.0-lightlev.g)).g; //its not very softwarey, but re-palettizing is ugly.\n"
"col.b = texture2D(s_colourmap, vec2(pal, 1.0-lightlev.b)).b; //without lits, it should be identical.\n"
@ -10684,7 +10686,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#include \"sys/fog.h\"\n"
//FIXME: too lazy to implement this right now.
//FIXME: too lazy to implement this right now. rtlights on d3d9 are just bad right now.
"#undef RTLIGHT\n"
"#undef PCF\n"
"#undef CUBE\n"

View File

@ -1853,8 +1853,8 @@ void SV_AcceptMessage(client_t *newcl)
MSG_WriteLong(&sb, ShortSwap(localaddr.port));
if (newcl->proquake_angles_hack)
{
MSG_WriteByte(&sb, 1/*MOD_PROQUAKE*/);
MSG_WriteByte(&sb, 10 * 3.50/*MOD_PROQUAKE_VERSION*/);
MSG_WriteByte(&sb, MOD_PROQUAKE);
MSG_WriteByte(&sb, MOD_PROQUAKE_VERSION);
MSG_WriteByte(&sb, 0/*flags*/);
}
*(int*)sb.data = BigLong(NETFLAG_CTL|sb.cursize);
@ -3861,7 +3861,7 @@ qboolean SVNQ_ConnectionlessPacket(void)
MSG_WriteLong(&sb, BigLong(1)); //sequence 1, because 0 matches the old sequence, and thus might get dropped. hopefully the client will cope with dupes properly and ignore any regular (but unreliable) stuff.
MSG_WriteByte(&sb, svc_stufftext);
MSG_WriteString(&sb, va("cmd challengeconnect %i %i\n", SV_NewChallenge(), 1/*MOD_PROQUAKE*/));
MSG_WriteString(&sb, va("cmd challengeconnect %i %i\n", SV_NewChallenge(), MOD_PROQUAKE));
*(int*)sb.data = BigLong(NETFLAG_UNRELIABLE|sb.cursize);
NET_SendPacket(NS_SERVER, sb.cursize, sb.data, &net_from);
@ -3949,8 +3949,8 @@ qboolean SVNQ_ConnectionlessPacket(void)
MSG_WriteByte(&sb, CCREP_ACCEPT);
NET_LocalAddressForRemote(svs.sockets, &net_from, &localaddr, 0);
MSG_WriteLong(&sb, ShortSwap(localaddr.port));
MSG_WriteByte(&sb, 1/*MOD_PROQUAKE*/);
MSG_WriteByte(&sb, 10 * 3.50/*MOD_PROQUAKE_VERSION*/);
MSG_WriteByte(&sb, MOD_PROQUAKE);
MSG_WriteByte(&sb, MOD_PROQUAKE_VERSION);
*(int*)sb.data = BigLong(NETFLAG_CTL|sb.cursize);
NET_SendPacket(NS_SERVER, sb.cursize, sb.data, &net_from);

View File

@ -8776,7 +8776,7 @@ void SV_ClientThink (void)
//
// if dead, behave differently
//
if (sv_player->v->health <= 0)
if (sv_player->v->health <= 0 && !host_client->spectator)
return;
//