From 83cc102208085ea634b834174443868ab2435026 Mon Sep 17 00:00:00 2001 From: TimeServ Date: Sat, 6 Aug 2005 22:39:28 +0000 Subject: [PATCH] m_accel/m_accel_noforce/m_threshold_noforce added, m_filter fixed up added particle fields inwater and spawnchance changed particle field timelimit -> spawntime emit state is now kept (fixes rid# 1015648 FINALLY) git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1203 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_ents.c | 2 + engine/client/cl_tent.c | 21 ++- engine/client/client.h | 1 + engine/client/in_sdl.c | 4 +- engine/client/in_win.c | 52 ++++-- engine/client/m_options.c | 5 +- engine/client/pr_csqc.c | 18 +- engine/client/r_part.c | 338 +++++++++++++++++++++++++------------ engine/client/renderer.c | 2 - engine/common/particles.h | 12 +- engine/gl/gl_alias.c | 2 +- engine/gl/gl_model.c | 20 +-- engine/gl/gl_model.h | 9 +- engine/gl/gl_ppl.c | 34 +--- engine/gl/gl_rlight.c | 6 +- engine/gl/gl_rmain.c | 24 +-- engine/gl/gl_rsurf.c | 10 +- engine/gl/gl_vidlinuxglx.c | 33 ++-- engine/sw/r_main.c | 24 +-- engine/sw/r_misc.c | 1 - engine/sw/sw_model.c | 1 - engine/sw/vid_x.c | 26 ++- 22 files changed, 390 insertions(+), 255 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index bb289a9a8..fe3e4b277 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -1520,6 +1520,7 @@ void CL_LinkPacketEntities (void) } cl_numvisedicts++; + ent->visframe = 0; ent->keynum = s1->number; @@ -1636,6 +1637,7 @@ void CL_LinkPacketEntities (void) if (i == cl_oldnumvisedicts) { P_DelinkTrailstate(&(cl.lerpents[s1->number].trailstate)); + P_DelinkTrailstate(&(cl.lerpents[s1->number].emitstate)); continue; // not in last message } diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 52976f331..5c4ab0b74 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -124,6 +124,7 @@ typedef struct vec3_t start, end; int particleeffect; trailstate_t *trailstate; + trailstate_t *emitstate; } beam_t; beam_t cl_beams[MAX_BEAMS]; @@ -334,6 +335,8 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n model_t *m; int btype, etype; + vec3_t impact, normal; + vec3_t extra; switch(tent) { @@ -384,17 +387,11 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n if (cls.state == ca_active && etype >= 0) { - vec3_t impact, normal; - vec3_t extra; VectorSubtract(end, start, normal); VectorNormalize(normal); VectorMA(end, 4, normal, extra); //extend the end-point by four - if (TraceLineN(start, extra, impact, normal)) - { - P_RunParticleEffectType(impact, normal, 1, etype); - R_AddDecals(end); - R_AddStain(end, -10, -10, -10, 20); - } + if (!TraceLineN(start, extra, impact, normal)) + etype = -1; } b = CL_NewBeam(ent, -1); @@ -413,6 +410,13 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n b->particleeffect = btype; VectorCopy (start, b->start); VectorCopy (end, b->end); + + if (etype >= 0) + { + P_RunParticleEffectState (impact, normal, 1, etype, &(b->emitstate)); + R_AddDecals(end); + R_AddStain(end, -10, -10, -10, 20); + } } void CL_ParseBeam (int tent) { @@ -2242,6 +2246,7 @@ void CL_UpdateBeams (void) if (b->endtime < cl.time) { P_DelinkTrailstate(&b->trailstate); + P_DelinkTrailstate(&b->emitstate); b->model = NULL; continue; } diff --git a/engine/client/client.h b/engine/client/client.h index 8c90a0b49..4cc5ee175 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -391,6 +391,7 @@ typedef struct { vec3_t origin; vec3_t angles; trailstate_t *trailstate; //when to next throw out a trail + trailstate_t *emitstate; //when to next emit unsigned short frame; } lerpents_t; // diff --git a/engine/client/in_sdl.c b/engine/client/in_sdl.c index cf976cd8b..f179cb700 100644 --- a/engine/client/in_sdl.c +++ b/engine/client/in_sdl.c @@ -290,8 +290,8 @@ void IN_Init (void) } void IN_Move (usercmd_t *cmd, int pnum) //add mouse movement to cmd { - mouse_x *= sensitivity.value; - mouse_y *= sensitivity.value; + mouse_x *= sensitivity.value*in_sensitivity; + mouse_y *= sensitivity.value*in_sensitivity; if (!cl.paused && mouseactive) diff --git a/engine/client/in_win.c b/engine/client/in_win.c index 76e572d17..5aa7f5d6b 100644 --- a/engine/client/in_win.c +++ b/engine/client/in_win.c @@ -50,10 +50,14 @@ HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, // mouse variables cvar_t m_filter = {"m_filter","0"}; +cvar_t m_accel = {"m_accel", "0"}; cvar_t m_forcewheel = {"m_forcewheel", "1"}; cvar_t in_mwhook = {"in_mwhook","0", NULL, CVAR_ARCHIVE}; cvar_t in_dinput = {"in_dinput","0", NULL, CVAR_ARCHIVE}; +cvar_t m_accel_noforce = {"m_accel_noforce", "0"}; +cvar_t m_threshold_noforce = {"m_threshold_noforce", "0"}; + cvar_t cl_keypad = {"cl_keypad", "0"}; typedef struct { @@ -89,7 +93,7 @@ mouse_t serialmouse; //int mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum; static qboolean restore_spi; -static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; +static int originalmouseparms[3], newmouseparms[3] = {0, 0, 0}; qboolean mouseinitialized; static qboolean mouseparmsvalid, mouseactivatetoggle; static qboolean mouseshowtoggle = 1; @@ -1115,21 +1119,14 @@ void IN_StartupMouse (void) if (mouseparmsvalid) { - if ( COM_CheckParm ("-noforcemspd") ) + if ( m_accel_noforce.value ) newmouseparms[2] = originalmouseparms[2]; - if ( COM_CheckParm ("-noforcemaccel") ) + if ( m_threshold_noforce.value ) { newmouseparms[0] = originalmouseparms[0]; newmouseparms[1] = originalmouseparms[1]; } - - if ( COM_CheckParm ("-noforcemparms") ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - newmouseparms[2] = originalmouseparms[2]; - } } #ifdef USINGRAWINPUT @@ -1199,11 +1196,29 @@ void IN_Init (void) // mouse variables Cvar_Register (&m_filter, "Input stuff"); + Cvar_Register (&m_accel, "Input stuff"); Cvar_Register (&m_forcewheel, "Input stuff"); Cvar_Register (&in_mwhook, "Input stuff"); Cvar_Register (&in_dinput, "Input stuff"); + Cvar_Register (&m_accel_noforce, "Input stuff"); + Cvar_Register (&m_threshold_noforce, "Input stuff"); + + // this looks strange but quake cmdline definitions + // and MS documentation don't agree with each other + if (COM_CheckParm ("-noforcemspd")) + Cvar_Set(&m_accel_noforce, "1"); + + if (COM_CheckParm ("-noforcemaccel")) + Cvar_Set(&m_threshold_noforce, "1"); + + if (COM_CheckParm ("-noforcemparms")) + { + Cvar_Set(&m_accel_noforce, "1"); + Cvar_Set(&m_threshold_noforce, "1"); + } + if (COM_CheckParm ("-dinput")) Cvar_Set(&in_dinput, "1"); @@ -1311,7 +1326,7 @@ static void ProcessMouse(mouse_t *mouse, usercmd_t *cmd, int pnum) extern int mousemove_x, mousemove_y; int mx, my; - double mouse_x, mouse_y; + double mouse_x, mouse_y, mouse_deltadist; int i; @@ -1380,8 +1395,9 @@ static void ProcessMouse(mouse_t *mouse, usercmd_t *cmd, int pnum) if (m_filter.value) { - mouse_x = (mx + mouse->old_delta[0]) * 0.5; - mouse_y = (my + mouse->old_delta[1]) * 0.5; + double fraction = bound(0, m_filter.value, 2) * 0.5; + mouse_x = (mx*(1-fraction) + mouse->old_delta[0]*fraction); + mouse_y = (my*(1-fraction) + mouse->old_delta[1]*fraction); } else { @@ -1392,8 +1408,14 @@ static void ProcessMouse(mouse_t *mouse, usercmd_t *cmd, int pnum) mouse->old_delta[0] = mx; mouse->old_delta[1] = my; - mouse_x *= sensitivity.value*in_sensitivityscale; - mouse_y *= sensitivity.value*in_sensitivityscale; + if (m_accel.value) { + mouse_deltadist = sqrt(mx*mx + my*my); + mouse_x *= (mouse_deltadist*m_accel.value + sensitivity.value*in_sensitivityscale); + mouse_y *= (mouse_deltadist*m_accel.value + sensitivity.value*in_sensitivityscale); + } else { + mouse_x *= sensitivity.value*in_sensitivityscale; + mouse_y *= sensitivity.value*in_sensitivityscale; + } if (cl.stats[pnum][STAT_VIEWZOOM]) { diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 76301b703..9d63095ef 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -311,7 +311,7 @@ void M_Menu_Particles_f (void) int y = 32; menu_t *menu; int mgt; - extern cvar_t r_bouncysparks, r_part_rain, gl_part_torch, gl_part_flame; + extern cvar_t r_bouncysparks, r_part_rain, gl_part_flame; static const char *r_part_rain_options[] = { "off", @@ -369,8 +369,7 @@ void M_Menu_Particles_f (void) // MC_AddSlider(menu, 16, y, " exp spark count", &r_particles_in_explosion, 16, 1024);y+=8; MC_AddCvarCombo(menu, 16, y, " texture emittance", &r_part_rain, r_part_rain_options, r_part_rain_values);y+=8; - MC_AddCvarCombo(menu, 16, y, " WallTorch effect", &gl_part_torch, gl_part_effects_ops, gl_part_effects_vals);y+=8; - MC_AddCvarCombo(menu, 16, y, " Open flame effect", &gl_part_flame, gl_part_effects_ops, gl_part_effects_vals);y+=8; + MC_AddCvarCombo(menu, 16, y, " model emitters", &gl_part_flame, gl_part_effects_ops, gl_part_effects_vals);y+=8; menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 200, 32, NULL, false); diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 733f21a1f..227065d53 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -1875,25 +1875,25 @@ static void PF_cl_te_gunshotquad (progfuncs_t *prinst, struct globalvars_s *pr_g { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectTypeString(pos, vec3_origin, 1, "te_gunshotquad")) - if (P_RunParticleEffectType(pos, NULL, 2, pt_gunshot)) - P_RunParticleEffect (pos, vec3_origin, 0, 40); + if (P_RunParticleEffectType(pos, NULL, 1, pt_gunshot)) + P_RunParticleEffect (pos, vec3_origin, 0, 20); } static void PF_cl_te_spikequad (progfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectTypeString(pos, vec3_origin, 1, "te_spikequad")) - if (P_RunParticleEffectType(pos, NULL, 2, pt_spike)) - if (P_RunParticleEffectType(pos, NULL, 20, pt_gunshot)) - P_RunParticleEffect (pos, vec3_origin, 0, 20); + if (P_RunParticleEffectType(pos, NULL, 1, pt_spike)) + if (P_RunParticleEffectType(pos, NULL, 10, pt_gunshot)) + P_RunParticleEffect (pos, vec3_origin, 0, 10); } static void PF_cl_te_superspikequad (progfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectTypeString(pos, vec3_origin, 1, "te_superspikequad")) - if (P_RunParticleEffectType(pos, NULL, 2, pt_superspike)) - if (P_RunParticleEffectType(pos, NULL, 4, pt_spike)) - if (P_RunParticleEffectType(pos, NULL, 40, pt_gunshot)) - P_RunParticleEffect (pos, vec3_origin, 0, 40); + if (P_RunParticleEffectType(pos, NULL, 1, pt_superspike)) + if (P_RunParticleEffectType(pos, NULL, 2, pt_spike)) + if (P_RunParticleEffectType(pos, NULL, 20, pt_gunshot)) + P_RunParticleEffect (pos, vec3_origin, 0, 20); } static void PF_cl_te_explosionquad (progfuncs_t *prinst, struct globalvars_s *pr_globals) { diff --git a/engine/client/r_part.c b/engine/client/r_part.c index dd37e85a4..41e83d570 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -132,6 +132,7 @@ cvar_t r_part_sparks_trifan = {"r_part_sparks_trifan", "1"}; cvar_t r_part_sparks_textured = {"r_part_sparks_textured", "1"}; cvar_t r_part_beams = {"r_part_beams", "1"}; cvar_t r_part_beams_textured = {"r_part_beams_textured", "1"}; +cvar_t r_part_contentswitch = {"r_part_contentswitch", "1"}; static float particletime; @@ -173,7 +174,8 @@ typedef struct part_type_s { float randomvelvert; float randscale; - float timelimit; + float spawntime; + float spawnchance; enum {PT_NORMAL, PT_SPARK, PT_SPARKFAN, PT_TEXTUREDSPARK, PT_BEAM, PT_DECAL} type; blendmode_t blendmode; @@ -186,6 +188,7 @@ typedef struct part_type_s { int texturenum; int assoc; int cliptype; + int inwater; float clipcount; int emit; float emittime; @@ -428,6 +431,7 @@ void P_ParticleEffect_f(void) ptype->skytris = st; strcpy(ptype->name, Cmd_Argv(1)); ptype->assoc=-1; + ptype->inwater = -1; ptype->cliptype = -1; ptype->emit = -1; ptype->alpha = 1; @@ -438,6 +442,7 @@ void P_ParticleEffect_f(void) ptype->rotationstartrand = M_PI-ptype->rotationstartmin; ptype->rotationmin = 0; //but don't spin ptype->rotationrand = 0; + ptype->spawnchance = 1; while(1) { @@ -456,9 +461,10 @@ void P_ParticleEffect_f(void) var = Cmd_Argv(0); value = Cmd_Argv(1); + // TODO: switch this mess to some sort of binary tree to increase + // parse speed if (!strcmp(var, "texture")) Q_strncpyz(ptype->texname, value, sizeof(ptype->texname)); - else if (!strcmp(var, "rotationstart")) { ptype->rotationstartmin = atof(value)*M_PI/180; @@ -539,7 +545,14 @@ void P_ParticleEffect_f(void) ptype = &part_type[pnum]; ptype->assoc = assoc; } - + else if (!strcmp(var, "inwater")) + { + // the underwater effect switch should only occur for + // 1 level so the standard assoc check works + assoc = CheckAssosiation(value, pnum); + ptype = &part_type[pnum]; + ptype->inwater = assoc; + } else if (!strcmp(var, "colorindex")) ptype->colorindex = atoi(value); else if (!strcmp(var, "colorrand")) @@ -682,8 +695,10 @@ void P_ParticleEffect_f(void) Con_DPrintf("isbeam is deprechiated, use type beam\n"); ptype->type = PT_BEAM; } - else if (!strcmp(var, "timelimit")) - ptype->timelimit = atof(value); + else if (!strcmp(var, "spawntime")) + ptype->spawntime = atof(value); + else if (!strcmp(var, "spawnchance")) + ptype->spawnchance = atof(value); else if (!strcmp(var, "cliptype")) { assoc = P_ParticleTypeForName(value);//careful - this can realloc all the particle types @@ -919,7 +934,8 @@ void P_AssosiateEffect_f (void) } effectnum = P_AllocateParticleType(effectname); model->particleeffect = effectnum; - model->particleengulphs = atoi(Cmd_Argv(3)); + if (atoi(Cmd_Argv(3))) + model->engineflags |= MDLF_ENGULPHS; P_SetModified(); //make it appear in f_modified. } @@ -946,14 +962,14 @@ void P_AssosiateTrail_f (void) model = Mod_FindName(modelname); effectnum = P_AllocateParticleType(effectname); model->particletrail = effectnum; - model->nodefaulttrail = true; //we could have assigned the trail to a model that wasn't loaded. + model->engineflags |= MDLF_NODEFAULTTRAIL; //we could have assigned the trail to a model that wasn't loaded. P_SetModified(); //make it appear in f_modified. } void P_DefaultTrail (model_t *model) { - if (model->nodefaulttrail == true) + if (model->engineflags & MDLF_NODEFAULTTRAIL) return; if (model->flags & EF_ROCKET) @@ -1166,6 +1182,7 @@ void P_InitParticles (void) Cvar_Register(&r_part_sparks_textured, particlecvargroupname); Cvar_Register(&r_part_beams, particlecvargroupname); Cvar_Register(&r_part_beams_textured, particlecvargroupname); + Cvar_Register(&r_part_contentswitch, particlecvargroupname); pt_explosion = P_AllocateParticleType("te_explosion"); pt_pointfile = P_AllocateParticleType("pe_pointfile"); @@ -1284,7 +1301,7 @@ void P_NewServer(void) { mod->particleeffect = -1; mod->particletrail = -1; - mod->nodefaulttrail = false; + mod->engineflags &= ~MDLF_NODEFAULTTRAIL; P_DefaultTrail(mod); } @@ -1632,6 +1649,71 @@ void P_DarkFieldParticles (float *org, qbyte colour) } } + +// Trailstate functions +static void P_CleanTrailstate(trailstate_t *ts) +{ + // clear LASTSEG flag from lastbeam so it can be reused + if (ts->lastbeam) + { + ts->lastbeam->flags &= ~BS_LASTSEG; + ts->lastbeam->flags |= BS_NODRAW; + } + + // clean structure + memset(ts, 0, sizeof(trailstate_t)); +} + +void P_DelinkTrailstate(trailstate_t **tsk) +{ + trailstate_t *ts; + trailstate_t *assoc; + + if (*tsk == NULL) + return; // not linked to a trailstate + + ts = *tsk; // store old pointer + *tsk = NULL; // clear pointer + + if (ts->key != tsk) + return; // prevent overwrite + + assoc = ts->assoc; // store assoc + P_CleanTrailstate(ts); // clean directly linked trailstate + + // clean trailstates assoc linked + while (assoc) + { + ts = assoc->assoc; + P_CleanTrailstate(assoc); + assoc = ts; + } +} + +static trailstate_t *P_NewTrailstate(trailstate_t **key) +{ + trailstate_t *ts; + + // bounds check here in case r_numtrailstates changed + if (ts_cycle >= r_numtrailstates) + ts_cycle = 0; + + // get trailstate + ts = trailstates + ts_cycle; + + // clear trailstate + P_CleanTrailstate(ts); + + // set key + ts->key = key; + + // advance index cycle + ts_cycle++; + + // return clean trailstate + return ts; +} + /* =============== R_EntityParticles @@ -1747,29 +1829,16 @@ R_BlobExplosion =============== */ -void P_BlobExplosion (vec3_t org) -{ - P_RunParticleEffectType(org, NULL, 1, pt_blob); -} - -int P_RunParticleEffectTypeString (vec3_t org, vec3_t dir, float count, char *name) -{ - int type = P_FindParticleType(name); - if (type < 0) - return 1; - - return P_RunParticleEffectType(org, dir, count, type); -} - int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent, vec3_t tangent2, float size, float **out); -int P_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum) +int P_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk) { part_type_t *ptype = &part_type[typenum]; int i, j, k, l, spawnspc; - float m; + float m, pcount; particle_t *p; beamseg_t *b, *bfirst; vec3_t ofsvec, arsvec; // offsetspread vec, areaspread vec + trailstate_t *ts; if (typenum < 0 || typenum >= numparticletypes) return 1; @@ -1777,6 +1846,39 @@ int P_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum) if (!ptype->loaded) return 1; + // inwater check, switch only once + if (r_part_contentswitch.value && ptype->inwater >= 0) + { + int cont; + cont = cl.worldmodel->hulls[0].funcs.HullPointContents(&cl.worldmodel->hulls[0], org); + + if (cont & FTECONTENTS_WATER) + ptype = &part_type[ptype->inwater]; + } + + // trailstate allocation/deallocation + if (tsk) + { + // if *tsk = NULL get a new one + if (*tsk == NULL) + { + ts = P_NewTrailstate(tsk); + *tsk = ts; + } + else + { + ts = *tsk; + + if (ts->key != tsk) // trailstate was overwritten + { + ts = P_NewTrailstate(tsk); // so get a new one + *tsk = ts; + } + } + } + else + ts = NULL; + if (ptype->type == PT_DECAL) { clippeddecal_t *d; @@ -1868,11 +1970,14 @@ int P_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum) // init spawn specific variables b = bfirst = NULL; spawnspc = 8; + pcount = count*ptype->count; + if (ts) + pcount += ts->emittime; switch (ptype->spawnmode) { case SM_UNICIRCLE: - m = (count*ptype->count); + m = pcount; if (ptype->type == PT_BEAM) m--; @@ -1910,9 +2015,25 @@ int P_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum) default: //others don't need intitialisation break; } - + + // time limit (for completeness) + if (ptype->spawntime && ts) + { + if (ts->statetime > particletime) + return 0; // timelimit still in effect + + ts->statetime = particletime + ptype->spawntime; // record old time + } + + // random chance for point effects + if (ptype->spawnchance < frandom()) + { + i = ceil(pcount); + break; + } + // particle spawning loop - for (i = 0; i < count*ptype->count; i++) + for (i = 0; i < pcount; i++) { if (!free_particles) break; @@ -2138,15 +2259,68 @@ int P_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum) } } + // save off emit times in trailstate + if (ts) + ts->emittime = pcount - i; + // go to next associated effect if (ptype->assoc < 0) break; + + // new trailstate + if (ts) + { + tsk = &(ts->assoc); + // if *tsk = NULL get a new one + if (*tsk == NULL) + { + ts = P_NewTrailstate(tsk); + *tsk = ts; + } + else + { + ts = *tsk; + + if (ts->key != tsk) // trailstate was overwritten + { + ts = P_NewTrailstate(tsk); // so get a new one + *tsk = ts; + } + } + } + ptype = &part_type[ptype->assoc]; } return 0; } +void P_BlobExplosion (vec3_t org) +{ + P_RunParticleEffectType(org, NULL, 1, pt_blob); +} + +int P_RunParticleEffectTypeString (vec3_t org, vec3_t dir, float count, char *name) +{ + int type = P_FindParticleType(name); + if (type < 0) + return 1; + + return P_RunParticleEffectType(org, dir, count, type); +} + +void P_EmitEffect (vec3_t pos, int type, trailstate_t **tsk) +{ +#ifdef SIDEVIEWS + if (r_secondaryview) //this is called when the models are actually drawn. + return; +#endif + if (cl.paused) + return; + + P_RunParticleEffectState(pos, NULL, host_frametime, type, tsk); +} + /* =============== R_RunParticleEffect @@ -2414,77 +2588,12 @@ void CLQ2_RailTrail (vec3_t start, vec3_t end) P_ParticleTrail(start, end, rt_railtrail, NULL); } -// Trailstate functions -static void P_CleanTrailstate(trailstate_t *ts) -{ - // clear LASTSEG flag from lastbeam so it can be reused - if (ts->lastbeam) - { - ts->lastbeam->flags &= ~BS_LASTSEG; - ts->lastbeam->flags |= BS_NODRAW; - } - - // clean structure - memset(ts, 0, sizeof(trailstate_t)); -} - -void P_DelinkTrailstate(trailstate_t **tsk) -{ - trailstate_t *ts; - trailstate_t *assoc; - - if (*tsk == NULL) - return; // not linked to a trailstate - - ts = *tsk; // store old pointer - *tsk = NULL; // clear pointer - - if (ts->key != tsk) - return; // prevent overwrite - - assoc = ts->assoc; // store assoc - P_CleanTrailstate(ts); // clean directly linked trailstate - - // clean trailstates assoc linked - while (assoc) - { - ts = assoc->assoc; - P_CleanTrailstate(assoc); - assoc = ts; - } -} - -static trailstate_t *P_NewTrailstate(trailstate_t **key) -{ - trailstate_t *ts; - - // bounds check here in case r_numtrailstates changed - if (ts_cycle >= r_numtrailstates) - ts_cycle = 0; - - // get trailstate - ts = trailstates + ts_cycle; - - // clear trailstate - P_CleanTrailstate(ts); - - // set key - ts->key = key; - - // advance index cycle - ts_cycle++; - - // return clean trailstate - return ts; -} - -int P_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailstate_t **tsk) +static int P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype, trailstate_t **tsk) { vec3_t vec, vstep, right, up, start; float len; int tcount; particle_t *p; - part_type_t *ptype = &part_type[type]; beamseg_t *b; beamseg_t *bfirst; trailstate_t *ts; @@ -2495,12 +2604,6 @@ int P_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailstate_t **tsk) float stop; float tdegree = 2*M_PI/256; /* MSVC whine */ - if (type < 0 || type >= numparticletypes) - return 1; //bad value - - if (!ptype->loaded) - return 1; - VectorCopy(startpos, start); // trailstate allocation/deallocation @@ -2535,15 +2638,19 @@ int P_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailstate_t **tsk) } // time limit for trails - if (ptype->timelimit && ts) + if (ptype->spawntime && ts) { if (ts->statetime > particletime) return 0; // timelimit still in effect - ts->statetime = particletime + ptype->timelimit; // record old time + ts->statetime = particletime + ptype->spawntime; // record old time ts = NULL; // clear trailstate so we don't save length/lastseg } + // random chance for trails + if (ptype->spawnchance < frandom()) + return 0; // don't spawn but return success + if (!ptype->die) ts = NULL; @@ -2793,16 +2900,27 @@ int P_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailstate_t **tsk) return 0; } -void P_TorchEffect (vec3_t pos, int type) +int P_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailstate_t **tsk) { -#ifdef SIDEVIEWS - if (r_secondaryview) //this is called when the models are actually drawn. - return; -#endif - if (cl.paused) - return; + part_type_t *ptype = &part_type[type]; - P_RunParticleEffectType(pos, NULL, host_frametime, type); + if (type < 0 || type >= numparticletypes) + return 1; //bad value + + if (!ptype->loaded) + return 1; + + // inwater check, switch only once + if (r_part_contentswitch.value && ptype->inwater >= 0) + { + int cont; + cont = cl.worldmodel->hulls[0].funcs.HullPointContents(&cl.worldmodel->hulls[0], startpos); + + if (cont & FTECONTENTS_WATER) + ptype = &part_type[ptype->inwater]; + } + + return P_ParticleTrailDraw (startpos, end, ptype, tsk); } void CLQ2_BubbleTrail (vec3_t start, vec3_t end) diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 44977836f..bc81f1d3b 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -93,7 +93,6 @@ cvar_t gl_font = {"gl_font", ""}; cvar_t gl_conback = {"gl_conback", ""}; cvar_t gl_smoothfont = {"gl_smoothfont", "1"}; cvar_t gl_part_flame = {"gl_part_flame", "1"}; -cvar_t gl_part_torch = {"gl_part_torch", "1"}; cvar_t r_part_rain = {"r_part_rain", "0"}; cvar_t r_bouncysparks = {"r_bouncysparks", "0"}; @@ -266,7 +265,6 @@ void GLRenderer_Init(void) Cvar_Register (&r_shadow_realtime_world_lightmaps, GLRENDEREROPTIONS); Cvar_Register (&gl_part_flame, GRAPHICALNICETIES); - Cvar_Register (&gl_part_torch, GRAPHICALNICETIES); Cvar_Register (&gl_keeptjunctions, GLRENDEREROPTIONS); Cvar_Register (&gl_reporttjunctions, GLRENDEREROPTIONS); diff --git a/engine/common/particles.h b/engine/common/particles.h index ac467962b..a7b07d751 100644 --- a/engine/common/particles.h +++ b/engine/common/particles.h @@ -67,9 +67,12 @@ typedef struct trailstate_s { struct beamseg_s *lastbeam; // last beam pointer (flagged with BS_LASTSEG) union { float lastdist; // last distance used with particle effect - float statetime; // time to emit effect again + float statetime; // time to emit effect again (used by spawntime field) + }; + union { + float laststop; // last stopping point for particle effect + float emittime; // used by r_effect emitters }; - float laststop; // last stopping point for particle effect } trailstate_t; // !!! if this is changed, it must be changed in d_ifacea.h too !!! @@ -154,7 +157,7 @@ void P_RunParticleEffect4 (vec3_t org, float radius, int color, int effect, int void P_DarkFieldParticles (float *org, qbyte colour); void P_EntityParticles (float *org, qbyte colour, float *radius); //nq's EF_BRIGHTFIELD -void P_TorchEffect (vec3_t pos, int type); //particles centered around a model, called every frame for those models. +void P_EmitEffect (vec3_t pos, int type, trailstate_t **tsk); //particles centered around a model, called every frame for those models. //functions that spawn point effects (basically just pass throughs) void P_BlobExplosion (vec3_t org); //tarbaby explosion or TF emp. @@ -169,8 +172,9 @@ int P_ParticleTrail (vec3_t start, vec3_t end, int type, trailstate_t **trailsta void P_DefaultTrail (struct model_s *model); //fills in the default particle properties for a loaded model. Should already have the model flags set. //the core spawn function for point effects -int P_RunParticleEffectType(vec3_t org, vec3_t dir, float count, int type); //1 if failed. +int P_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk); //1 if failed int P_RunParticleEffectTypeString (vec3_t org, vec3_t dir, float count, char *name); //1 if failed. +#define P_RunParticleEffectType(a,b,c,d) P_RunParticleEffectState(a,b,c,d,NULL) void P_EmitSkyEffectTris(struct model_s *mod, struct msurface_s *fa); diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index f3d5310b1..f072a793d 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -50,7 +50,7 @@ typedef struct -extern cvar_t gl_part_flame, gl_part_torch, r_fullbrightSkins, r_fb_models; +extern cvar_t gl_part_flame, r_fullbrightSkins, r_fb_models; extern cvar_t r_noaliasshadows; void R_TorchEffect (vec3_t pos, int type); void GLMod_FloodFillSkin( qbyte *skin, int skinwidth, int skinheight ); diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index af1530b1f..039bdf4f4 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -486,7 +486,7 @@ model_t *GLMod_FindName (char *name) mod->needload = true; mod_numknown++; mod->particleeffect = -1; - mod->nodefaulttrail = false; + mod->particletrail = -1; } return mod; @@ -1307,7 +1307,7 @@ void GLMod_LoadLighting (lump_t *l) { qbyte *luxdata = NULL; int mapcomeswith24bitcolouredlighting = false; - loadmodel->rgblighting = false; + loadmodel->engineflags &= ~MDLF_RGBLIGHTING; //lit file light intensity is made to match the world's light intensity. if (cls.allow_lightmapgamma) @@ -1419,7 +1419,7 @@ void GLMod_LoadLighting (lump_t *l) //load it loadmodel->lightdata = litdata+8; - loadmodel->rgblighting = true; + loadmodel->engineflags |= MDLF_RGBLIGHTING; //now some cheat protection. @@ -1458,16 +1458,16 @@ void GLMod_LoadLighting (lump_t *l) //failed to find } if (mapcomeswith24bitcolouredlighting) - loadmodel->rgblighting = true; + loadmodel->engineflags |= MDLF_RGBLIGHTING; #ifdef RUNTIMELIGHTING - else if (r_loadlits.value == 2 && !lightmodel && (loadmodel->rgblighting != true || (!luxdata && gl_bumpmappingpossible))) + else if (r_loadlits.value == 2 && !lightmodel && (!(loadmodel->engineflags & MDLF_RGBLIGHTING) || (!luxdata && gl_bumpmappingpossible))) { qbyte *litdata = NULL; int i; qbyte *normal; - writelitfile = !loadmodel->rgblighting; - loadmodel->rgblighting = true; + writelitfile = !(loadmodel->engineflags & MDLF_RGBLIGHTING); + loadmodel->engineflags |= MDLF_RGBLIGHTING; loadmodel->lightdata = Hunk_AllocName ( l->filelen*3+8, loadname); strcpy(loadmodel->lightdata, "QLIT"); ((int*)loadmodel->lightdata)[1] = LittleLong(1); @@ -1505,7 +1505,7 @@ void GLMod_LoadLighting (lump_t *l) if (loadmodel->lightdata) { - if (loadmodel->rgblighting && r_lightmap_saturation.value != 1.0f) + if ((loadmodel->engineflags & MDLF_RGBLIGHTING) && r_lightmap_saturation.value != 1.0f) { // desaturate lightmap according to cvar SaturateR8G8B8(loadmodel->lightdata, l->filelen, r_lightmap_saturation.value); @@ -1527,7 +1527,7 @@ void GLMod_LoadLighting (lump_t *l) *out++ = lmgamma[*in++]; } - if (loadmodel->rgblighting && r_lightmap_saturation.value != 1.0f) + if ((loadmodel->engineflags & MDLF_RGBLIGHTING) && r_lightmap_saturation.value != 1.0f) SaturateR8G8B8(loadmodel->lightdata, l->filelen, r_lightmap_saturation.value); } //memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); @@ -1879,7 +1879,7 @@ void GLMod_LoadFaces (lump_t *l) i = LittleLong(in->lightofs); if (i == -1) out->samples = NULL; - else if (loadmodel->rgblighting && loadmodel->fromgame != fg_halflife) + else if ((loadmodel->engineflags & MDLF_RGBLIGHTING) && loadmodel->fromgame != fg_halflife) out->samples = loadmodel->lightdata + i*3; else out->samples = loadmodel->lightdata + i; diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index ef00c0282..c463b894f 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -710,12 +710,9 @@ typedef struct model_s synctype_t synctype; int flags; + int engineflags; int particleeffect; - qboolean particleengulphs; int particletrail; - qboolean nodefaulttrail; - - qboolean rgblighting; //.lit, halflife. // // volume occupied by the model graphics @@ -793,6 +790,10 @@ typedef struct model_s } model_t; +#define MDLF_ENGULPHS 0x1 // particle effect engulphs model (don't draw) +#define MDLF_NODEFAULTTRAIL 0x2 +#define MDLF_RGBLIGHTING 0x4 + //============================================================================ /* void Mod_Init (void); diff --git a/engine/gl/gl_ppl.c b/engine/gl/gl_ppl.c index 70c294663..9a8ecd329 100644 --- a/engine/gl/gl_ppl.c +++ b/engine/gl/gl_ppl.c @@ -1856,18 +1856,12 @@ void PPL_BaseEntTextures(void) if (!currententity->model) continue; - if (cls.allow_anyparticles || currententity->visframe) //allowed or static { - if (currententity->model->particleeffect>=0) + if (currententity->model->engineflags & MDLF_ENGULPHS) { - if (currententity->model->particleengulphs) - { - if (gl_part_flame.value) - { //particle effect is addedin GLR_DrawEntitiesOnList. Is this so wrong? - continue; - } - } + if (gl_part_flame.value) + continue; } } @@ -2856,15 +2850,10 @@ void PPL_DrawEntFullBrights(void) if (cls.allow_anyparticles || currententity->visframe) //allowed or static { - if (currententity->model->particleeffect>=0) + if (currententity->model->engineflags & MDLF_ENGULPHS) { - if (currententity->model->particleengulphs) - { - if (gl_part_flame.value) - { - continue; - } - } + if (gl_part_flame.value) + continue; } } @@ -3919,15 +3908,10 @@ void PPL_DrawShadowMeshes(dlight_t *dl) if (cls.allow_anyparticles || currententity->visframe) //allowed or static { - if (currententity->model->particleeffect>=0) + if (currententity->model->engineflags & MDLF_ENGULPHS) { - if (currententity->model->particleengulphs) - { - if (gl_part_flame.value) - { - continue; - } - } + if (gl_part_flame.value) + continue; } } diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index 17c99e10f..84cd56f00 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -617,7 +617,7 @@ int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) r = 0; if (lightmap) { - if (cl.worldmodel->rgblighting) + if (cl.worldmodel->engineflags & MDLF_RGBLIGHTING) { lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3; @@ -780,7 +780,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end) { if (cl.worldmodel->deluxdata) { - if (cl.worldmodel->rgblighting) + if (cl.worldmodel->engineflags & MDLF_RGBLIGHTING) { deluxmap = surf->samples - cl.worldmodel->lightdata + cl.worldmodel->deluxdata; @@ -841,7 +841,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end) } else { - if (cl.worldmodel->rgblighting) + if (cl.worldmodel->engineflags & MDLF_RGBLIGHTING) { lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3; for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 1f2d69019..406360638 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -110,7 +110,6 @@ cvar_t r_novis = {"r_novis","0"}; //cvar_t r_netgraph = {"r_netgraph","0"}; extern cvar_t gl_part_flame; -extern cvar_t gl_part_torch; cvar_t gl_clear = {"gl_clear","0"}; cvar_t gl_cull = {"gl_cull","1"}; @@ -788,24 +787,13 @@ void GLR_DrawEntitiesOnList (void) if (cls.allow_anyparticles || currententity->visframe) //allowed or static { - if (currententity->model->particleeffect>=0) + if (gl_part_flame.value) { - if (currententity->model->particleengulphs) - { - if (gl_part_flame.value) - { - P_TorchEffect(currententity->origin, currententity->model->particleeffect); - currententity->model = NULL; - continue; - } - } - else - { - if (gl_part_torch.value) - { - P_TorchEffect(currententity->origin, currententity->model->particleeffect); - } - } + P_EmitEffect (currententity->origin, + currententity->model->particleeffect, + &(cl.lerpents[currententity->keynum].emitstate)); + if (currententity->model->engineflags & MDLF_ENGULPHS) + continue; } } diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index fd00503e0..a68311a0a 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -642,7 +642,7 @@ void GLR_BuildDeluxMap (msurface_t *surf, qbyte *dest) goto store; } - if (currentmodel->rgblighting) + if (currentmodel->engineflags & MDLF_RGBLIGHTING) deluxmap = surf->samples - currentmodel->lightdata + currentmodel->deluxdata; else deluxmap = (surf->samples - currentmodel->lightdata)*3 + currentmodel->deluxdata; @@ -659,7 +659,7 @@ void GLR_BuildDeluxMap (msurface_t *surf, qbyte *dest) // add all the lightmaps if (lightmap) { - if (currentmodel->rgblighting) + if (currentmodel->engineflags & MDLF_RGBLIGHTING) { deluxmap = surf->samples - currentmodel->lightdata + currentmodel->deluxdata; @@ -839,7 +839,7 @@ void GLR_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap * } // memset(blocklights, 255, sizeof(blocklights)); } - else if (currentmodel->rgblighting) //rgb + else if (currentmodel->engineflags & MDLF_RGBLIGHTING) //rgb { for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; maps++) @@ -928,7 +928,7 @@ void GLR_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap * // add all the lightmaps if (lightmap) { - if (currentmodel->rgblighting) //rgb + if (currentmodel->engineflags & MDLF_RGBLIGHTING) //rgb for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; maps++) { @@ -3753,7 +3753,7 @@ void GL_BuildLightmaps (void) if (cl.worldmodel->fromgame == fg_doom) return; //no lightmaps. - if (cl.worldmodel->rgblighting || cl.worldmodel->deluxdata || r_loadlits.value) + if ((cl.worldmodel->engineflags & MDLF_RGBLIGHTING) || cl.worldmodel->deluxdata || r_loadlits.value) gl_lightmap_format = GL_RGB; else gl_lightmap_format = GL_LUMINANCE; diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index ae7e67776..7fbb6ce2a 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -84,6 +84,8 @@ extern cvar_t _windowed_mouse; #ifndef SWQUAKE cvar_t m_filter = {"m_filter", "0"}; +cvar_t m_accel = {"m_accel", "0"}; + #ifdef IN_XFLIP cvar_t in_xflip = {"in_xflip", "0"}; #endif @@ -933,17 +935,10 @@ void IN_MouseMove (usercmd_t *cmd, int pnum) { extern int mouseusedforgui, mousecursor_x, mousecursor_y; extern int mousemove_x, mousemove_y; + float mx, my; - if (m_filter.value) - { - mouse_x = (mouse_x + old_mouse_x) * 0.5; - mouse_y = (mouse_y + old_mouse_y) * 0.5; - } - old_mouse_x = mouse_x; - old_mouse_y = mouse_y; - - mouse_x *= sensitivity.value; - mouse_y *= sensitivity.value; + mx = mouse_x; + my = mouse_y; if (mouseusedforgui || (key_dest == key_menu && m_state == m_complex) || UI_MenuState()) { @@ -967,6 +962,24 @@ void IN_MouseMove (usercmd_t *cmd, int pnum) UI_MousePosition(mousecursor_x, mousecursor_y); } + if (m_filter.value) + { + float fraction = bound(0, m_filter.value, 2) * 0.5; + mouse_x = (mouse_x*(1-fraction) + old_mouse_x*fraction); + mouse_y = (mouse_y*(1-fraction) + old_mouse_y*fraction); + } + old_mouse_x = mx; + old_mouse_y = my; + + if (m_accel.value) { + mouse_deltadist = sqrt(mx*mx + my*my); + mouse_x *= (mouse_deltadist*m_accel.value + sensitivity.value*in_sensitivityscale); + mouse_y *= (mouse_deltadist*m_accel.value + sensitivity.value*in_sensitivityscale); + } else { + mouse_x *= sensitivity.value*in_sensitivityscale; + mouse_y *= sensitivity.value*in_sensitivityscale; + } + #ifdef IN_XFLIP if(in_xflip.value) mouse_x *= -1; #endif diff --git a/engine/sw/r_main.c b/engine/sw/r_main.c index 0e799dc0e..de9371687 100644 --- a/engine/sw/r_main.c +++ b/engine/sw/r_main.c @@ -664,7 +664,7 @@ R_DrawEntitiesOnList */ void SWR_DrawEntitiesOnList (void) { - extern cvar_t gl_part_flame, gl_part_torch; + extern cvar_t gl_part_flame; int i, j; int lnum; alight_t lighting; @@ -699,23 +699,13 @@ void SWR_DrawEntitiesOnList (void) if (cls.allow_anyparticles || currententity->visframe) //allowed or static { - if (currententity->model->particleeffect>=0) + if (gl_part_flame.value) { - if (currententity->model->particleengulphs) - { - if (gl_part_flame.value) - { - P_TorchEffect(currententity->origin, currententity->model->particleeffect); - continue; - } - } - else - { - if (gl_part_torch.value) - { - P_TorchEffect(currententity->origin, currententity->model->particleeffect); - } - } + P_EmitEffect (currententity->origin, + currententity->model->particleeffect, + &(cl.lerpents[currententity->keynum].emitstate)); + if (currententity->model->engineflags & MDLF_ENGULPHS) + continue; } } diff --git a/engine/sw/r_misc.c b/engine/sw/r_misc.c index a0b509712..3e32c1ecb 100644 --- a/engine/sw/r_misc.c +++ b/engine/sw/r_misc.c @@ -171,7 +171,6 @@ Performance monitoring tool ============== */ #define MAX_TIMINGS 100 -extern float mouse_x, mouse_y; int graphval; void R_TimeGraph (void) { diff --git a/engine/sw/sw_model.c b/engine/sw/sw_model.c index 9e4bc6653..94184d16f 100644 --- a/engine/sw/sw_model.c +++ b/engine/sw/sw_model.c @@ -246,7 +246,6 @@ model_t *SWMod_FindName (char *name) mod->needload = true; mod_numknown++; mod->particleeffect = -1; - mod->nodefaulttrail = false; } return mod; diff --git a/engine/sw/vid_x.c b/engine/sw/vid_x.c index 6749b4588..15a030d32 100644 --- a/engine/sw/vid_x.c +++ b/engine/sw/vid_x.c @@ -140,6 +140,7 @@ int shmget (key_t key, size_t size, int shmflg) #endif cvar_t m_filter = {"m_filter","0", NULL, CVAR_ARCHIVE}; +cvar_t m_accel = {"m_accel", "0"}; #ifdef IN_XFLIP cvar_t in_xflip = {"in_xflip", "0"}; #endif @@ -1254,6 +1255,7 @@ void IN_Init (void) { Cvar_Register (&_windowed_mouse, "input controls"); Cvar_Register (&m_filter, "input controls"); + Cvar_Register (&m_accel, "input controls"); #ifdef IN_XFLIP Cvar_Register (&in_xflip, "input controls"); #endif @@ -1287,6 +1289,8 @@ void IN_Commands (void) extern int mousecursor_x, mousecursor_y; void IN_Move (usercmd_t *cmd, int pnum) { + float mx, my; + if (!mouse_avail) { mousecursor_x = p_mouse_x; //absolute offsets. @@ -1309,16 +1313,24 @@ void IN_Move (usercmd_t *cmd, int pnum) if (mousecursor_y > vid.height) mousecursor_y = vid.height; - if (m_filter.value) { - mouse_x = (mouse_x + old_mouse_x) * 0.5; - mouse_y = (mouse_y + old_mouse_y) * 0.5; + if (m_filter.value) + { + float fraction = bound(0, m_filter.value, 2) * 0.5; + mouse_x = (mouse_x*(1-fraction) + old_mouse_x*fraction); + mouse_y = (mouse_y*(1-fraction) + old_mouse_y*fraction); } - old_mouse_x = mouse_x; - old_mouse_y = mouse_y; + old_mouse_x = mx; + old_mouse_y = my; - mouse_x *= sensitivity.value; - mouse_y *= sensitivity.value; + if (m_accel.value) { + mouse_deltadist = sqrt(mx*mx + my*my); + mouse_x *= (mouse_deltadist*m_accel.value + sensitivity.value*in_sensitivityscale); + mouse_y *= (mouse_deltadist*m_accel.value + sensitivity.value*in_sensitivityscale); + } else { + mouse_x *= sensitivity.value*in_sensitivityscale; + mouse_y *= sensitivity.value*in_sensitivityscale; + } #ifdef IN_XFLIP if(in_xflip.value) mouse_x *= -1;