From a6ac015c5b5e8692c9d243bc1af705a7a2ec0813 Mon Sep 17 00:00:00 2001 From: Spoike Date: Wed, 3 Jan 2018 04:40:06 +0000 Subject: [PATCH] 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 --- engine/client/cl_ents.c | 8 +- engine/client/cl_parse.c | 11 +- engine/client/client.h | 2 +- engine/client/image.c | 2 +- engine/client/in_generic.c | 4 +- engine/client/keys.c | 8 +- engine/client/p_classic.c | 2 +- engine/client/p_script.c | 10 +- engine/client/pr_csqc.c | 8 +- engine/client/pr_menu.c | 2 +- engine/client/r_2d.c | 26 +++ engine/client/r_surf.c | 2 +- engine/client/view.c | 8 +- engine/common/bothdefs.h | 3 +- engine/common/com_mesh.c | 35 +++- engine/common/fs.c | 2 +- engine/common/net.h | 8 + engine/gl/gl_alias.c | 346 +++++++++++++++++++++++++------------ engine/gl/gl_backend.c | 2 +- engine/gl/gl_rlight.c | 2 +- engine/gl/gl_vidlinuxglx.c | 6 +- engine/gl/gl_vidnt.c | 3 +- engine/gl/glquake.h | 1 + engine/gl/r_bishaders.h | 8 +- engine/server/sv_main.c | 10 +- engine/server/sv_user.c | 2 +- 26 files changed, 363 insertions(+), 158 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 4c51a28dd..d40ccca43 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -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) diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 00e2a1d34..1c6f5c34d 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -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; diff --git a/engine/client/client.h b/engine/client/client.h index dc8ec31a0..854c67027 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -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); diff --git a/engine/client/image.c b/engine/client/image.c index 9b8381b0f..713ed0afa 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -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); diff --git a/engine/client/in_generic.c b/engine/client/in_generic.c index 16e298c59..e6df62a57 100644 --- a/engine/client/in_generic.c +++ b/engine/client/in_generic.c @@ -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] = { diff --git a/engine/client/keys.c b/engine/client/keys.c index 216c67b03..bf8ba1363 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -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: diff --git a/engine/client/p_classic.c b/engine/client/p_classic.c index 245fa05af..f85a92c83 100644 --- a/engine/client/p_classic.c +++ b/engine/client/p_classic.c @@ -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]); diff --git a/engine/client/p_script.c b/engine/client/p_script.c index c83e401bf..ad2432b43 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -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); } diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index f60a760b2..7b9789069 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -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) { diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 380ad5b59..3a2c30380 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -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); diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index fc88c4590..b389da864 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -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) { diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 587f5de86..3bf52c8e5 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -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; diff --git a/engine/client/view.c b/engine/client/view.c index c2d2e1093..4fb4735ec 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -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); diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index b5b814d71..2fceaa94a 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -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 diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 941252925..1f7330741 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -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; diff --git a/engine/common/fs.c b/engine/common/fs.c index f69beb632..3db6d63eb 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -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" diff --git a/engine/common/net.h b/engine/common/net.h index 437bbdd5b..aac743dee 100644 --- a/engine/common/net.h +++ b/engine/common/net.h @@ -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) diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 2bc29dc01..2ab8b6aa1 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -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> 1; + for (j=0 ; j>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 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 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 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; diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 89073d8ae..7c1b14be0 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -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]; diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index b9732d923..d0909930d 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -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); } diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index b70ee1621..e1b4509f1 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -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"); } diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index 8eceac857..81648a48b 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -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) diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 08b735b26..4d48c8434 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -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); /* diff --git a/engine/gl/r_bishaders.h b/engine/gl/r_bishaders.h index 574bbe578..27caa44a0 100644 --- a/engine/gl/r_bishaders.h +++ b/engine/gl/r_bishaders.h @@ -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" diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 98401366e..e42cb3770 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -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); diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 2f2897d94..b6ee6f446 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -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; //