diff --git a/engine/client/cl_cg.c b/engine/client/cl_cg.c index a2c407908..0a76763b1 100644 --- a/engine/client/cl_cg.c +++ b/engine/client/cl_cg.c @@ -756,7 +756,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con mins = vec3_origin; if (!maxs) maxs = vec3_origin; - mod->funcs.NativeTrace(mod, 0, 0, NULL, start, end, mins, maxs, fn==CG_CM_CAPSULETRACE, brushmask, &tr); + mod->funcs.NativeTrace(mod, 0, NULLFRAMESTATE, NULL, start, end, mins, maxs, fn==CG_CM_CAPSULETRACE, brushmask, &tr); results->allsolid = tr.allsolid; results->contents = tr.contents; results->fraction = tr.fraction; diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index bd9db0b29..823e0083d 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -4521,21 +4521,21 @@ CL_ParseStartSoundPacket */ void CLQW_ParseStartSoundPacket(void) { - vec3_t pos; - int channel, ent; - int sound_num; - int volume; - float attenuation; - int i; + vec3_t pos; + int channel, ent; + int sound_num; + int volume; + float attenuation; + int i; - channel = MSG_ReadShort(); + channel = MSG_ReadShort(); - if (channel & QWSND_VOLUME) + if (channel & QWSND_VOLUME) volume = MSG_ReadByte (); else volume = DEFAULT_SOUND_PACKET_VOLUME; - if (channel & QWSND_ATTENUATION) + if (channel & QWSND_ATTENUATION) attenuation = MSG_ReadByte () / 64.0; else attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; @@ -4552,7 +4552,7 @@ void CLQW_ParseStartSoundPacket(void) Host_EndGame ("CL_ParseStartSoundPacket: ent = %i", ent); #ifdef PEXT_CSQC - if (!CSQC_StartSound(ent, channel, cl.sound_name[sound_num], pos, volume/255.0, attenuation, 100, 0, 0)) + if (!CSQC_StartSound(ent, channel, cl.sound_name[sound_num], pos, volume/255.0, attenuation, 1, 0, 0)) #endif { if (!sound_num) @@ -4677,7 +4677,7 @@ void CLNQ_ParseStartSoundPacket(void) int field_mask; float attenuation; int i; - int pitchadj; + float pitchadj; float timeofs; unsigned int flags; @@ -4697,9 +4697,9 @@ void CLNQ_ParseStartSoundPacket(void) attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; if (field_mask & FTESND_PITCHADJ) - pitchadj = MSG_ReadByte(); + pitchadj = MSG_ReadByte()/100.0; else - pitchadj = 100; + pitchadj = 1; if (field_mask & FTESND_TIMEOFS) timeofs = MSG_ReadShort() / 1000.0; @@ -4715,6 +4715,9 @@ void CLNQ_ParseStartSoundPacket(void) else VectorClear(vel); + if (field_mask & DPSND_SPEEDUSHORT4000) + pitchadj = (unsigned short)MSG_ReadShort() / 4000.0; + flags = field_mask>>8; flags &= CF_FORCELOOP | CF_NOREVERB | CF_FOLLOW; @@ -7850,6 +7853,12 @@ void CLNQ_ParseServerMessage (void) CL_SetStatNumeric (destsplit, i, f, f); } break; + case svcfte_setangledelta: + for (i=0 ; i<3 ; i++) + cl.playerview[destsplit].viewangles[i] += MSG_ReadAngle16 (); + VectorCopy (cl.playerview[destsplit].viewangles, cl.playerview[destsplit].simangles); + VectorCopy (cl.playerview[destsplit].viewangles, cl.playerview[destsplit].intermissionangles); + break; case svc_setangle: { inframe_t *inf = &cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK]; diff --git a/engine/client/cl_pred.c b/engine/client/cl_pred.c index 13be3d652..7526087a7 100644 --- a/engine/client/cl_pred.c +++ b/engine/client/cl_pred.c @@ -170,7 +170,7 @@ q2trace_t VARGS CLQ2_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end trace_t t; // check against world - cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, start, end, mins, maxs, false, MASK_PLAYERSOLID, &t); + cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, NULLFRAMESTATE, NULL, start, end, mins, maxs, false, MASK_PLAYERSOLID, &t); if (t.fraction < 1.0) t.ent = (struct edict_s *)1; diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 10ec00695..ef4cf3932 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1317,7 +1317,7 @@ void SCR_CrosshairPosition(playerview_t *pview, float *x, float *y) memset(&tr, 0, sizeof(tr)); tr.fraction = 1; - cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, start, end, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &tr); + cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, NULLFRAMESTATE, NULL, start, end, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &tr); start[2]-=16; if (tr.fraction != 1) { diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 4122153ab..cd53452de 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -1075,8 +1075,11 @@ void CL_ParseTEnt (void) case TENQ_BEAM: type = TEQW_BEAM; break; + case TENQ_EXPLOSION_SPRITE: + type = TE_EXPLOSION; + break; case TE_EXPLOSION: - type = TEQW_EXPLOSIONNOSPRITE; + type = TEQW_EXPLOSION_NOSPRITE; break; case TE_GUNSHOT: type = TE_GUNSHOT_NQCOMPAT; @@ -1337,7 +1340,7 @@ void CL_ParseTEnt (void) ex->endalpha = ex->startalpha; //don't fade out } break; - case TEQW_EXPLOSIONNOSPRITE: //nq-style, no sprite + case TEQW_EXPLOSION_NOSPRITE: //nq-style, no sprite case TE_EXPLOSION: //qw-style, with (optional) sprite // particles pos[0] = MSG_ReadCoord (); diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index f6b1b4b22..d55a51b10 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -2315,7 +2315,7 @@ void CLQ2_AddEntities (void) AngleVectors(r_refdef.viewangles, axis[0], axis[1], axis[2]); VectorMA(r_refdef.vieworg, -chase_back.value, axis[0], camorg); VectorMA(camorg, -chase_up.value, pv->gravitydir, camorg); -// if (cl.worldmodel && cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, r_refdef.vieworg, camorg, vec3_origin, vec3_origin, true, MASK_WORLDSOLID, &tr)) +// if (cl.worldmodel && cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, NULLFRAMESTATE, NULL, r_refdef.vieworg, camorg, vec3_origin, vec3_origin, true, MASK_WORLDSOLID, &tr)) VectorCopy(camorg, r_refdef.vieworg); V_EditExternalModels(0, NULL, 0); diff --git a/engine/client/image.c b/engine/client/image.c index 61ae7f1d6..85100a8c5 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -2481,7 +2481,7 @@ static qboolean Image_ReadDDSFile(texid_t tex, unsigned int flags, char *fname, int encoding; ddsheader fmtheader; - if (*(int*)filedata != *(int*)"DDS ") + if (*(int*)filedata != (('D'<<0)|('D'<<8)|('S'<<16)|(' '<<24))) return false; memcpy(&fmtheader, filedata+4, sizeof(fmtheader)); @@ -2492,14 +2492,14 @@ static qboolean Image_ReadDDSFile(texid_t tex, unsigned int flags, char *fname, if (nummips < 1) nummips = 1; - if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT1") + if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('D'<<0)|('X'<<8)|('T'<<16)|('1'<<24))) { encoding = PTI_S3RGBA1; //alpha or not? Assume yes, and let the drivers decide. pad = 8; divsize = 4; blocksize = 8; } - else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT2") //dx3 with premultiplied alpha + else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('D'<<0)|('X'<<8)|('T'<<16)|('2'<<24))) //dx3 with premultiplied alpha { // if (!(tex->flags & IF_PREMULTIPLYALPHA)) return false; @@ -2508,7 +2508,7 @@ static qboolean Image_ReadDDSFile(texid_t tex, unsigned int flags, char *fname, divsize = 4; blocksize = 16; } - else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT3") + else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('D'<<0)|('X'<<8)|('T'<<16)|('3'<<24))) { if (tex->flags & IF_PREMULTIPLYALPHA) return false; @@ -2517,7 +2517,7 @@ static qboolean Image_ReadDDSFile(texid_t tex, unsigned int flags, char *fname, divsize = 4; blocksize = 16; } - else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT4") //dx5 with premultiplied alpha + else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('D'<<0)|('X'<<8)|('T'<<16)|('4'<<24))) //dx5 with premultiplied alpha { // if (!(tex->flags & IF_PREMULTIPLYALPHA)) return false; @@ -2526,7 +2526,7 @@ static qboolean Image_ReadDDSFile(texid_t tex, unsigned int flags, char *fname, divsize = 4; blocksize = 16; } - else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT5") + else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('D'<<0)|('X'<<8)|('T'<<16)|('5'<<24))) { if (tex->flags & IF_PREMULTIPLYALPHA) return false; @@ -4646,10 +4646,9 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t char fname[MAX_QPATH]; char *altname; char *nextalt; - qboolean exactext = !!(tex->flags & IF_EXACTEXTENSION); flocation_t loc; - unsigned int locflags; + unsigned int locflags = 0; vfsfile_t *f; size_t fsize; @@ -4720,7 +4719,7 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t //guess not, fall back to normalmaps } - if (Image_LoadTextureFromMemory(tex, tex->flags, tex->ident, loc.rawname, buf, fsize)) + if (Image_LoadTextureFromMemory(tex, tex->flags, tex->ident, fname, buf, fsize)) { BZ_Free(tex->fallbackdata); tex->fallbackdata = NULL; diff --git a/engine/client/merged.h b/engine/client/merged.h index ef3ddd335..a4b7b8dc9 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -69,6 +69,7 @@ typedef struct { float bonecontrols[MAX_BONE_CONTROLLERS]; //hl special bone controllers #endif } framestate_t; +#define NULLFRAMESTATE (framestate_t*)NULL diff --git a/engine/client/p_script.c b/engine/client/p_script.c index 090272817..24d7c32b3 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -1623,7 +1623,7 @@ parsefluid: ptype->sounds[ptype->numsounds].vol = 1; ptype->sounds[ptype->numsounds].atten = 1; - ptype->sounds[ptype->numsounds].pitch = 100; + ptype->sounds[ptype->numsounds].pitch = 1; ptype->sounds[ptype->numsounds].delay = 0; ptype->sounds[ptype->numsounds].weight = 0; @@ -1650,7 +1650,7 @@ parsefluid: ptype->sounds[ptype->numsounds].atten = atof(e); } else if (!Q_strncasecmp(e, "pitch=", 6)) - ptype->sounds[ptype->numsounds].pitch = atof(strchr(e, '=')+1); + ptype->sounds[ptype->numsounds].pitch = atof(strchr(e, '=')+1)*0.01; else if (!Q_strncasecmp(e, "delay=", 6)) ptype->sounds[ptype->numsounds].delay = atof(strchr(e, '=')+1); else if (!Q_strncasecmp(e, "weight=", 7)) @@ -1667,9 +1667,9 @@ parsefluid: ptype->sounds[ptype->numsounds].atten = atof(Cmd_Argv(3)); if (!ptype->sounds[ptype->numsounds].atten) ptype->sounds[ptype->numsounds].atten = 1; - ptype->sounds[ptype->numsounds].pitch = atof(Cmd_Argv(4)); + ptype->sounds[ptype->numsounds].pitch = atof(Cmd_Argv(4))*0.01; if (!ptype->sounds[ptype->numsounds].pitch) - ptype->sounds[ptype->numsounds].pitch = 100; + ptype->sounds[ptype->numsounds].pitch = 1; ptype->sounds[ptype->numsounds].delay = atof(Cmd_Argv(5)); if (!ptype->sounds[ptype->numsounds].delay) ptype->sounds[ptype->numsounds].delay = 0; diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 98d3c2d63..6b5ad332f 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -3610,7 +3610,7 @@ void QCBUILTIN PF_soundupdate (pubprogfuncs_t *prinst, struct globalvars_s *pr_g const char *sample = PR_GetStringOfs(prinst, OFS_PARM2); float volume = G_FLOAT(OFS_PARM3); float attenuation = G_FLOAT(OFS_PARM4); - float pitchpct = (prinst->callargc >= 6)?G_FLOAT(OFS_PARM5):0; + float pitchpct = (prinst->callargc >= 6)?G_FLOAT(OFS_PARM5)*0.01:0; unsigned int flags = (prinst->callargc>=7)?G_FLOAT(OFS_PARM6):0; float startoffset = (prinst->callargc>=8)?G_FLOAT(OFS_PARM7):0; @@ -3659,7 +3659,7 @@ static void QCBUILTIN PF_cs_sound(pubprogfuncs_t *prinst, struct globalvars_s *p sample = PR_GetStringOfs(prinst, OFS_PARM2); volume = G_FLOAT(OFS_PARM3); attenuation = G_FLOAT(OFS_PARM4); - pitchpct = (prinst->callargc>=6)?G_FLOAT(OFS_PARM5):0; + pitchpct = (prinst->callargc>=6)?G_FLOAT(OFS_PARM5)*0.01:0; flags = (prinst->callargc>=7)?G_FLOAT(OFS_PARM6):0; startoffset = (prinst->callargc>=8)?G_FLOAT(OFS_PARM7):0; @@ -3691,7 +3691,7 @@ static void QCBUILTIN PF_cs_pointsound(pubprogfuncs_t *prinst, struct globalvars volume = G_FLOAT(OFS_PARM2); attenuation = G_FLOAT(OFS_PARM3); if (prinst->callargc >= 5) - pitchpct = G_FLOAT(OFS_PARM4); + pitchpct = G_FLOAT(OFS_PARM4)*0.01; else pitchpct = 0; @@ -7883,7 +7883,7 @@ int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float G_FLOAT(OFS_PARM3) = vol; G_FLOAT(OFS_PARM4) = attenuation; VectorCopy(pos, G_VECTOR(OFS_PARM5)); - G_FLOAT(OFS_PARM6) = pitchmod; + G_FLOAT(OFS_PARM6) = pitchmod*100; G_FLOAT(OFS_PARM7) = flags; // G_FLOAT(OFS_PARM8) = timeofs; diff --git a/engine/client/r_part.c b/engine/client/r_part.c index e6b285062..8aab13b51 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -911,10 +911,10 @@ float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int { AngleVectors(pe->angles, axis[0], axis[1], axis[2]); VectorNegate(axis[1], axis[1]); - pe->model->funcs.NativeTrace(pe->model, 0, 0, axis, ts, te, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &trace); + pe->model->funcs.NativeTrace(pe->model, 0, PE_FRAMESTATE, axis, ts, te, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &trace); } else - pe->model->funcs.NativeTrace(pe->model, 0, 0, NULL, ts, te, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &trace); + pe->model->funcs.NativeTrace(pe->model, 0, PE_FRAMESTATE, NULL, ts, te, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &trace); if (trace.fraction<1) { if (bestfrac > trace.fraction) diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 445c4d882..a43e4ee08 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -93,6 +93,7 @@ cvar_t r_bouncysparks = CVARFD ("r_bouncysparks", "1", CVAR_ARCHIVE, "Enables particle interaction with world surfaces, allowing for bouncy particles, stains, and decals."); cvar_t r_drawentities = CVAR ("r_drawentities", "1"); +cvar_t r_max_gpu_bones = CVARD ("r_max_gpu_bones", "", "Specifies the maximum number of bones that can be handled on the GPU. If empty, will guess."); cvar_t r_drawflat = CVARAF ("r_drawflat", "0", "gl_textureless", CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM); cvar_t r_lightmap = CVARF ("r_lightmap", "0", @@ -877,6 +878,7 @@ void Renderer_Init(void) Cvar_Register (&gl_texturemode2d, GLRENDEREROPTIONS); Cvar_Register (&gl_mipcap, GLRENDEREROPTIONS); Cvar_Register (&gl_texture_anisotropic_filtering, GLRENDEREROPTIONS); + Cvar_Register (&r_max_gpu_bones, GRAPHICALNICETIES); Cvar_Register (&r_drawflat, GRAPHICALNICETIES); Cvar_Register (&r_lightmap, GRAPHICALNICETIES); Cvar_Register (&r_menutint, GRAPHICALNICETIES); diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index b235e6bde..1396d1876 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -2553,7 +2553,7 @@ static void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch) // ======================================================================= // Start a sound effect // ======================================================================= -static void S_UpdateSoundCard(soundcardinfo_t *sc, qboolean updateonly, channel_t *target_chan, int entnum, int entchannel, sfx_t *sfx, vec3_t origin, vec3_t velocity, float fvol, float attenuation, float timeoffset, float pitchadj, unsigned int flags) +static void S_UpdateSoundCard(soundcardinfo_t *sc, qboolean updateonly, channel_t *target_chan, int entnum, int entchannel, sfx_t *sfx, vec3_t origin, vec3_t velocity, float fvol, float attenuation, float timeoffset, float ratemul, unsigned int flags) { channel_t *check; int vol; @@ -2572,10 +2572,10 @@ static void S_UpdateSoundCard(soundcardinfo_t *sc, qboolean updateonly, channel_ if (!sfx) sfx = target_chan->sfx; - if (pitchadj <= 0) - pitchadj = 100; + if (ratemul <= 0) + ratemul = 1; - pitchadj *= snd_playbackrate.value * (cls.state?cl.gamespeed:1) * (cls.demoplayback?cl_demospeed.value:1); + ratemul *= snd_playbackrate.value * (cls.state?cl.gamespeed:1) * (cls.demoplayback?cl_demospeed.value:1); vol = fvol*255; @@ -2632,7 +2632,7 @@ static void S_UpdateSoundCard(soundcardinfo_t *sc, qboolean updateonly, channel_ absstartpos = 0; } - target_chan->rate = ((1<rate = ((1<rate/sc->sn.speed; if (target_chan->rate < 1) /*make sure the rate won't crash us*/ target_chan->rate = 1; target_chan->pos = absstartpos + (int)(timeoffset*sc->sn.speed*target_chan->rate); diff --git a/engine/common/bspfile.h b/engine/common/bspfile.h index 512701a81..04b7db73b 100644 --- a/engine/common/bspfile.h +++ b/engine/common/bspfile.h @@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAX_MAP_HULLSDQ1 4 #define MAX_MAP_HULLSDH2 8 -#define MAX_MAP_HULLSM 16 +#define MAX_MAP_HULLSM 8 //#define MAX_MAP_MODELS 256 //#define MAX_MAP_BRUSHES 0x8000 diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 7be78b2ea..5eb150318 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -1578,7 +1578,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in usebones = false; else if (inf->ofs_skel_xyz && !inf->ofs_skel_weight) usebones = false; - else if (e->fatness || !inf->ofs_skel_idx || inf->numbones > MAX_GPU_BONES) + else if (e->fatness || !inf->ofs_skel_idx || inf->numbones > sh_config.max_gpu_bones) #endif usebones = false; @@ -2270,7 +2270,7 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, framestate_t *framestate, v #ifdef SKELETALMODELS if (mod->numbones) { - if (!mod->ofs_skel_idx) + if (!mod->ofs_skel_idx || !framestate) posedata = mod->ofs_skel_xyz; //if there's no weights, don't try animating anything. else if (mod->shares_verts != cursurfnum || !posedata) { @@ -2292,12 +2292,14 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, framestate_t *framestate, v else { group = mod->ofsanimations; - group += framestate->g[FS_REG].frame[0] % mod->numanimations; + if (framestate) + group += framestate->g[FS_REG].frame[0] % mod->numanimations; //FIXME: no support for frame blending. if (!group->numposes) continue; pose = group->poseofs; - pose += (int)(framestate->g[FS_REG].frametime[0] * group->rate)%group->numposes; + if (framestate) + pose += (int)(framestate->g[FS_REG].frametime[0] * group->rate)%group->numposes; posedata = pose->ofsverts; } diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index a41278467..c88522c19 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -216,7 +216,7 @@ unsigned int Net_PextMask(int maskset, qboolean fornq) if (fornq) { //only ones that are tested - mask &= PEXT2_VOICECHAT | PEXT2_REPLACEMENTDELTAS | PEXT2_NEWSIZEENCODING | PEXT2_PREDINFO; + mask &= /*PEXT2_PRYDONCURSOR |*/ PEXT2_VOICECHAT | PEXT2_SETANGLEDELTA | PEXT2_REPLACEMENTDELTAS | PEXT2_MAXPLAYERS | PEXT2_PREDINFO | PEXT2_NEWSIZEENCODING; } // else // mask &= ~PEXT2_PREDINFO; diff --git a/engine/common/pmove.c b/engine/common/pmove.c index eedd64f58..0d7272130 100644 --- a/engine/common/pmove.c +++ b/engine/common/pmove.c @@ -975,7 +975,7 @@ void PM_CategorizePosition (void) VectorMA (pmove.origin, 24, flatforward, fwd1); - pmove.physents[0].model->funcs.NativeTrace(pmove.physents[0].model, 0, 0, NULL, pmove.origin, fwd1, pmove.player_mins, pmove.player_maxs, pmove.capsule, MASK_PLAYERSOLID, &t); + pmove.physents[0].model->funcs.NativeTrace(pmove.physents[0].model, 0, PE_FRAMESTATE, NULL, pmove.origin, fwd1, pmove.player_mins, pmove.player_maxs, pmove.capsule, MASK_PLAYERSOLID, &t); if (t.surface && t.surface->flags & Q3SURF_LADDER) { pmove.onladder = true; diff --git a/engine/common/pmove.h b/engine/common/pmove.h index 63c9ca501..977339776 100644 --- a/engine/common/pmove.h +++ b/engine/common/pmove.h @@ -48,6 +48,8 @@ typedef struct qbyte notouch; //don't trigger touch events. FIXME: why are these entities even in the list? qbyte isportal; //special portal traversion required unsigned int forcecontentsmask; +// framestate_t framestate; +#define PE_FRAMESTATE NULLFRAMESTATE //remove this once we start wanting players to interact with ents in different frames. } physent_t; typedef struct diff --git a/engine/common/pmovetst.c b/engine/common/pmovetst.c index f53709dbb..5ea04c852 100644 --- a/engine/common/pmovetst.c +++ b/engine/common/pmovetst.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "quakedef.h" -static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace, vec3_t origin, vec3_t angles); +static qboolean PM_TransformedHullCheck (model_t *model, framestate_t *framestate, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace, vec3_t origin, vec3_t angles); int Q1BSP_HullPointContents(hull_t *hull, vec3_t p); static hull_t box_hull; static mclipnode_t box_clipnodes[6]; @@ -182,7 +182,7 @@ int PM_ExtraBoxContents (vec3_t p) { if (pe->forcecontentsmask) { - if (!PM_TransformedHullCheck(pm, p, p, pmove.player_mins, pmove.player_maxs, &tr, pe->origin, pe->angles)) + if (!PM_TransformedHullCheck(pm, PE_FRAMESTATE, p, p, pmove.player_mins, pmove.player_maxs, &tr, pe->origin, pe->angles)) continue; if (tr.startsolid || tr.inwater) pc |= pe->forcecontentsmask; @@ -209,7 +209,7 @@ LINE TESTING IN HULLS */ /*returns if it actually did a trace*/ -static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, vec3_t player_mins, vec3_t player_maxs, trace_t *trace, vec3_t origin, vec3_t angles) +static qboolean PM_TransformedHullCheck (model_t *model, framestate_t *framestate, vec3_t start, vec3_t end, vec3_t player_mins, vec3_t player_maxs, trace_t *trace, vec3_t origin, vec3_t angles) { vec3_t start_l, end_l; int i; @@ -226,7 +226,7 @@ static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t en { AngleVectors (angles, axis[0], axis[1], axis[2]); VectorNegate(axis[1], axis[1]); - model->funcs.NativeTrace(model, 0, 0, axis, start_l, end_l, player_mins, player_maxs, pmove.capsule, MASK_PLAYERSOLID, trace); + model->funcs.NativeTrace(model, 0, framestate, axis, start_l, end_l, player_mins, player_maxs, pmove.capsule, MASK_PLAYERSOLID, trace); } else { @@ -237,7 +237,7 @@ static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t en if (start_l[i]+player_maxs[i] < model->mins[i] && end_l[i] + player_maxs[i] < model->mins[i]) return false; } - model->funcs.NativeTrace(model, 0, 0, NULL, start_l, end_l, player_mins, player_maxs, pmove.capsule, MASK_PLAYERSOLID, trace); + model->funcs.NativeTrace(model, 0, framestate, NULL, start_l, end_l, player_mins, player_maxs, pmove.capsule, MASK_PLAYERSOLID, trace); } } else @@ -388,7 +388,7 @@ qboolean PM_TestPlayerPosition (vec3_t pos, qboolean ignoreportals) //if the trace ended up inside a portal region, then its not valid. if (pe->model) { - if (!PM_TransformedHullCheck (pe->model, pos, pos, vec3_origin, vec3_origin, &trace, pe->origin, pe->angles)) + if (!PM_TransformedHullCheck (pe->model, PE_FRAMESTATE, pos, pos, vec3_origin, vec3_origin, &trace, pe->origin, pe->angles)) continue; if (trace.allsolid) return false; @@ -405,7 +405,7 @@ qboolean PM_TestPlayerPosition (vec3_t pos, qboolean ignoreportals) { if (pe->model) { - if (!PM_TransformedHullCheck (pe->model, pos, pos, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles)) + if (!PM_TransformedHullCheck (pe->model, PE_FRAMESTATE, pos, pos, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles)) continue; if (trace.allsolid) { @@ -480,7 +480,7 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end, unsigned int solidmask) PM_HullForBox (mins, maxs); // trace a line through the apropriate clipping hull - if (!PM_TransformedHullCheck (NULL, start, end, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles)) + if (!PM_TransformedHullCheck (NULL, NULL, start, end, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles)) continue; } else if (pe->isportal) @@ -489,13 +489,13 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end, unsigned int solidmask) PM_PortalCSG(pe, i, pmove.player_mins, pmove.player_maxs, start, end, &total); // trace a line through the apropriate clipping hull - if (!PM_TransformedHullCheck (pe->model, start, end, vec3_origin, vec3_origin, &trace, pe->origin, pe->angles)) + if (!PM_TransformedHullCheck (pe->model, PE_FRAMESTATE, start, end, vec3_origin, vec3_origin, &trace, pe->origin, pe->angles)) continue; } else { // trace a line through the apropriate clipping hull - if (!PM_TransformedHullCheck (pe->model, start, end, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles)) + if (!PM_TransformedHullCheck (pe->model, PE_FRAMESTATE, start, end, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles)) continue; if (trace.allsolid) diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 308bbfb56..f5f97c2aa 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -866,7 +866,7 @@ enum { #define FTESND_MOREFLAGS (1<<2) // actually, chan flags #define NQSND_LARGEENTITY (1<<3) //both dp+fitz #define NQSND_LARGESOUND (1<<4) //both dp+fitz -//#define DPSND_SPEEDUSHORT4000 (1<<5) // ushort speed*4000 (speed is usually 1.0, a value of 0.0 is the same as 1.0) +#define DPSND_SPEEDUSHORT4000 (1<<5) // ushort speed*4000 (speed is usually 1.0, a value of 0.0 is the same as 1.0) #define FTESND_TIMEOFS (1<<6) //signed short, in milliseconds. #define FTESND_PITCHADJ (1<<7) //a byte (speed percent (0=100%)) //more flags are weird. @@ -923,7 +923,8 @@ enum { TEQW_BEAM = 18, //use the builtin, luke. TENEH_SMOKE = 18, //gah [vector] origin [byte] palette TEQW_EXPLOSION2 = 19, //use the builtin, luke. - TEQW_EXPLOSIONNOSPRITE = 20, + TEQW_EXPLOSION_NOSPRITE = 20, //nq-style explosion over qw + TENQ_EXPLOSION_SPRITE = 20, //qw-style explosion over nq TE_GUNSHOT_NQCOMPAT = 21, //nq has count byte, qw does not // hexen 2 diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 544fc3536..d7d5d3946 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -2123,7 +2123,7 @@ void Q1BSPX_Setup(model_t *mod, char *filebase, unsigned int filelen, lump_t *lu i = LittleLong(h->numlumps); /*verify the header*/ - if (*(int*)h->id != *(int*)"BSPX" || + if (*(int*)h->id != (('B'<<0)|('S'<<8)|('P'<<16)|('X'<<24)) || i < 0 || offs + sizeof(*h) + sizeof(h->lumps[0])*(i-1) > filelen) return; diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 971a7fc18..e055e5345 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -3137,12 +3137,10 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm, break; case SP_M_ENTBONES: { -#ifdef GLESONLY - //cop out. - qglUniform4fvARB(ph, shaderstate.sourcevbo->numbones*3, shaderstate.sourcevbo->bones); -#else - qglUniformMatrix3x4fv(ph, shaderstate.sourcevbo->numbones, false, shaderstate.sourcevbo->bones); -#endif + if (sh_config.maxver>=120) + qglUniformMatrix3x4fv(ph, shaderstate.sourcevbo->numbones, false, shaderstate.sourcevbo->bones); + else + qglUniform4fvARB(ph, shaderstate.sourcevbo->numbones*3, shaderstate.sourcevbo->bones); } break; case SP_M_INVVIEWPROJECTION: diff --git a/engine/gl/gl_hlmdl.c b/engine/gl/gl_hlmdl.c index 7e1865e18..1f0ced046 100644 --- a/engine/gl/gl_hlmdl.c +++ b/engine/gl/gl_hlmdl.c @@ -570,7 +570,7 @@ void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, fl } if (!model->animcache[sequence->seqindex]) model->animcache[sequence->seqindex] = FS_LoadMallocGroupFile(model->memgroup, sequencedata->name+32, &fz); - if (!model->animcache[sequence->seqindex] || model->animcache[sequence->seqindex]->magic != *(int*)"IDSQ" || model->animcache[sequence->seqindex]->version != 10) + if (!model->animcache[sequence->seqindex] || model->animcache[sequence->seqindex]->magic != (('I'<<0)|('D'<<8)|('S'<<16)|('Q'<<24)) || model->animcache[sequence->seqindex]->version != 10) { Sys_Error("Unable to load %s\n", sequencedata->name+32); return; diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index beda31773..9b38b8c00 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -53,11 +53,6 @@ typedef enum { } shadersort_t; #define MAX_BONES 256 -#ifdef FTE_TARGET_WEB -#define MAX_GPU_BONES 32 //ATI drivers bug out and start to crash if you put this at 128. FIXME: make dynamic. -#else -#define MAX_GPU_BONES 64 //ATI drivers bug out and start to crash if you put this at 128. FIXME: make dynamic. -#endif struct doll_s; void rag_uninstanciateall(void); void rag_flushdolls(qboolean force); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index d862d73f0..67c4706cf 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -1124,6 +1124,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip qboolean geom = false; qboolean tess = false; + char maxgpubones[128]; cvar_t *cvarrefs[64]; char *cvarnames[64]; int cvartypes[64]; @@ -1423,6 +1424,15 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip } blobadded = false; + if (!sh_config.max_gpu_bones) + { + Q_snprintfz(maxgpubones, sizeof(maxgpubones), ""); + nopermutation |= PERMUTATION_SKELETAL; + } + else if (qrenderer == QR_OPENGL && sh_config.maxver < 120) //with old versions of glsl (including gles), mat3x4 is not supported, and we have to emulate it with 3*vec4. maybe we should just do that unconditionally, but whatever. + Q_snprintfz(maxgpubones, sizeof(maxgpubones), "#define MAX_GPU_BONES %i\n#define PACKEDBONES\n", sh_config.max_gpu_bones); + else + Q_snprintfz(maxgpubones, sizeof(maxgpubones), "#define MAX_GPU_BONES %i\n", sh_config.max_gpu_bones); if (gl_specular.value) { if (nummodifiers < MAXMODIFIERS) @@ -1530,6 +1540,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip prog->supportedpermutations = ~nopermutation; for (p = 0; p < PERMUTATIONS; p++) { + qboolean isprimary; memset(&prog->permu[p].h, 0, sizeof(prog->permu[p].h)); if (nopermutation & p) { @@ -1541,8 +1552,11 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip if (p & (1u<supportedpermutations &= ~p; if (!(p & SILENTPERMUTATIONS)) onefailed = true; //don't flag it if skeletal failed. if (!p) //give up if permutation 0 failed. that one failing is fatal. @@ -3483,6 +3499,23 @@ qboolean Shader_Init (void) Hash_InitTable(&shader_active_hash, 1024, shader_active_hash_mem); Shader_FlushGenerics(); + + if (!sh_config.progs_supported) + sh_config.max_gpu_bones = 0; + else + { + extern cvar_t r_max_gpu_bones; + if (!*r_max_gpu_bones.string) + { +#ifdef FTE_TARGET_WEB + sh_config.max_gpu_bones = 0; //webgl tends to crap out if this is too high, so 32 is a good enough value to play safe. some browsers have really shitty uniform performance too, so lets just default to pure-cpu transforms. in javascript. yes, its that bad. +#else + sh_config.max_gpu_bones = 64; //ATI drivers bug out and start to crash if you put this at 128. +#endif + } + else + sh_config.max_gpu_bones = bound(0, r_max_gpu_bones.ival, MAX_BONES); + } } memset(wibuf, 0xff, sizeof(wibuf)); diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index e57873366..b37ebcf4e 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -1263,7 +1263,6 @@ static const char *glsl_hdrs[] = "uniform sampler2D s_deluxmap3;\n" #endif #endif - "#ifdef USEUBOS\n" "layout(std140) uniform u_lightinfo\n" "{\n" @@ -1305,14 +1304,16 @@ static const char *glsl_hdrs[] = "vec3 e_light_ambient;\n" "float e_time;\n" "};\n" - "layout(std140) unform u_bones\n" - "{\n" -#ifdef GLESONLY - "vec4 m_bones[3*"STRINGIFY(MAX_GPU_BONES)"];\n" -#else - "mat3x4 m_bones["STRINGIFY(MAX_GPU_BONES)"]\n" -#endif - "};\n" + "#ifdef SKELETAL\n" + "layout(std140) unform u_bones\n" + "{\n" + "#ifdef PACKEDBONES\n" + "vec4 m_bones[3*MAX_GPU_BONES];\n" + "#else\n" + "mat3x4 m_bones[MAX_GPU_BONES]\n" + "#endif\n" + "};\n" + "#endif\n" "#else\n" "uniform mat4 m_model;\n" "uniform mat4 m_view;\n" @@ -1320,11 +1321,11 @@ static const char *glsl_hdrs[] = "uniform mat4 m_projection;\n" // "uniform mat4 m_modelviewprojection;\n" "#ifdef SKELETAL\n" //skeletal permutation tends to require glsl 120 -#ifdef GLESONLY - "uniform vec4 m_bones[3*"STRINGIFY(MAX_GPU_BONES)"];\n" -#else - "uniform mat3x4 m_bones["STRINGIFY(MAX_GPU_BONES)"];\n" -#endif + "#ifdef PACKEDBONES\n" + "uniform vec4 m_bones[3*MAX_GPU_BONES];\n" + "#else\n" + "uniform mat3x4 m_bones[MAX_GPU_BONES];\n" + "#endif\n" "#endif\n" "uniform mat4 m_invviewprojection;\n" "uniform mat4 m_invmodelviewprojection;\n" @@ -1371,145 +1372,148 @@ static const char *glsl_hdrs[] = , "sys/skeletal.h", "#ifndef DEFS_DEFINED\n" - "attribute vec3 v_normal;\n" - "attribute vec3 v_svector;\n" - "attribute vec3 v_tvector;\n" + "attribute vec3 v_normal;\n" + "attribute vec3 v_svector;\n" + "attribute vec3 v_tvector;\n" "#endif\n" "#ifdef SKELETAL\n" "#ifndef DEFS_DEFINED\n" "attribute vec4 v_bone;" - "attribute vec4 v_weight;" -#ifdef GLESONLY - "uniform vec4 m_bones[3*"STRINGIFY(MAX_GPU_BONES)"];\n" -#else - "uniform mat3x4 m_bones["STRINGIFY(MAX_GPU_BONES)"];\n" -#endif + "attribute vec4 v_weight;\n" + "#ifdef PACKEDBONES\n" + "uniform vec4 m_bones[3*MAX_GPU_BONES];\n" + "#else\n" + "uniform mat3x4 m_bones[MAX_GPU_BONES];\n" + "#endif\n" "#endif\n" - "vec4 skeletaltransform()" - "{" -#ifdef GLESONLY - "mat4 wmat;\n" - "wmat[0] = m_bones[0+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[0] += m_bones[0+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[0] += m_bones[0+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[0] += m_bones[0+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[1] = m_bones[1+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[1] += m_bones[1+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[1] += m_bones[1+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[1] += m_bones[1+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[2] = m_bones[2+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[2] += m_bones[2+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[2] += m_bones[2+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[2] += m_bones[2+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[3] = vec4(0.0,0.0,0.0,1.0);\n" - "return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat);" -#else - "mat3x4 wmat;\n" - "wmat = m_bones[int(v_bone.x)] * v_weight.x;\n" - "wmat += m_bones[int(v_bone.y)] * v_weight.y;\n" - "wmat += m_bones[int(v_bone.z)] * v_weight.z;\n" - "wmat += m_bones[int(v_bone.w)] * v_weight.w;\n" - "return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);" -#endif - "}\n" - "vec4 skeletaltransform_nst(out vec3 n, out vec3 t, out vec3 b)" - "{" -#ifdef GLESONLY - "mat4 wmat;\n" - "wmat[0] = m_bones[0+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[0] += m_bones[0+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[0] += m_bones[0+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[0] += m_bones[0+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[1] = m_bones[1+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[1] += m_bones[1+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[1] += m_bones[1+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[1] += m_bones[1+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[2] = m_bones[2+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[2] += m_bones[2+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[2] += m_bones[2+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[2] += m_bones[2+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[3] = vec4(0.0,0.0,0.0,1.0);\n" - "n = (vec4(v_normal.xyz, 0.0) * wmat).xyz;" - "t = (vec4(v_svector.xyz, 0.0) * wmat).xyz;" - "b = (vec4(v_tvector.xyz, 0.0) * wmat).xyz;" - "return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat);" -#else - "mat3x4 wmat;\n" - "wmat = m_bones[int(v_bone.x)] * v_weight.x;" - "wmat += m_bones[int(v_bone.y)] * v_weight.y;" - "wmat += m_bones[int(v_bone.z)] * v_weight.z;" - "wmat += m_bones[int(v_bone.w)] * v_weight.w;" - "n = vec4(v_normal.xyz, 0.0) * wmat;" - "t = vec4(v_svector.xyz, 0.0) * wmat;" - "b = vec4(v_tvector.xyz, 0.0) * wmat;" - "return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);" -#endif - "}\n" - "vec4 skeletaltransform_wnst(out vec3 w, out vec3 n, out vec3 t, out vec3 b)" - "{" -#ifdef GLESONLY - "mat4 wmat;\n" - "wmat[0] = m_bones[0+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[0] += m_bones[0+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[0] += m_bones[0+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[0] += m_bones[0+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[1] = m_bones[1+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[1] += m_bones[1+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[1] += m_bones[1+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[1] += m_bones[1+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[2] = m_bones[2+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[2] += m_bones[2+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[2] += m_bones[2+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[2] += m_bones[2+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[3] = vec4(0.0,0.0,0.0,1.0);\n" - "n = (vec4(v_normal.xyz, 0.0) * wmat).xyz;" - "t = (vec4(v_svector.xyz, 0.0) * wmat).xyz;" - "b = (vec4(v_tvector.xyz, 0.0) * wmat).xyz;" - "w = (vec4(v_position.xyz, 1.0) * wmat).xyz;" - "return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat);" -#else - "mat3x4 wmat;\n" - "wmat = m_bones[int(v_bone.x)] * v_weight.x;" - "wmat += m_bones[int(v_bone.y)] * v_weight.y;" - "wmat += m_bones[int(v_bone.z)] * v_weight.z;" - "wmat += m_bones[int(v_bone.w)] * v_weight.w;" - "n = vec4(v_normal.xyz, 0.0) * wmat;" - "t = vec4(v_svector.xyz, 0.0) * wmat;" - "b = vec4(v_tvector.xyz, 0.0) * wmat;" - "w = vec4(v_position.xyz, 1.0) * wmat;" - "return m_modelviewprojection * vec4(w, 1.0);" -#endif - "}\n" - "vec4 skeletaltransform_n(out vec3 n)" - "{" -#ifdef GLESONLY - "mat4 wmat;\n" - "wmat[0] = m_bones[0+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[0] += m_bones[0+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[0] += m_bones[0+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[0] += m_bones[0+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[1] = m_bones[1+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[1] += m_bones[1+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[1] += m_bones[1+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[1] += m_bones[1+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[2] = m_bones[2+3*int(v_bone.x)] * v_weight.x;\n" - "wmat[2] += m_bones[2+3*int(v_bone.y)] * v_weight.y;\n" - "wmat[2] += m_bones[2+3*int(v_bone.z)] * v_weight.z;\n" - "wmat[2] += m_bones[2+3*int(v_bone.w)] * v_weight.w;\n" - "wmat[3] = vec4(0.0,0.0,0.0,1.0);\n" - "n = (vec4(v_normal.xyz, 0.0) * wmat).xyz;" - "return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat);" -#else - "mat3x4 wmat;\n" - "wmat = m_bones[int(v_bone.x)] * v_weight.x;" - "wmat += m_bones[int(v_bone.y)] * v_weight.y;" - "wmat += m_bones[int(v_bone.z)] * v_weight.z;" - "wmat += m_bones[int(v_bone.w)] * v_weight.w;" - "n = vec4(v_normal.xyz, 0.0) * wmat;" - "return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);" -#endif - "}\n" + "#ifdef PACKEDBONES\n" + "vec4 skeletaltransform()" + "{" + "mat4 wmat;" + "wmat[0] = m_bones[0+3*int(v_bone.x)] * v_weight.x;" + "wmat[0] += m_bones[0+3*int(v_bone.y)] * v_weight.y;" + "wmat[0] += m_bones[0+3*int(v_bone.z)] * v_weight.z;" + "wmat[0] += m_bones[0+3*int(v_bone.w)] * v_weight.w;" + "wmat[1] = m_bones[1+3*int(v_bone.x)] * v_weight.x;" + "wmat[1] += m_bones[1+3*int(v_bone.y)] * v_weight.y;" + "wmat[1] += m_bones[1+3*int(v_bone.z)] * v_weight.z;" + "wmat[1] += m_bones[1+3*int(v_bone.w)] * v_weight.w;" + "wmat[2] = m_bones[2+3*int(v_bone.x)] * v_weight.x;" + "wmat[2] += m_bones[2+3*int(v_bone.y)] * v_weight.y;" + "wmat[2] += m_bones[2+3*int(v_bone.z)] * v_weight.z;" + "wmat[2] += m_bones[2+3*int(v_bone.w)] * v_weight.w;" + "wmat[3] = vec4(0.0,0.0,0.0,1.0);\n" + "return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat);" + "}\n" + "vec4 skeletaltransform_nst(out vec3 n, out vec3 t, out vec3 b)" + "{" + "mat4 wmat;" + "wmat[0] = m_bones[0+3*int(v_bone.x)] * v_weight.x;" + "wmat[0] += m_bones[0+3*int(v_bone.y)] * v_weight.y;" + "wmat[0] += m_bones[0+3*int(v_bone.z)] * v_weight.z;" + "wmat[0] += m_bones[0+3*int(v_bone.w)] * v_weight.w;" + "wmat[1] = m_bones[1+3*int(v_bone.x)] * v_weight.x;" + "wmat[1] += m_bones[1+3*int(v_bone.y)] * v_weight.y;" + "wmat[1] += m_bones[1+3*int(v_bone.z)] * v_weight.z;" + "wmat[1] += m_bones[1+3*int(v_bone.w)] * v_weight.w;" + "wmat[2] = m_bones[2+3*int(v_bone.x)] * v_weight.x;" + "wmat[2] += m_bones[2+3*int(v_bone.y)] * v_weight.y;" + "wmat[2] += m_bones[2+3*int(v_bone.z)] * v_weight.z;" + "wmat[2] += m_bones[2+3*int(v_bone.w)] * v_weight.w;" + "wmat[3] = vec4(0.0,0.0,0.0,1.0);" + "n = (vec4(v_normal.xyz, 0.0) * wmat).xyz;" + "t = (vec4(v_svector.xyz, 0.0) * wmat).xyz;" + "b = (vec4(v_tvector.xyz, 0.0) * wmat).xyz;" + "return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat);" + "}\n" + "vec4 skeletaltransform_wnst(out vec3 w, out vec3 n, out vec3 t, out vec3 b)" + "{" + "mat4 wmat;" + "wmat[0] = m_bones[0+3*int(v_bone.x)] * v_weight.x;" + "wmat[0] += m_bones[0+3*int(v_bone.y)] * v_weight.y;" + "wmat[0] += m_bones[0+3*int(v_bone.z)] * v_weight.z;" + "wmat[0] += m_bones[0+3*int(v_bone.w)] * v_weight.w;" + "wmat[1] = m_bones[1+3*int(v_bone.x)] * v_weight.x;" + "wmat[1] += m_bones[1+3*int(v_bone.y)] * v_weight.y;" + "wmat[1] += m_bones[1+3*int(v_bone.z)] * v_weight.z;" + "wmat[1] += m_bones[1+3*int(v_bone.w)] * v_weight.w;" + "wmat[2] = m_bones[2+3*int(v_bone.x)] * v_weight.x;" + "wmat[2] += m_bones[2+3*int(v_bone.y)] * v_weight.y;" + "wmat[2] += m_bones[2+3*int(v_bone.z)] * v_weight.z;" + "wmat[2] += m_bones[2+3*int(v_bone.w)] * v_weight.w;" + "wmat[3] = vec4(0.0,0.0,0.0,1.0);" + "n = (vec4(v_normal.xyz, 0.0) * wmat).xyz;" + "t = (vec4(v_svector.xyz, 0.0) * wmat).xyz;" + "b = (vec4(v_tvector.xyz, 0.0) * wmat).xyz;" + "w = (vec4(v_position.xyz, 1.0) * wmat).xyz;" + "return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat);" + "}\n" + "vec4 skeletaltransform_n(out vec3 n)" + "{" + "mat4 wmat;" + "wmat[0] = m_bones[0+3*int(v_bone.x)] * v_weight.x;" + "wmat[0] += m_bones[0+3*int(v_bone.y)] * v_weight.y;" + "wmat[0] += m_bones[0+3*int(v_bone.z)] * v_weight.z;" + "wmat[0] += m_bones[0+3*int(v_bone.w)] * v_weight.w;" + "wmat[1] = m_bones[1+3*int(v_bone.x)] * v_weight.x;" + "wmat[1] += m_bones[1+3*int(v_bone.y)] * v_weight.y;" + "wmat[1] += m_bones[1+3*int(v_bone.z)] * v_weight.z;" + "wmat[1] += m_bones[1+3*int(v_bone.w)] * v_weight.w;" + "wmat[2] = m_bones[2+3*int(v_bone.x)] * v_weight.x;" + "wmat[2] += m_bones[2+3*int(v_bone.y)] * v_weight.y;" + "wmat[2] += m_bones[2+3*int(v_bone.z)] * v_weight.z;" + "wmat[2] += m_bones[2+3*int(v_bone.w)] * v_weight.w;" + "wmat[3] = vec4(0.0,0.0,0.0,1.0);" + "n = (vec4(v_normal.xyz, 0.0) * wmat).xyz;" + "return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat);" + "}\n" + "#else\n" + "vec4 skeletaltransform()" + "{" + "mat3x4 wmat;" + "wmat = m_bones[int(v_bone.x)] * v_weight.x;" + "wmat += m_bones[int(v_bone.y)] * v_weight.y;" + "wmat += m_bones[int(v_bone.z)] * v_weight.z;" + "wmat += m_bones[int(v_bone.w)] * v_weight.w;" + "return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);" + "}\n" + "vec4 skeletaltransform_nst(out vec3 n, out vec3 t, out vec3 b)" + "{" + "mat3x4 wmat;" + "wmat = m_bones[int(v_bone.x)] * v_weight.x;" + "wmat += m_bones[int(v_bone.y)] * v_weight.y;" + "wmat += m_bones[int(v_bone.z)] * v_weight.z;" + "wmat += m_bones[int(v_bone.w)] * v_weight.w;" + "n = vec4(v_normal.xyz, 0.0) * wmat;" + "t = vec4(v_svector.xyz, 0.0) * wmat;" + "b = vec4(v_tvector.xyz, 0.0) * wmat;" + "return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);" + "}\n" + "vec4 skeletaltransform_wnst(out vec3 w, out vec3 n, out vec3 t, out vec3 b)" + "{" + "mat3x4 wmat;" + "wmat = m_bones[int(v_bone.x)] * v_weight.x;" + "wmat += m_bones[int(v_bone.y)] * v_weight.y;" + "wmat += m_bones[int(v_bone.z)] * v_weight.z;" + "wmat += m_bones[int(v_bone.w)] * v_weight.w;" + "n = vec4(v_normal.xyz, 0.0) * wmat;" + "t = vec4(v_svector.xyz, 0.0) * wmat;" + "b = vec4(v_tvector.xyz, 0.0) * wmat;" + "w = vec4(v_position.xyz, 1.0) * wmat;" + "return m_modelviewprojection * vec4(w, 1.0);" + "}\n" + "vec4 skeletaltransform_n(out vec3 n)" + "{" + "mat3x4 wmat;" + "wmat = m_bones[int(v_bone.x)] * v_weight.x;" + "wmat += m_bones[int(v_bone.y)] * v_weight.y;" + "wmat += m_bones[int(v_bone.z)] * v_weight.z;" + "wmat += m_bones[int(v_bone.w)] * v_weight.w;" + "n = vec4(v_normal.xyz, 0.0) * wmat;" + "return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);" + "}\n" + "#endif\n" "#else\n" "#define skeletaltransform ftetransform\n" "vec4 skeletaltransform_wnst(out vec3 w, out vec3 n, out vec3 t, out vec3 b)" @@ -2342,21 +2346,16 @@ qboolean GLSlang_ValidateProgramPermu(program_t *prog, const char *name, unsigne } qboolean GLSlang_CreateProgramPermu(program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *geom, const char *frag, qboolean noerrors, vfsfile_t *blobfile) { -#ifdef FTE_TARGET_WEB - //emscripten's uniform code results in excessive stalls that hinder usability. - //the uniforms required for bones basically turn it into a DOS attack. - //so lets just do all the work inside javascript instead... (oh god this is going to be painful) - if (permu & PERMUTATION_SKELETAL) - return false; -#endif - if (!ver) { - ver = gl_config.gles?100:110; -#ifndef GLESONLY - if (permu & PERMUTATION_SKELETAL) - ver = 120; -#endif + if (gl_config.gles) + ver = 100; + else + { + ver = 110; + if (sh_config.maxver>=120 && (permu & PERMUTATION_SKELETAL)) + ver = 120; + } } if ((permu & PERMUTATION_SKELETAL) && gl_config.maxattribs < 10) return false; //can happen in gles2 diff --git a/engine/gl/glmod_doom.c b/engine/gl/glmod_doom.c index 5ec7cd43f..19414a2e5 100644 --- a/engine/gl/glmod_doom.c +++ b/engine/gl/glmod_doom.c @@ -2033,7 +2033,7 @@ static void Doom_LoadVerticies(char *name) glc = 0; gl1 = NULL; } - else if (gl2[0] == *(int*)"gNd2") + else if (gl2[0] == (('g'<<0)|('N'<<8)|('d'<<16)|('2'<<24))) { gl2++; glc = (fsize-4)/sizeof(int)/2; diff --git a/engine/gl/ltface.c b/engine/gl/ltface.c index 329647230..6d3b66899 100644 --- a/engine/gl/ltface.c +++ b/engine/gl/ltface.c @@ -64,7 +64,7 @@ static vec_t CastRay (struct relight_ctx_s *ctx, vec3_t p1, vec3_t p2) if (ctx->shadows) { - ctx->models[0]->funcs.NativeTrace (ctx->models[0], 0, 0, NULL, p1, p2, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &trace); + ctx->models[0]->funcs.NativeTrace (ctx->models[0], 0, NULLFRAMESTATE, NULL, p1, p2, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &trace); if (trace.fraction < 1) return -1; } diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 1d3fe186a..9b35afdb5 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -696,6 +696,7 @@ typedef struct qboolean progs_required; //no fixed function if this is true (d3d11, gles, gl3core) unsigned int minver; //lowest glsl version usable unsigned int maxver; //highest glsl version usable + unsigned int max_gpu_bones; //max number of bones supported by uniforms. qboolean texfmt[PTI_MAX]; //which texture formats are supported (renderable not implied) unsigned int texture_maxsize; //max size of a 2d texture diff --git a/engine/qclib/pr_comp.h b/engine/qclib/pr_comp.h index b95749e74..93d150a6c 100644 --- a/engine/qclib/pr_comp.h +++ b/engine/qclib/pr_comp.h @@ -553,8 +553,8 @@ typedef struct #define PROG_VERSION 6 #define PROG_KKQWSVVERSION 7 #define PROG_EXTENDEDVERSION 7 -#define PROG_SECONDARYVERSION16 (*(int*)"1FTE" ^ *(int*)"PROG") //something unlikly and still meaningful (to me) -#define PROG_SECONDARYVERSION32 (*(int*)"1FTE" ^ *(int*)"32B ") //something unlikly and still meaningful (to me) +#define PROG_SECONDARYVERSION16 ((('1'<<0)|('F'<<8)|('T'<<16)|('E'<<24))^(('P'<<0)|('R'<<8)|('O'<<16)|('G'<<24))) //something unlikly and still meaningful (to me) +#define PROG_SECONDARYVERSION32 ((('1'<<0)|('F'<<8)|('T'<<16)|('E'<<24))^(('3'<<0)|('2'<<8)|('B'<<16)|(' '<<24))) //something unlikly and still meaningful (to me) typedef struct { int version; diff --git a/engine/qclib/qcd_main.c b/engine/qclib/qcd_main.c index dd278aa1c..bd309db8c 100644 --- a/engine/qclib/qcd_main.c +++ b/engine/qclib/qcd_main.c @@ -262,8 +262,8 @@ char *PDECL filefromprogs(pubprogfuncs_t *ppf, progsnum_t prnum, char *fname, si return NULL; if (pr_progstate[prnum].progs->version != PROG_EXTENDEDVERSION) return NULL; - if (!pr_progstate[prnum].progs->secondaryversion != PROG_SECONDARYVERSION16 && - !pr_progstate[prnum].progs->secondaryversion != PROG_SECONDARYVERSION32) + if (pr_progstate[prnum].progs->secondaryversion != PROG_SECONDARYVERSION16 && + pr_progstate[prnum].progs->secondaryversion != PROG_SECONDARYVERSION32) return NULL; num = *(int*)((char *)pr_progstate[prnum].progs + pr_progstate[prnum].progs->ofsfiles); diff --git a/engine/server/net_preparse.c b/engine/server/net_preparse.c index b4eebe97a..fd0a5842f 100644 --- a/engine/server/net_preparse.c +++ b/engine/server/net_preparse.c @@ -874,7 +874,7 @@ void NPP_NQFlush(void) requireextension = PEXT_TE_BULLET; SV_MulticastProtExt(org, multicasttype, pr_global_struct->dimension_send, 0, requireextension); - buffer[1] = TEQW_EXPLOSIONNOSPRITE; + buffer[1] = TEQW_EXPLOSION_NOSPRITE; } break; case TENQ_BEAM: diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 2eaffa3db..355b9aef0 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -3346,7 +3346,7 @@ static void QCBUILTIN PF_sound (pubprogfuncs_t *prinst, struct globalvars_s *pr_ volume = G_FLOAT(OFS_PARM3) * 255; attenuation = G_FLOAT(OFS_PARM4); if (svprogfuncs->callargc > 5) - pitchadj = G_FLOAT(OFS_PARM5); + pitchadj = G_FLOAT(OFS_PARM5)*0.01; else pitchadj = 0; if (svprogfuncs->callargc > 6) @@ -3386,7 +3386,7 @@ static void QCBUILTIN PF_pointsound(pubprogfuncs_t *prinst, struct globalvars_s volume = G_FLOAT(OFS_PARM2); attenuation = G_FLOAT(OFS_PARM3); if (prinst->callargc >= 5) - pitchpct = G_FLOAT(OFS_PARM4); + pitchpct = G_FLOAT(OFS_PARM4)*0.01; else pitchpct = 0; @@ -5388,12 +5388,12 @@ void SV_point_tempentity (vec3_t o, int type, int count) //count (usually 1) is MSG_WriteByte (&sv.nqmulticast, type); //nq doesn't have a count. #endif break; - case TEQW_EXPLOSIONNOSPRITE: + case TEQW_EXPLOSION_NOSPRITE: MSG_WriteByte (&sv.multicast, TE_EXPLOSION); #ifdef NQPROT MSG_WriteByte (&sv.nqmulticast, TE_EXPLOSION); #endif - type = TEQW_EXPLOSIONNOSPRITE; + type = TEQW_EXPLOSION_NOSPRITE; split = PEXT_TE_BULLET; break; case TE_LIGHTNING1: @@ -8493,7 +8493,7 @@ static void QCBUILTIN PF_te_superspikequad(pubprogfuncs_t *prinst, struct global static void QCBUILTIN PF_te_explosion(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { if (progstype != PROG_QW) - SV_point_tempentity(G_VECTOR(OFS_PARM0), TEQW_EXPLOSIONNOSPRITE, 1); + SV_point_tempentity(G_VECTOR(OFS_PARM0), TEQW_EXPLOSION_NOSPRITE, 1); else SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_EXPLOSION, 1); } @@ -11508,7 +11508,7 @@ void PR_DumpPlatform_f(void) {"m_init", "void()", MENU}, {"m_shutdown", "void()", MENU}, {"m_draw", "void(vector screensize)", MENU, "Provides the menuqc with a chance to draw. Will be called even if the menu does not have focus, so be sure to avoid that. COMPAT: screensize is not provided in DP."}, - {"m_drawloading", "void(vector screensize)", MENU, "Additional drawing function to draw loading screen overlays."}, + {"m_drawloading", "void(vector screensize, float opaque)", MENU, "Additional drawing function to draw loading screens. If opaque is set, then this function must ensure that the entire screen is overdrawn (even if just by a black drawfill)."}, {"m_keydown", "void(float scan, float chr)", MENU}, {"m_keyup", "void(float scan, float chr)", MENU}, {"m_toggle", "void(float wantmode)", MENU}, diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 153efbd86..e0259c158 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -2294,7 +2294,7 @@ qboolean Cull_Traceline(pvscamera_t *cameras, edict_t *seen) for (c = 0; c < cameras->numents; c++) { tr.fraction = 1; - if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, cameras->org[c], seen->v->origin, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &tr)) + if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, NULLFRAMESTATE, NULL, cameras->org[c], seen->v->origin, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &tr)) return false; //wasn't blocked } @@ -2308,7 +2308,7 @@ qboolean Cull_Traceline(pvscamera_t *cameras, edict_t *seen) end[2] = seen->v->origin[2] + ((i&4)?seen->v->mins[2]+0.1:seen->v->maxs[2]); tr.fraction = 1; - if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, cameras->org[c], end, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &tr)) + if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, NULLFRAMESTATE, NULL, cameras->org[c], end, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &tr)) return false; //this trace went through, so don't cull } } diff --git a/engine/server/sv_rankin.c b/engine/server/sv_rankin.c index aa0ba30b8..5665166cc 100644 --- a/engine/server/sv_rankin.c +++ b/engine/server/sv_rankin.c @@ -27,7 +27,7 @@ cvar_t rank_parms_last = CVARD("rank_parms_last", "31", "Mod setting: the index char rank_cvargroup[] = "server rankings"; #define RANKFILE_VERSION ((NUM_RANK_SPAWN_PARMS==32)?0:0x00000001) -#define RANKFILE_IDENT *(int*)"RANK" +#define RANKFILE_IDENT (('R'<<0)|('A'<<8)|('N'<<16)|('K'<<24)) static void READ_PLAYERSTATS(int x, rankstats_t *os) { diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index d7429f1a2..9828887f0 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -1239,7 +1239,7 @@ struct startsoundcontext_s unsigned int sampleidx; unsigned int volume; float attenuation; - float pitchpct; + float ratemul; unsigned int chflags; unsigned int timeofs; }; @@ -1263,7 +1263,7 @@ static void SV_SoundMulticast(client_t *client, sizebuf_t *msg, void *vctx) field_mask |= NQSND_LARGESOUND; if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) { - if (ctx->pitchpct && (ctx->pitchpct != 100)) + if (ctx->ratemul && (ctx->ratemul != 1)) field_mask |= FTESND_PITCHADJ; if (ctx->timeofs != 0) field_mask |= FTESND_TIMEOFS; @@ -1273,6 +1273,14 @@ static void SV_SoundMulticast(client_t *client, sizebuf_t *msg, void *vctx) if (field_mask > 0xff) field_mask |= FTESND_MOREFLAGS; } + if (client->protocol == SCP_DARKPLACES7) + { //dpp7 clients get slightly higher precision + if (ctx->ratemul && (ctx->ratemul != 1)) + { + field_mask |= DPSND_SPEEDUSHORT4000; + field_mask &= ~FTESND_PITCHADJ; + } + } if (ISNQCLIENT(client) || ctx->chan >= 8 || ctx->ent >= 2048 || (field_mask & ~(NQSND_VOLUME|NQSND_ATTENUATION))) { @@ -1293,7 +1301,7 @@ static void SV_SoundMulticast(client_t *client, sizebuf_t *msg, void *vctx) if (field_mask & NQSND_ATTENUATION) MSG_WriteByte (msg, bound(0, ctx->attenuation*64, 255)); if (field_mask & FTESND_PITCHADJ) - MSG_WriteByte (msg, bound(1, ctx->pitchpct, 255)); + MSG_WriteByte (msg, bound(1, ctx->ratemul*100, 255)); if (field_mask & FTESND_TIMEOFS) MSG_WriteShort (msg, bound(-32768, ctx->timeofs*1000, 32767)); if (field_mask & FTESND_VELOCITY) @@ -1302,6 +1310,8 @@ static void SV_SoundMulticast(client_t *client, sizebuf_t *msg, void *vctx) MSG_WriteShort (msg, ctx->vel[1]*8); MSG_WriteShort (msg, ctx->vel[2]*8); } + if (field_mask & DPSND_SPEEDUSHORT4000) + MSG_WriteShort (msg, bound(1, ctx->ratemul*4000, 65535)); if (field_mask & NQSND_LARGEENTITY) { MSG_WriteEntity (msg, ctx->ent); @@ -1336,7 +1346,7 @@ static void SV_SoundMulticast(client_t *client, sizebuf_t *msg, void *vctx) MSG_WriteCoord (msg, ctx->org[i]); } } -void SV_StartSound (int ent, vec3_t origin, float *velocity, int seenmask, int channel, const char *sample, int volume, float attenuation, float pitchadj, float timeofs, unsigned int chflags) +void SV_StartSound (int ent, vec3_t origin, float *velocity, int seenmask, int channel, const char *sample, int volume, float attenuation, float ratemul, float timeofs, unsigned int chflags) { qboolean use_phs; qboolean reliable = chflags & CF_RELIABLE; @@ -1366,7 +1376,7 @@ void SV_StartSound (int ent, vec3_t origin, float *velocity, int seenmask, int c ctx.chflags = chflags; ctx.org = origin; ctx.vel = velocity; - ctx.pitchpct = pitchadj; + ctx.ratemul = ratemul; ctx.timeofs = timeofs; ctx.volume = volume; diff --git a/engine/server/svhl_game.c b/engine/server/svhl_game.c index 4ab5ec67c..6a6932f92 100644 --- a/engine/server/svhl_game.c +++ b/engine/server/svhl_game.c @@ -819,7 +819,7 @@ char *QDECL GHL_TraceTexture(hledict_t *againstent, vec3_t start, vec3_t end) { trace_t tr; bi_trace(); - sv.world.worldmodel->funcs.NativeTrace(sv.world.worldmodel, 0, 0, NULL, start, end, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &tr); + sv.world.worldmodel->funcs.NativeTrace(sv.world.worldmodel, 0, NULLFRAMESTATE, NULL, start, end, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &tr); return tr.surface->name; } unk QDECL GHL_TraceSphere(unk){notimpf(__func__);} diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index a1f608961..ac50b79be 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -421,7 +421,7 @@ static void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs if (!maxs) maxs = vec3_origin; - sv.world.worldmodel->funcs.NativeTrace(sv.world.worldmodel, 0, 0, NULL, start, end, mins, maxs, capsule, contentmask, &tr); + sv.world.worldmodel->funcs.NativeTrace(sv.world.worldmodel, 0, NULLFRAMESTATE, NULL, start, end, mins, maxs, capsule, contentmask, &tr); result->allsolid = tr.allsolid; result->contents = tr.contents; VectorCopy(tr.endpos, result->endpos); diff --git a/engine/server/world.c b/engine/server/world.c index 60fb160c9..f5475e6b1 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -2077,7 +2077,7 @@ trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t memset ( &clip, 0, sizeof ( moveclip_t ) ); // clip to world - w->worldmodel->funcs.NativeTrace(w->worldmodel, 0, 0, NULL, start, end, mins, maxs, false, hitcontentsmask, &clip.trace); + w->worldmodel->funcs.NativeTrace(w->worldmodel, 0, NULLFRAMESTATE, NULL, start, end, mins, maxs, false, hitcontentsmask, &clip.trace); clip.trace.ent = ge->edicts; if (clip.trace.fraction == 0)