X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=cl_particles.c;h=202f32e924a8dff2e4109edef7f641ba4125ccc2;hb=5b9edfa473d826457b915c59b09ac240d805173e;hp=7b56f9146080f8b2d072fbf47363240871ade495;hpb=29669abad5bba01d0607f28a3ade12ffd7ba79b9;p=xonotic%2Fdarkplaces.git diff --git a/cl_particles.c b/cl_particles.c index 7b56f914..202f32e9 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -20,198 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -#ifdef WORKINGLQUAKE -#define lhrandom(MIN,MAX) ((rand() & 32767) * (((MAX)-(MIN)) * (1.0f / 32767.0f)) + (MIN)) -#define NUMVERTEXNORMALS 162 -siextern float r_avertexnormals[NUMVERTEXNORMALS][3]; -#define m_bytenormals r_avertexnormals -#define CL_PointQ1Contents(v) (Mod_PointInLeaf(v,cl.worldmodel)->contents) -typedef unsigned char unsigned char; -#define cl_stainmaps.integer 0 -void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2) -{ -} -#define CL_EntityParticles R_EntityParticles -#define CL_ReadPointFile_f R_ReadPointFile_f -#define CL_ParseParticleEffect R_ParseParticleEffect -#define CL_ParticleExplosion R_ParticleExplosion -#define CL_ParticleExplosion2 R_ParticleExplosion2 -#define CL_TeleportSplash R_TeleportSplash -#define CL_BlobExplosion R_BlobExplosion -#define CL_RunParticleEffect R_RunParticleEffect -#define CL_LavaSplash R_LavaSplash -void R_CalcBeam_Vertex3f (float *vert, vec3_t org1, vec3_t org2, float width) -{ - vec3_t right1, right2, diff, normal; - - VectorSubtract (org2, org1, normal); - VectorNormalize (normal); - - // calculate 'right' vector for start - VectorSubtract (r_vieworigin, org1, diff); - VectorNormalize (diff); - CrossProduct (normal, diff, right1); - - // calculate 'right' vector for end - VectorSubtract (r_vieworigin, org2, diff); - VectorNormalize (diff); - CrossProduct (normal, diff, right2); - - vert[ 0] = org1[0] + width * right1[0]; - vert[ 1] = org1[1] + width * right1[1]; - vert[ 2] = org1[2] + width * right1[2]; - vert[ 3] = org1[0] - width * right1[0]; - vert[ 4] = org1[1] - width * right1[1]; - vert[ 5] = org1[2] - width * right1[2]; - vert[ 6] = org2[0] - width * right2[0]; - vert[ 7] = org2[1] - width * right2[1]; - vert[ 8] = org2[2] - width * right2[2]; - vert[ 9] = org2[0] + width * right2[0]; - vert[10] = org2[1] + width * right2[1]; - vert[11] = org2[2] + width * right2[2]; -} -void fractalnoise(unsigned char *noise, int size, int startgrid) -{ - int x, y, g, g2, amplitude, min, max, size1 = size - 1, sizepower, gridpower; - int *noisebuf; -#define n(x,y) noisebuf[((y)&size1)*size+((x)&size1)] - - for (sizepower = 0;(1 << sizepower) < size;sizepower++); - if (size != (1 << sizepower)) - { - Con_Printf("fractalnoise: size must be power of 2\n"); - return; - } - - for (gridpower = 0;(1 << gridpower) < startgrid;gridpower++); - if (startgrid != (1 << gridpower)) - { - Con_Printf("fractalnoise: grid must be power of 2\n"); - return; - } - - startgrid = bound(0, startgrid, size); - - amplitude = 0xFFFF; // this gets halved before use - noisebuf = malloc(size*size*sizeof(int)); - memset(noisebuf, 0, size*size*sizeof(int)); - - for (g2 = startgrid;g2;g2 >>= 1) - { - // brownian motion (at every smaller level there is random behavior) - amplitude >>= 1; - for (y = 0;y < size;y += g2) - for (x = 0;x < size;x += g2) - n(x,y) += (rand()&litude); - - g = g2 >> 1; - if (g) - { - // subdivide, diamond-square algorithm (really this has little to do with squares) - // diamond - for (y = 0;y < size;y += g2) - for (x = 0;x < size;x += g2) - n(x+g,y+g) = (n(x,y) + n(x+g2,y) + n(x,y+g2) + n(x+g2,y+g2)) >> 2; - // square - for (y = 0;y < size;y += g2) - for (x = 0;x < size;x += g2) - { - n(x+g,y) = (n(x,y) + n(x+g2,y) + n(x+g,y-g) + n(x+g,y+g)) >> 2; - n(x,y+g) = (n(x,y) + n(x,y+g2) + n(x-g,y+g) + n(x+g,y+g)) >> 2; - } - } - } - // find range of noise values - min = max = 0; - for (y = 0;y < size;y++) - for (x = 0;x < size;x++) - { - if (n(x,y) < min) min = n(x,y); - if (n(x,y) > max) max = n(x,y); - } - max -= min; - max++; - // normalize noise and copy to output - for (y = 0;y < size;y++) - for (x = 0;x < size;x++) - *noise++ = (unsigned char) (((n(x,y) - min) * 256) / max); - free(noisebuf); -#undef n -} -void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up) -{ - float d; - - right[0] = forward[2]; - right[1] = -forward[0]; - right[2] = forward[1]; - - d = DotProduct(forward, right); - right[0] -= d * forward[0]; - right[1] -= d * forward[1]; - right[2] -= d * forward[2]; - VectorNormalize(right); - CrossProduct(right, forward, up); -} -#if QW -#include "pmove.h" -extern qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, pmtrace_t *trace); -#endif -trace_t CL_TraceBox (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hitbmodels, int *hitent, int hitsupercontentsmask, qboolean hitplayers) -{ -#if QW - pmtrace_t trace; -#else - trace_t trace; -#endif - memset (&trace, 0, sizeof(trace)); - trace.fraction = 1; - VectorCopy (end, trace.endpos); -#if QW - PM_RecursiveHullCheck (cl.model_precache[1]->hulls, 0, 0, 1, start, end, &trace); -#else - RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace); -#endif - return trace; -} -#else #include "cl_collision.h" #include "image.h" -#endif - -#define MAX_PARTICLES 32768 // default max # of particles at one time -#define ABSOLUTE_MIN_PARTICLES 512 // no fewer than this no matter what's on the command line - -typedef enum -{ - PARTICLE_BILLBOARD = 0, - PARTICLE_SPARK = 1, - PARTICLE_ORIENTED_DOUBLESIDED = 2, - PARTICLE_BEAM = 3 -} -porientation_t; - -typedef enum -{ - PBLEND_ALPHA = 0, - PBLEND_ADD = 1, - PBLEND_MOD = 2 -} -pblend_t; - -typedef struct particletype_s -{ - pblend_t blendmode; - porientation_t orientation; - qboolean lighting; -} -particletype_t; - -typedef enum -{ - pt_alphastatic, pt_static, pt_spark, pt_beam, pt_rain, pt_raindecal, pt_snow, pt_bubble, pt_blood, pt_smoke, pt_decal, pt_entityparticle, pt_total -} -ptype_t; // must match ptype_t values particletype_t particletype[pt_total] = @@ -230,27 +40,6 @@ particletype_t particletype[pt_total] = {PBLEND_ALPHA, PARTICLE_BILLBOARD, false}, //pt_entityparticle }; -typedef struct particle_s -{ - particletype_t *type; - int texnum; - vec3_t org; - vec3_t vel; // velocity of particle, or orientation of decal, or end point of beam - float size; - float alpha; // 0-255 - float alphafade; // how much alpha reduces per second - float time2; // used for snow fluttering and decal fade - float bounce; // how much bounce-back from a surface the particle hits (0 = no physics, 1 = stop and slide, 2 = keep bouncing forever, 1.5 is typical) - float gravity; // how much gravity affects this particle (1.0 = normal gravity, 0.0 = none) - float friction; // how much air friction affects this object (objects with a low mass/size ratio tend to get more air friction) - unsigned char color[4]; - unsigned short owner; // decal stuck to this entity - model_t *ownermodel; // model the decal is stuck to (used to make sure the entity is still alive) - vec3_t relativeorigin; // decal at this location in entity's coordinate space - vec3_t relativedirection; // decal oriented this way relative to entity's coordinate space -} -particle_t; - static int particlepalette[256] = { 0x000000,0x0f0f0f,0x1f1f1f,0x2f2f2f,0x3f3f3f,0x4b4b4b,0x5b5b5b,0x6b6b6b, // 0-7 @@ -304,39 +93,27 @@ static const int tex_bubble = 62; static const int tex_raindrop = 61; static const int tex_beam = 60; -static int cl_maxparticles; -static int cl_numparticles; -static int cl_freeparticle; -static particle_t *particles; - -cvar_t cl_particles = {CVAR_SAVE, "cl_particles", "1"}; -cvar_t cl_particles_quality = {CVAR_SAVE, "cl_particles_quality", "1"}; -cvar_t cl_particles_size = {CVAR_SAVE, "cl_particles_size", "1"}; -cvar_t cl_particles_quake = {CVAR_SAVE, "cl_particles_quake", "0"}; -cvar_t cl_particles_bloodshowers = {CVAR_SAVE, "cl_particles_bloodshowers", "1"}; -cvar_t cl_particles_blood = {CVAR_SAVE, "cl_particles_blood", "1"}; -cvar_t cl_particles_blood_alpha = {CVAR_SAVE, "cl_particles_blood_alpha", "0.5"}; -cvar_t cl_particles_blood_bloodhack = {CVAR_SAVE, "cl_particles_blood_bloodhack", "1"}; -cvar_t cl_particles_bulletimpacts = {CVAR_SAVE, "cl_particles_bulletimpacts", "1"}; -cvar_t cl_particles_explosions_bubbles = {CVAR_SAVE, "cl_particles_explosions_bubbles", "1"}; -cvar_t cl_particles_explosions_smoke = {CVAR_SAVE, "cl_particles_explosions_smokes", "0"}; -cvar_t cl_particles_explosions_sparks = {CVAR_SAVE, "cl_particles_explosions_sparks", "1"}; -cvar_t cl_particles_explosions_shell = {CVAR_SAVE, "cl_particles_explosions_shell", "0"}; -cvar_t cl_particles_smoke = {CVAR_SAVE, "cl_particles_smoke", "1"}; -cvar_t cl_particles_smoke_alpha = {CVAR_SAVE, "cl_particles_smoke_alpha", "0.5"}; -cvar_t cl_particles_smoke_alphafade = {CVAR_SAVE, "cl_particles_smoke_alphafade", "0.55"}; -cvar_t cl_particles_sparks = {CVAR_SAVE, "cl_particles_sparks", "1"}; -cvar_t cl_particles_bubbles = {CVAR_SAVE, "cl_particles_bubbles", "1"}; -cvar_t cl_decals = {CVAR_SAVE, "cl_decals", "0"}; -cvar_t cl_decals_time = {CVAR_SAVE, "cl_decals_time", "0"}; -cvar_t cl_decals_fadetime = {CVAR_SAVE, "cl_decals_fadetime", "20"}; - -void CL_Particles_Clear(void) -{ - cl_numparticles = 0; - cl_freeparticle = 0; - memset(particles, 0, sizeof(particle_t) * cl_maxparticles); -} +cvar_t cl_particles = {CVAR_SAVE, "cl_particles", "1", "enables particle effects"}; +cvar_t cl_particles_quality = {CVAR_SAVE, "cl_particles_quality", "1", "multiplies number of particles and reduces their alpha"}; +cvar_t cl_particles_size = {CVAR_SAVE, "cl_particles_size", "1", "multiplies particle size"}; +cvar_t cl_particles_quake = {CVAR_SAVE, "cl_particles_quake", "0", "makes particle effects look mostly like the ones in Quake"}; +cvar_t cl_particles_bloodshowers = {CVAR_SAVE, "cl_particles_bloodshowers", "1", "enables blood shower effects"}; +cvar_t cl_particles_blood = {CVAR_SAVE, "cl_particles_blood", "1", "enables blood effects"}; +cvar_t cl_particles_blood_alpha = {CVAR_SAVE, "cl_particles_blood_alpha", "0.5", "opacity of blood"}; +cvar_t cl_particles_blood_bloodhack = {CVAR_SAVE, "cl_particles_blood_bloodhack", "1", "make certain quake particle() calls create blood effects instead"}; +cvar_t cl_particles_bulletimpacts = {CVAR_SAVE, "cl_particles_bulletimpacts", "1", "enables bulletimpact effects"}; +cvar_t cl_particles_explosions_bubbles = {CVAR_SAVE, "cl_particles_explosions_bubbles", "1", "enables bubbles from underwater explosions"}; +cvar_t cl_particles_explosions_smoke = {CVAR_SAVE, "cl_particles_explosions_smokes", "0", "enables smoke from explosions"}; +cvar_t cl_particles_explosions_sparks = {CVAR_SAVE, "cl_particles_explosions_sparks", "1", "enables sparks from explosions"}; +cvar_t cl_particles_explosions_shell = {CVAR_SAVE, "cl_particles_explosions_shell", "0", "enables polygonal shell from explosions"}; +cvar_t cl_particles_smoke = {CVAR_SAVE, "cl_particles_smoke", "1", "enables smoke (used by multiple effects)"}; +cvar_t cl_particles_smoke_alpha = {CVAR_SAVE, "cl_particles_smoke_alpha", "0.5", "smoke brightness"}; +cvar_t cl_particles_smoke_alphafade = {CVAR_SAVE, "cl_particles_smoke_alphafade", "0.55", "brightness fade per second"}; +cvar_t cl_particles_sparks = {CVAR_SAVE, "cl_particles_sparks", "1", "enables sparks (used by multiple effects)"}; +cvar_t cl_particles_bubbles = {CVAR_SAVE, "cl_particles_bubbles", "1", "enables bubbles (used by multiple effects)"}; +cvar_t cl_decals = {CVAR_SAVE, "cl_decals", "0", "enables decals (bullet holes, blood, etc)"}; +cvar_t cl_decals_time = {CVAR_SAVE, "cl_decals_time", "0", "how long before decals start to fade away"}; +cvar_t cl_decals_fadetime = {CVAR_SAVE, "cl_decals_fadetime", "20", "how long decals take to fade away"}; /* =============== @@ -346,21 +123,7 @@ CL_InitParticles void CL_ReadPointFile_f (void); void CL_Particles_Init (void) { - int i; - -// COMMANDLINEOPTION: Client: -particles changes maximum number of particles at once, default 32768 - i = COM_CheckParm ("-particles"); - - if (i && i < com_argc - 1) - { - cl_maxparticles = (int)(atoi(com_argv[i+1])); - if (cl_maxparticles < ABSOLUTE_MIN_PARTICLES) - cl_maxparticles = ABSOLUTE_MIN_PARTICLES; - } - else - cl_maxparticles = MAX_PARTICLES; - - Cmd_AddCommand ("pointfile", CL_ReadPointFile_f); + Cmd_AddCommand ("pointfile", CL_ReadPointFile_f, "display point file produced by qbsp when a leak was detected in the map (a line leading through the leak hole, to an entity inside the level)"); Cvar_RegisterVariable (&cl_particles); Cvar_RegisterVariable (&cl_particles_quality); @@ -383,20 +146,10 @@ void CL_Particles_Init (void) Cvar_RegisterVariable (&cl_decals); Cvar_RegisterVariable (&cl_decals_time); Cvar_RegisterVariable (&cl_decals_fadetime); - -#ifdef WORKINGLQUAKE - particles = (particle_t *) Hunk_AllocName(cl_maxparticles * sizeof(particle_t), "particles"); -#else - particles = (particle_t *) Mem_Alloc(cl_mempool, cl_maxparticles * sizeof(particle_t)); -#endif - CL_Particles_Clear(); } void CL_Particles_Shutdown (void) { -#ifdef WORKINGLQUAKE - // No clue what to do here... -#endif } // list of all 26 parameters: @@ -417,12 +170,12 @@ particle_t *particle(particletype_t *ptype, int pcolor1, int pcolor2, int ptex, int l1, l2; particle_t *part; vec3_t v; - for (;cl_freeparticle < cl_maxparticles && particles[cl_freeparticle].type;cl_freeparticle++); - if (cl_freeparticle >= cl_maxparticles) + for (;cl.free_particle < cl.max_particles && cl.particles[cl.free_particle].type;cl.free_particle++); + if (cl.free_particle >= cl.max_particles) return NULL; - part = &particles[cl_freeparticle++]; - if (cl_numparticles < cl_freeparticle) - cl_numparticles = cl_freeparticle; + part = &cl.particles[cl.free_particle++]; + if (cl.num_particles < cl.free_particle) + cl.num_particles = cl.free_particle; memset(part, 0, sizeof(*part)); part->type = ptype; l2 = (int)lhrandom(0.5, 256.5); @@ -458,13 +211,11 @@ void CL_SpawnDecalParticleForSurface(int hitent, const vec3_t org, const vec3_t if (p) { p->time2 = cl.time; -#ifndef WORKINGLQUAKE p->owner = hitent; - p->ownermodel = cl_entities[p->owner].render.model; - Matrix4x4_Transform(&cl_entities[p->owner].render.inversematrix, org, p->relativeorigin); - Matrix4x4_Transform3x3(&cl_entities[p->owner].render.inversematrix, normal, p->relativedirection); + p->ownermodel = cl.entities[p->owner].render.model; + Matrix4x4_Transform(&cl.entities[p->owner].render.inversematrix, org, p->relativeorigin); + Matrix4x4_Transform3x3(&cl.entities[p->owner].render.inversematrix, normal, p->relativedirection); VectorAdd(p->relativeorigin, p->relativedirection, p->relativeorigin); -#endif } } @@ -480,8 +231,10 @@ void CL_SpawnDecalParticleForPoint(const vec3_t org, float maxdist, float size, { VectorRandom(org2); VectorMA(org, maxdist, org2, org2); - trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, &hitent, SUPERCONTENTS_SOLID, false); - if (bestfrac > trace.fraction) + trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, &hitent, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, false); + // take the closest trace result that doesn't end up hitting a NOMARKS + // surface (sky for example) + if (bestfrac > trace.fraction && !(trace.hitq3surfaceflags & Q3SURFACEFLAG_NOMARKS)) { bestfrac = trace.fraction; besthitent = hitent; @@ -505,11 +258,7 @@ void CL_EntityParticles (entity_t *ent) static vec3_t avelocities[NUMVERTEXNORMALS]; if (!cl_particles.integer) return; -#ifdef WORKINGLQUAKE - VectorCopy(ent->origin, org); -#else Matrix4x4_OriginFromMatrix(&ent->render.matrix, org); -#endif if (!avelocities[0][0]) for (i = 0;i < NUMVERTEXNORMALS * 3;i++) @@ -539,11 +288,7 @@ void CL_ReadPointFile_f (void) FS_StripExtension (cl.worldmodel->name, name, sizeof (name)); strlcat (name, ".pts", sizeof (name)); -#if WORKINGLQUAKE - pointfile = COM_LoadTempFile (name); -#else pointfile = (char *)FS_LoadFile(name, tempmempool, true, NULL); -#endif if (!pointfile) { Con_Printf("Could not open %s\n", name); @@ -575,15 +320,13 @@ void CL_ReadPointFile_f (void) VectorCopy(org, leakorg); c++; - if (cl_numparticles < cl_maxparticles - 3) + if (cl.num_particles < cl.max_particles - 3) { s++; particle(particletype + pt_static, particlepalette[(-c)&15], particlepalette[(-c)&15], tex_particle, 2, 255, 0, 0, 0, org[0], org[1], org[2], 0, 0, 0, 0, 0, 0); } } -#ifndef WORKINGLQUAKE Mem_Free(pointfile); -#endif VectorCopy(leakorg, org); Con_Printf("%i points read (%i particles spawned)\nLeak at %f %f %f\n", c, s, org[0], org[1], org[2]); @@ -604,7 +347,7 @@ void CL_ParseParticleEffect (void) vec3_t org, dir; int i, count, msgcount, color; - MSG_ReadVector(org, cl.protocol); + MSG_ReadVector(org, cls.protocol); for (i=0 ; i<3 ; i++) dir[i] = MSG_ReadChar (); msgcount = MSG_ReadByte (); @@ -658,12 +401,12 @@ void CL_ParticleExplosion (vec3_t org) if (i & 1) { color = particlepalette[ramp1[r]]; - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, (1.0f / cl_particles_quality.value) * 32 * (8 - r), (1.0f / cl_particles_quality.value) * 318, 0, 0, org[0], org[1], org[2], 0, 0, 0, -4, 16, 256); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 32 * (8 - r), 318, 0, 0, org[0], org[1], org[2], 0, 0, 0, -4, 16, 256); } else { color = particlepalette[ramp2[r]]; - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, (1.0f / cl_particles_quality.value) * 32 * (8 - r), (1.0f / cl_particles_quality.value) * 478, 0, 0, org[0], org[1], org[2], 0, 0, 0, 1, 16, 256); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 32 * (8 - r), 478, 0, 0, org[0], org[1], org[2], 0, 0, 0, 1, 16, 256); } } } @@ -674,7 +417,7 @@ void CL_ParticleExplosion (vec3_t org) { if (cl_particles.integer && cl_particles_bubbles.integer && cl_particles_explosions_bubbles.integer) for (i = 0;i < 128 * cl_particles_quality.value;i++) - particle(particletype + pt_bubble, 0x404040, 0x808080, tex_bubble, 2, (1.0f / cl_particles_quality.value) * lhrandom(128, 255), (1.0f / cl_particles_quality.value) * 128, -0.125, 1.5, org[0], org[1], org[2], 0, 0, 0, (1.0 / 16.0), 16, 96); + particle(particletype + pt_bubble, 0x404040, 0x808080, tex_bubble, 2, lhrandom(128, 255), 128, -0.125, 1.5, org[0], org[1], org[2], 0, 0, 0, (1.0 / 16.0), 16, 96); } else { @@ -686,11 +429,6 @@ void CL_ParticleExplosion (vec3_t org) { int k; vec3_t v, v2; -#ifdef WORKINGLQUAKE - v2[0] = lhrandom(-48, 48); - v2[1] = lhrandom(-48, 48); - v2[2] = lhrandom(-48, 48); -#else for (k = 0;k < 16;k++) { v[0] = org[0] + lhrandom(-48, 48); @@ -701,7 +439,6 @@ void CL_ParticleExplosion (vec3_t org) break; } VectorSubtract(trace.endpos, org, v2); -#endif VectorScale(v2, 2.0f, v2); particle(particletype + pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 12, 32, 64, 0, 0, org[0], org[1], org[2], v2[0], v2[1], v2[2], 0, 0, 0); } @@ -709,7 +446,7 @@ void CL_ParticleExplosion (vec3_t org) if (cl_particles.integer && cl_particles_sparks.integer && cl_particles_explosions_sparks.integer) for (i = 0;i < 128 * cl_particles_quality.value;i++) - particle(particletype + pt_spark, 0x903010, 0xFFD030, tex_particle, 1.0f, (1.0f / cl_particles_quality.value) * lhrandom(0, 255), (1.0f / cl_particles_quality.value) * 512, 1, 0, org[0], org[1], org[2], 0, 0, 80, 0.2, 0, 256); + particle(particletype + pt_spark, 0x903010, 0xFFD030, tex_particle, 1.0f, lhrandom(0, 255), 512, 1, 0, org[0], org[1], org[2], 0, 0, 80, 0.2, 0, 256); } } @@ -732,9 +469,9 @@ void CL_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength) { k = particlepalette[colorStart + (i % colorLength)]; if (cl_particles_quake.integer) - particle(particletype + pt_static, k, k, tex_particle, 1, (1.0f / cl_particles_quality.value) * 255, (1.0f/cl_particles_quality.value)*850, 0, 0, org[0], org[1], org[2], 0, 0, 0, -4, 8, 256); + particle(particletype + pt_static, k, k, tex_particle, 1, 255, 850, 0, 0, org[0], org[1], org[2], 0, 0, 0, -4, 8, 256); else - particle(particletype + pt_static, k, k, tex_particle, lhrandom(0.5, 1.5), (1.0f / cl_particles_quality.value) * 255, (1.0f/cl_particles_quality.value)*512, 0, 0, org[0], org[1], org[2], 0, 0, 0, lhrandom(1.5, 3), 8, 192); + particle(particletype + pt_static, k, k, tex_particle, lhrandom(0.5, 1.5), 255, 512, 0, 0, org[0], org[1], org[2], 0, 0, 0, lhrandom(1.5, 3), 8, 192); } } @@ -760,12 +497,12 @@ void CL_BlobExplosion (vec3_t org) if (i & 1) { k = particlepalette[66 + rand()%6]; - particle(particletype + pt_static, k, k, tex_particle, 1, (1.0f / cl_particles_quality.value) * lhrandom(182, 255), (1.0f/cl_particles_quality.value)*182, 0, 0, org[0], org[1], org[2], 0, 0, 0, -4, 16, 256); + particle(particletype + pt_static, k, k, tex_particle, 1, lhrandom(182, 255), 182, 0, 0, org[0], org[1], org[2], 0, 0, 0, -4, 16, 256); } else { k = particlepalette[150 + rand()%6]; - particle(particletype + pt_static, k, k, tex_particle, 1, (1.0f / cl_particles_quality.value) * lhrandom(182, 255), (1.0f/cl_particles_quality.value)*182, 0, 0, org[0], org[1], org[2], 0, 0, lhrandom(-256, 256), 0, 16, 0); + particle(particletype + pt_static, k, k, tex_particle, 1, lhrandom(182, 255), 182, 0, 0, org[0], org[1], org[2], 0, 0, lhrandom(-256, 256), 0, 16, 0); } } } @@ -792,7 +529,7 @@ void CL_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) while (count--) { k = particlepalette[color + (rand()&7)]; - particle(particletype + pt_alphastatic, k, k, tex_particle, 1, (1.0f / cl_particles_quality.value) * lhrandom(51, 255), (1.0f / cl_particles_quality.value) * 512, 0, 0.05, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, 8, 0); + particle(particletype + pt_alphastatic, k, k, tex_particle, 1, lhrandom(51, 255), 512, 0, 0.05, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, 8, 0); } } else @@ -802,9 +539,9 @@ void CL_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) { k = particlepalette[color + (rand()&7)]; if (gamemode == GAME_GOODVSBAD2) - particle(particletype + pt_alphastatic, k, k, tex_particle, 5, (1.0f / cl_particles_quality.value) * 255, (1.0f / cl_particles_quality.value) * 300, 0, 0, org[0], org[1], org[2], 0, 0, 0, 0, 8, 10); + particle(particletype + pt_alphastatic, k, k, tex_particle, 5, 255, 300, 0, 0, org[0], org[1], org[2], 0, 0, 0, 0, 8, 10); else - particle(particletype + pt_alphastatic, k, k, tex_particle, 1, (1.0f / cl_particles_quality.value) * 255, (1.0f / cl_particles_quality.value) * 512, 0, 0, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, 8, 15); + particle(particletype + pt_alphastatic, k, k, tex_particle, 1, 255, 512, 0, 0, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, 8, 15); } } } @@ -815,7 +552,7 @@ void CL_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) CL_SparkShower =============== */ -void CL_SparkShower (vec3_t org, vec3_t dir, int count, vec_t gravityscale) +void CL_SparkShower (vec3_t org, vec3_t dir, int count, vec_t gravityscale, vec_t radius) { int k; @@ -828,12 +565,12 @@ void CL_SparkShower (vec3_t org, vec3_t dir, int count, vec_t gravityscale) while(count--) { k = particlepalette[0x68 + (rand() & 7)]; - particle(particletype + pt_spark, k, k, tex_particle, 0.4f, (1.0f / cl_particles_quality.value) * lhrandom(64, 255), (1.0f / cl_particles_quality.value) * 512, gravityscale, 0, org[0], org[1], org[2], dir[0], dir[1], dir[2] + sv_gravity.value * 0.1, 0, 0, 64); + particle(particletype + pt_spark, k, k, tex_particle, 0.4f, lhrandom(64, 255), 512, gravityscale, 0, org[0], org[1], org[2], dir[0], dir[1], dir[2] + sv_gravity.value * 0.1, 0, radius, 64); } } } -void CL_Smoke (vec3_t org, vec3_t dir, int count) +void CL_Smoke (vec3_t org, vec3_t dir, int count, vec_t radius) { vec3_t org2; int k; @@ -851,7 +588,7 @@ void CL_Smoke (vec3_t org, vec3_t dir, int count) org2[1] = org[1] + 0.125f * lhrandom(-count, count); org2[2] = org[2] + 0.125f * lhrandom(-count, count); trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, NULL, SUPERCONTENTS_SOLID, false); - particle(particletype + pt_smoke, 0x101010, 0x202020, tex_smoke[rand()&7], 3, (1.0f / cl_particles_quality.value) * 255, (1.0f / cl_particles_quality.value) * 1024, 0, 0, trace.endpos[0], trace.endpos[1], trace.endpos[2], 0, 0, 0, 0, 0, 8); + particle(particletype + pt_smoke, 0x101010, 0x202020, tex_smoke[rand()&7], 3, 255, 1024, 0, 0, trace.endpos[0], trace.endpos[1], trace.endpos[2], 0, 0, 0, 0, radius, 8); } } } @@ -889,15 +626,15 @@ void CL_BloodPuff (vec3_t org, vec3_t vel, int count) count *= 5.0f; if (count > 1000) count = 1000; - bloodcount += count; + bloodcount += count * cl_particles_quality.value; while(bloodcount > 0) { org2[0] = org[0] + 0.125f * lhrandom(-bloodcount, bloodcount); org2[1] = org[1] + 0.125f * lhrandom(-bloodcount, bloodcount); org2[2] = org[2] + 0.125f * lhrandom(-bloodcount, bloodcount); trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, NULL, SUPERCONTENTS_SOLID, false); - particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, cl_particles_blood_alpha.value * 768 / cl_particles_quality.value, cl_particles_blood_alpha.value * 384 / cl_particles_quality.value, 0, -1, trace.endpos[0], trace.endpos[1], trace.endpos[2], vel[0], vel[1], vel[2], 1, 0, s); - bloodcount -= 16 / cl_particles_quality.value; + particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, cl_particles_blood_alpha.value * 768, cl_particles_blood_alpha.value * 384, 0, -1, trace.endpos[0], trace.endpos[1], trace.endpos[2], vel[0], vel[1], vel[2], 1, 0, s); + bloodcount -= 16; } } @@ -916,7 +653,7 @@ void CL_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count) velscale[1] = velspeed * 2.0 / diff[1]; velscale[2] = velspeed * 2.0 / diff[2]; - bloodcount += count * 5.0f; + bloodcount += count * 5.0f * cl_particles_quality.value; while (bloodcount > 0) { org[0] = lhrandom(mins[0], maxs[0]); @@ -925,8 +662,8 @@ void CL_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count) vel[0] = (org[0] - center[0]) * velscale[0]; vel[1] = (org[1] - center[1]) * velscale[1]; vel[2] = (org[2] - center[2]) * velscale[2]; - bloodcount -= 16 / cl_particles_quality.value; - particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, cl_particles_blood_alpha.value * 768 / cl_particles_quality.value, cl_particles_blood_alpha.value * 384 / cl_particles_quality.value, 0, -1, org[0], org[1], org[2], vel[0], vel[1], vel[2], 1, 0, 0); + bloodcount -= 16; + particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, cl_particles_blood_alpha.value * 768, cl_particles_blood_alpha.value * 384, 0, -1, org[0], org[1], org[2], vel[0], vel[1], vel[2], 1, 0, 0); } } @@ -943,7 +680,7 @@ void CL_ParticleCube (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int color while (count--) { k = particlepalette[colorbase + (rand()&3)]; - particle(particletype + pt_alphastatic, k, k, tex_particle, 2, 255 / cl_particles_quality.value, (255 / cl_particles_quality.value) / 2, gravity ? 1 : 0, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), dir[0], dir[1], dir[2], 0, 0, randomvel); + particle(particletype + pt_alphastatic, k, k, tex_particle, 2, 255, 128, gravity ? 1 : 0, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), dir[0], dir[1], dir[2], 0, 0, randomvel); } } @@ -977,9 +714,9 @@ void CL_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int color { k = particlepalette[colorbase + (rand()&3)]; if (gamemode == GAME_GOODVSBAD2) - particle(particletype + pt_rain, k, k, tex_particle, 20, lhrandom(8, 16) / cl_particles_quality.value, 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0); + particle(particletype + pt_rain, k, k, tex_particle, 20, lhrandom(8, 16), 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0); else - particle(particletype + pt_rain, k, k, tex_particle, 0.5, lhrandom(8, 16) / cl_particles_quality.value, 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0); + particle(particletype + pt_rain, k, k, tex_particle, 0.5, lhrandom(8, 16), 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0); } break; case 1: @@ -987,9 +724,9 @@ void CL_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int color { k = particlepalette[colorbase + (rand()&3)]; if (gamemode == GAME_GOODVSBAD2) - p = particle(particletype + pt_snow, k, k, tex_particle, 20, lhrandom(64, 128) / cl_particles_quality.value, 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0); + p = particle(particletype + pt_snow, k, k, tex_particle, 20, lhrandom(64, 128), 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0); else - p = particle(particletype + pt_snow, k, k, tex_particle, 1, lhrandom(64, 128) / cl_particles_quality.value, 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0); + p = particle(particletype + pt_snow, k, k, tex_particle, 1, lhrandom(64, 128), 0, 0, -1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(minz, maxz), dir[0], dir[1], dir[2], 0, 0, 0); if (p) VectorCopy(p->vel, p->relativedirection); } @@ -1025,7 +762,7 @@ void CL_Stardust (vec3_t mins, vec3_t maxs, int count) VectorNormalize(v); VectorScale(v, 100, v); v[2] += sv_gravity.value * 0.15f; - particle(particletype + pt_static, 0x903010, 0xFFD030, tex_particle, 1.5, lhrandom(64, 128) / cl_particles_quality.value, 128 / cl_particles_quality.value, 1, 0, o[0], o[1], o[2], v[0], v[1], v[2], 0.2, 0, 0); + particle(particletype + pt_static, 0x903010, 0xFFD030, tex_particle, 1.5, lhrandom(64, 128), 128, 1, 0, o[0], o[1], o[2], v[0], v[1], v[2], 0.2, 0, 0); } } @@ -1042,9 +779,9 @@ void CL_FlameCube (vec3_t mins, vec3_t maxs, int count) while (count--) { k = particlepalette[224 + (rand()&15)]; - particle(particletype + pt_static, k, k, tex_particle, 4, lhrandom(64, 128) / cl_particles_quality.value, 384 / cl_particles_quality.value, -1, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), 0, 0, 32, 1, 0, 32); + particle(particletype + pt_static, k, k, tex_particle, 4, lhrandom(64, 128), 384, -1, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), 0, 0, 32, 1, 0, 32); if (count & 1) - particle(particletype + pt_static, 0x303030, 0x606060, tex_smoke[rand()&7], 6, lhrandom(48, 96) / cl_particles_quality.value, 64 / cl_particles_quality.value, 0, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), 0, 0, 24, 0, 0, 8); + particle(particletype + pt_static, 0x303030, 0x606060, tex_smoke[rand()&7], 6, lhrandom(48, 96), 64, 0, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), 0, 0, 24, 0, 0, 8); } } @@ -1057,7 +794,7 @@ void CL_Flames (vec3_t org, vec3_t vel, int count) while (count--) { k = particlepalette[224 + (rand()&15)]; - particle(particletype + pt_static, k, k, tex_particle, 4, lhrandom(64, 128) / cl_particles_quality.value, 384 / cl_particles_quality.value, -1, 1.1, org[0], org[1], org[2], vel[0], vel[1], vel[2], 1, 0, 128); + particle(particletype + pt_static, k, k, tex_particle, 4, lhrandom(64, 128), 384, -1, 1.1, org[0], org[1], org[2], vel[0], vel[1], vel[2], 1, 0, 128); } } @@ -1165,18 +902,11 @@ void CL_TeleportSplash (vec3_t org) } } -#ifdef WORKINGLQUAKE -void R_RocketTrail (vec3_t start, vec3_t end, int type) -#else void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *ent) -#endif { vec3_t vec, dir, vel, pos; float len, dec, speed, qd; int smoke, blood, bubbles, r; -#ifdef WORKINGLQUAKE - int contents; -#endif if (end[0] == start[0] && end[1] == start[1] && end[2] == start[2]) return; @@ -1185,12 +915,6 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en VectorNormalize(dir); VectorSubtract (end, start, vec); -#ifdef WORKINGLQUAKE - len = VectorNormalize (vec); - dec = 0; - speed = 1.0f / cl.frametime; - VectorSubtract(end, start, vel); -#else len = VectorNormalizeLength (vec); dec = -ent->persistent.trail_time; ent->persistent.trail_time += len; @@ -1205,7 +929,6 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en speed = 1.0f / speed; VectorSubtract(ent->state_current.origin, ent->state_previous.origin, vel); color = particlepalette[color]; -#endif VectorScale(vel, speed, vel); // advance into this frame to reach the first puff location @@ -1214,12 +937,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en smoke = cl_particles.integer && cl_particles_smoke.integer; blood = cl_particles.integer && cl_particles_blood.integer; -#ifdef WORKINGLQUAKE - contents = CL_PointQ1Contents(pos); - bubbles = cl_particles.integer && cl_particles_bubbles.integer && (contents == CONTENTS_WATER || contents == CONTENTS_SLIME); -#else bubbles = cl_particles.integer && cl_particles_bubbles.integer && (CL_PointSuperContents(pos) & (SUPERCONTENTS_WATER | SUPERCONTENTS_SLIME)); -#endif qd = 1.0f / cl_particles_quality.value; while (len >= 0) @@ -1229,37 +947,37 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en case 0: // rocket trail if (cl_particles_quake.integer) { - dec = qd*3; + dec = 3; r = rand()&3; color = particlepalette[ramp3[r]]; - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*42*(6-r), qd*306, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 42*(6-r), 306, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0); } else { - dec = qd*3; + dec = 3; if (smoke) { - particle(particletype + pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*62, qd*cl_particles_smoke_alphafade.value*62, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); - particle(particletype + pt_static, 0x801010, 0xFFA020, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*288, qd*cl_particles_smoke_alphafade.value*1400, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 20); + particle(particletype + pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, cl_particles_smoke_alpha.value*62, cl_particles_smoke_alphafade.value*62, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); + particle(particletype + pt_static, 0x801010, 0xFFA020, tex_smoke[rand()&7], 3, cl_particles_smoke_alpha.value*288, cl_particles_smoke_alphafade.value*1400, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 20); } if (bubbles) - particle(particletype + pt_bubble, 0x404040, 0x808080, tex_bubble, 2, qd*lhrandom(64, 255), qd*256, -0.25, 1.5, pos[0], pos[1], pos[2], 0, 0, 0, (1.0 / 16.0), 0, 16); + particle(particletype + pt_bubble, 0x404040, 0x808080, tex_bubble, 2, lhrandom(64, 255), 256, -0.25, 1.5, pos[0], pos[1], pos[2], 0, 0, 0, (1.0 / 16.0), 0, 16); } break; case 1: // grenade trail if (cl_particles_quake.integer) { - dec = qd*3; + dec = 3; r = 2 + (rand()%5); color = particlepalette[ramp3[r]]; - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*42*(6-r), qd*306, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 42*(6-r), 306, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0); } else { - dec = qd*3; + dec = 3; if (smoke) - particle(particletype + pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, qd*cl_particles_smoke_alpha.value*50, qd*cl_particles_smoke_alphafade.value*50, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); + particle(particletype + pt_smoke, 0x303030, 0x606060, tex_smoke[rand()&7], 3, cl_particles_smoke_alpha.value*50, cl_particles_smoke_alphafade.value*50, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); } break; @@ -1270,20 +988,20 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en { if (type == 2) { - dec = qd*3; + dec = 3; color = particlepalette[67 + (rand()&3)]; - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*128, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 255, 128, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0); } else { - dec = qd*6; + dec = 6; color = particlepalette[67 + (rand()&3)]; - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*128, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 255, 128, 0, -0.05, pos[0], pos[1], pos[2], 0, 0, 0, 0, 3, 0); } } else { - dec = qd*16; + dec = 16; if (blood) particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, qd * cl_particles_blood_alpha.value * 768.0f, qd * cl_particles_blood_alpha.value * 384.0f, 0, -1, pos[0], pos[1], pos[2], vel[0] * 0.5f, vel[1] * 0.5f, vel[2] * 0.5f, 1, 0, 64); } @@ -1292,26 +1010,26 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en case 3: // green tracer if (cl_particles_quake.integer) { - dec = qd*6; + dec = 6; color = particlepalette[52 + (rand()&7)]; - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*512, 0, 0, pos[0], pos[1], pos[2], 30*vec[1], 30*-vec[0], 0, 0, 0, 0); - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*512, 0, 0, pos[0], pos[1], pos[2], 30*-vec[1], 30*vec[0], 0, 0, 0, 0); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 255, 512, 0, 0, pos[0], pos[1], pos[2], 30*vec[1], 30*-vec[0], 0, 0, 0, 0); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 255, 512, 0, 0, pos[0], pos[1], pos[2], 30*-vec[1], 30*vec[0], 0, 0, 0, 0); } else { - dec = qd*16; + dec = 16; if (smoke) { if (gamemode == GAME_GOODVSBAD2) { - dec = qd*6; - particle(particletype + pt_static, 0x00002E, 0x000030, tex_particle, 6, qd*128, qd*384, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); + dec = 6; + particle(particletype + pt_static, 0x00002E, 0x000030, tex_particle, 6, 128, 384, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); } else { - dec = qd*3; + dec = 3; color = particlepalette[20 + (rand()&7)]; - particle(particletype + pt_static, color, color, tex_particle, 2, qd*64, qd*192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); + particle(particletype + pt_static, color, color, tex_particle, 2, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); } } } @@ -1320,18 +1038,18 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en case 5: // flame tracer if (cl_particles_quake.integer) { - dec = qd*6; + dec = 6; color = particlepalette[230 + (rand()&7)]; - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*512, 0, 0, pos[0], pos[1], pos[2], 30*vec[1], 30*-vec[0], 0, 0, 0, 0); - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*512, 0, 0, pos[0], pos[1], pos[2], 30*-vec[1], 30*vec[0], 0, 0, 0, 0); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 255, 512, 0, 0, pos[0], pos[1], pos[2], 30*vec[1], 30*-vec[0], 0, 0, 0, 0); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 255, 512, 0, 0, pos[0], pos[1], pos[2], 30*-vec[1], 30*vec[0], 0, 0, 0, 0); } else { - dec = qd*3; + dec = 3; if (smoke) { color = particlepalette[226 + (rand()&7)]; - particle(particletype + pt_static, color, color, tex_particle, 2, qd*64, qd*192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); + particle(particletype + pt_static, color, color, tex_particle, 2, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); } } break; @@ -1339,61 +1057,58 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en case 6: // voor trail if (cl_particles_quake.integer) { - dec = qd*3; + dec = 3; color = particlepalette[152 + (rand()&3)]; - particle(particletype + pt_alphastatic, color, color, tex_particle, 1, qd*255, qd*850, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 8, 0); + particle(particletype + pt_alphastatic, color, color, tex_particle, 1, 255, 850, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 8, 0); } else { - dec = qd*16; + dec = 16; if (smoke) { if (gamemode == GAME_GOODVSBAD2) { - dec = qd*6; - particle(particletype + pt_alphastatic, particlepalette[0 + (rand()&255)], particlepalette[0 + (rand()&255)], tex_particle, 6, qd*255, qd*384, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); + dec = 6; + particle(particletype + pt_alphastatic, particlepalette[0 + (rand()&255)], particlepalette[0 + (rand()&255)], tex_particle, 6, 255, 384, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); } else if (gamemode == GAME_PRYDON) { - dec = qd*6; - particle(particletype + pt_static, 0x103040, 0x204050, tex_particle, 6, qd*64, qd*192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); + dec = 6; + particle(particletype + pt_static, 0x103040, 0x204050, tex_particle, 6, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); } else { - dec = qd*3; - particle(particletype + pt_static, 0x502030, 0x502030, tex_particle, 3, qd*64, qd*192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); + dec = 3; + particle(particletype + pt_static, 0x502030, 0x502030, tex_particle, 3, 64, 192, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); } } } break; -#ifndef WORKINGLQUAKE case 7: // Nehahra smoke tracer - dec = qd*7; + dec = 7; if (smoke) - particle(particletype + pt_alphastatic, 0x303030, 0x606060, tex_smoke[rand()&7], 7, qd*64, qd*320, 0, 0, pos[0], pos[1], pos[2], 0, 0, lhrandom(4, 12), 0, 0, 4); + particle(particletype + pt_alphastatic, 0x303030, 0x606060, tex_smoke[rand()&7], 7, 64, 320, 0, 0, pos[0], pos[1], pos[2], 0, 0, lhrandom(4, 12), 0, 0, 4); break; case 8: // Nexuiz plasma trail - dec = qd*4; + dec = 4; if (smoke) - particle(particletype + pt_static, 0x283880, 0x283880, tex_particle, 4, qd*255, qd*1024, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 16); + particle(particletype + pt_static, 0x283880, 0x283880, tex_particle, 4, 255, 1024, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 16); break; case 9: // glow trail - dec = qd*3; + dec = 3; if (smoke) - particle(particletype + pt_alphastatic, color, color, tex_particle, 5, qd*128, qd*320, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); + particle(particletype + pt_alphastatic, color, color, tex_particle, 5, 128, 320, 0, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0); break; -#endif default: Sys_Error("CL_RocketTrail: unknown trail type %i", type); } // advance to next time and position + dec *= qd; len -= dec; VectorMA (pos, dec, vec, pos); } -#ifndef WORKINGLQUAKE ent->persistent.trail_time = len; -#endif } void CL_BeamParticle (const vec3_t start, const vec3_t end, vec_t radius, float red, float green, float blue, float alpha, float lifetime) @@ -1414,7 +1129,7 @@ void CL_Tei_Smoke(const vec3_t org, const vec3_t dir, int count) // smoke puff if (cl_particles_smoke.integer) for (f = 0;f < count;f += 4.0f / cl_particles_quality.value) - particle(particletype + pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 5, 255 / cl_particles_quality.value, 512 / cl_particles_quality.value, 0, 0, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, count * 0.125f, count * 0.5f); + particle(particletype + pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 5, 255, 512, 0, 0, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, count * 0.125f, count * 0.5f); } void CL_Tei_PlasmaHit(const vec3_t org, const vec3_t dir, int count) @@ -1429,12 +1144,12 @@ void CL_Tei_PlasmaHit(const vec3_t org, const vec3_t dir, int count) // smoke puff if (cl_particles_smoke.integer) for (f = 0;f < count;f += 4.0f / cl_particles_quality.value) - particle(particletype + pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 5, 255 / cl_particles_quality.value, 512 / cl_particles_quality.value, 0, 0, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, count * 0.125f, count); + particle(particletype + pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 5, 255, 512, 0, 0, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, count * 0.125f, count); // sparks if (cl_particles_sparks.integer) for (f = 0;f < count;f += 1.0f / cl_particles_quality.value) - particle(particletype + pt_spark, 0x2030FF, 0x80C0FF, tex_particle, 2.0f, lhrandom(64, 255) / cl_particles_quality.value, 512 / cl_particles_quality.value, 0, 0, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, 0, count * 3.0f); + particle(particletype + pt_spark, 0x2030FF, 0x80C0FF, tex_particle, 2.0f, lhrandom(64, 255), 512, 0, 0, org[0], org[1], org[2], dir[0], dir[1], dir[2], 0, 0, count * 3.0f); } /* @@ -1451,24 +1166,20 @@ void CL_MoveParticles (void) trace_t trace; // LordHavoc: early out condition - if (!cl_numparticles) + if (!cl.num_particles) { - cl_freeparticle = 0; + cl.free_particle = 0; return; } -#ifdef WORKINGLQUAKE - frametime = cl.frametime; -#else frametime = cl.time - cl.oldtime; -#endif gravity = frametime * sv_gravity.value; dvel = 1+4*frametime; bloodwaterfade = max(cl_particles_blood_alpha.value, 0.01f) * frametime * 128.0f; maxparticle = -1; j = 0; - for (i = 0, p = particles;i < cl_numparticles;i++, p++) + for (i = 0, p = cl.particles;i < cl.num_particles;i++, p++) { if (!p->type) continue; @@ -1490,14 +1201,24 @@ void CL_MoveParticles (void) VectorCopy(p->org, org); if (p->bounce) { - if (p->type == particletype + pt_rain) + trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, &hitent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | (p->type == particletype + pt_rain ? SUPERCONTENTS_LIQUIDSMASK : 0), false); + // if the trace started in or hit something of SUPERCONTENTS_NODROP + // or if the trace hit something flagged as NOIMPACT + // then remove the particle + if (trace.hitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT || ((trace.startsupercontents | trace.hitsupercontents) & SUPERCONTENTS_NODROP)) { - // raindrop - splash on solid/water/slime/lava - trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK, false); - if (trace.fraction < 1) + p->type = NULL; + continue; + } + // react if the particle hit something + if (trace.fraction < 1) + { + VectorCopy(trace.endpos, p->org); + if (p->type == particletype + pt_rain) { + // raindrop - splash on solid/water/slime/lava + int count; // convert from a raindrop particle to a rainsplash decal - VectorCopy(trace.endpos, p->org); VectorCopy(trace.plane.normal, p->vel); VectorAdd(p->org, p->vel, p->org); p->type = particletype + pt_raindecal; @@ -1508,36 +1229,35 @@ void CL_MoveParticles (void) p->friction = 0; p->gravity = 0; p->size = 8.0; + count = rand() & 3; + while(count--) + particle(particletype + pt_spark, 0x000000, 0x707070, tex_particle, 0.25f, lhrandom(64, 255), 512, 1, 0, p->org[0], p->org[1], p->org[2], p->vel[0]*16, p->vel[1]*16, 32 + p->vel[2]*16, 0, 0, 32); } - } - else if (p->type == particletype + pt_blood) - { - // blood - splash on solid - trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, &hitent, SUPERCONTENTS_SOLID, false); - if (trace.fraction < 1) + else if (p->type == particletype + pt_blood) { - // convert from a blood particle to a blood decal - VectorCopy(trace.endpos, p->org); - VectorCopy(trace.plane.normal, p->vel); - VectorAdd(p->org, p->vel, p->org); -#ifndef WORKINGLQUAKE - if (cl_stainmaps.integer) - R_Stain(p->org, 32, 32, 16, 16, p->alpha * p->size * (1.0f / 40.0f), 192, 48, 48, p->alpha * p->size * (1.0f / 40.0f)); -#endif + // blood - splash on solid + if (trace.hitq3surfaceflags & Q3SURFACEFLAG_NOMARKS) + { + p->type = NULL; + continue; + } if (!cl_decals.integer) { p->type = NULL; continue; } + // convert from a blood particle to a blood decal + VectorCopy(trace.plane.normal, p->vel); + VectorAdd(p->org, p->vel, p->org); + if (cl_stainmaps.integer) + R_Stain(p->org, 32, 32, 16, 16, p->alpha * p->size * (1.0f / 40.0f), 192, 48, 48, p->alpha * p->size * (1.0f / 40.0f)); p->type = particletype + pt_decal; p->texnum = tex_blooddecal[rand()&7]; -#ifndef WORKINGLQUAKE p->owner = hitent; - p->ownermodel = cl_entities[hitent].render.model; - Matrix4x4_Transform(&cl_entities[hitent].render.inversematrix, p->org, p->relativeorigin); - Matrix4x4_Transform3x3(&cl_entities[hitent].render.inversematrix, p->vel, p->relativedirection); -#endif + p->ownermodel = cl.entities[hitent].render.model; + Matrix4x4_Transform(&cl.entities[hitent].render.inversematrix, p->org, p->relativeorigin); + Matrix4x4_Transform3x3(&cl.entities[hitent].render.inversematrix, p->vel, p->relativedirection); p->time2 = cl.time; p->alphafade = 0; p->bounce = 0; @@ -1545,25 +1265,19 @@ void CL_MoveParticles (void) p->gravity = 0; p->size *= 2.0f; } - } - else - { - trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, NULL, SUPERCONTENTS_SOLID, false); - if (trace.fraction < 1) + else if (p->bounce < 0) { - VectorCopy(trace.endpos, p->org); - if (p->bounce < 0) - { - p->type = NULL; - continue; - } - else - { - dist = DotProduct(p->vel, trace.plane.normal) * -p->bounce; - VectorMA(p->vel, dist, trace.plane.normal, p->vel); - if (DotProduct(p->vel, p->vel) < 0.03) - VectorClear(p->vel); - } + // bounce -1 means remove on impact + p->type = NULL; + continue; + } + else + { + // anything else - bounce off solid + dist = DotProduct(p->vel, trace.plane.normal) * -p->bounce; + VectorMA(p->vel, dist, trace.plane.normal, p->vel); + if (DotProduct(p->vel, p->vel) < 0.03) + VectorClear(p->vel); } } } @@ -1572,11 +1286,7 @@ void CL_MoveParticles (void) if (p->friction) { f = p->friction * frametime; -#ifdef WORKINGLQUAKE - if (CL_PointQ1Contents(p->org) != CONTENTS_EMPTY) -#else if (CL_PointSuperContents(p->org) & SUPERCONTENTS_LIQUIDSMASK) -#endif f *= 4; f = 1.0f - f; VectorScale(p->vel, f, p->vel); @@ -1595,47 +1305,28 @@ void CL_MoveParticles (void) p->time2 = 1; break; case pt_blood: -#ifdef WORKINGLQUAKE - a = CL_PointQ1Contents(p->org); - if (a <= CONTENTS_WATER) -#else a = CL_PointSuperContents(p->org); if (a & (SUPERCONTENTS_WATER | SUPERCONTENTS_SLIME)) -#endif { p->size += frametime * 8; //p->alpha -= bloodwaterfade; } else p->vel[2] -= gravity; -#ifdef WORKINGLQUAKE - if (a == CONTENTS_SOLID || a == CONTENTS_LAVA) -#else if (a & (SUPERCONTENTS_SOLID | SUPERCONTENTS_LAVA | SUPERCONTENTS_NODROP)) -#endif p->type = NULL; break; case pt_bubble: -#ifdef WORKINGLQUAKE - a = CL_PointQ1Contents(p->org); - if (a != CONTENTS_WATER && a != CONTENTS_SLIME) -#else a = CL_PointSuperContents(p->org); if (!(a & (SUPERCONTENTS_WATER | SUPERCONTENTS_SLIME))) -#endif { p->type = NULL; break; } break; case pt_rain: -#ifdef WORKINGLQUAKE - a = CL_PointQ1Contents(p->org); - if (a != CONTENTS_EMPTY && a != CONTENTS_SKY) -#else a = CL_PointSuperContents(p->org); - if (a & (SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK)) -#endif + if (a & (SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_LIQUIDSMASK)) p->type = NULL; break; case pt_snow: @@ -1647,13 +1338,8 @@ void CL_MoveParticles (void) p->vel[1] = p->relativedirection[1] + lhrandom(-32, 32); //p->vel[2] = p->relativedirection[2] + lhrandom(-32, 32); } -#ifdef WORKINGLQUAKE - a = CL_PointQ1Contents(p->org); - if (a != CONTENTS_EMPTY && a != CONTENTS_SKY) -#else a = CL_PointSuperContents(p->org); - if (a & (SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK)) -#endif + if (a & (SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_LIQUIDSMASK)) p->type = NULL; break; case pt_smoke: @@ -1662,15 +1348,13 @@ void CL_MoveParticles (void) case pt_decal: // FIXME: this has fairly wacky handling of alpha p->alphafade = cl.time > (p->time2 + cl_decals_time.value) ? (255 / cl_decals_fadetime.value) : 0; -#ifndef WORKINGLQUAKE - if (cl_entities[p->owner].render.model == p->ownermodel) + if (cl.entities[p->owner].render.model == p->ownermodel) { - Matrix4x4_Transform(&cl_entities[p->owner].render.matrix, p->relativeorigin, p->org); - Matrix4x4_Transform3x3(&cl_entities[p->owner].render.matrix, p->relativedirection, p->vel); + Matrix4x4_Transform(&cl.entities[p->owner].render.matrix, p->relativeorigin, p->org); + Matrix4x4_Transform3x3(&cl.entities[p->owner].render.matrix, p->relativedirection, p->vel); } else p->type = NULL; -#endif break; case pt_raindecal: a = max(0, (cl.time - p->time2) * 40); @@ -1684,8 +1368,8 @@ void CL_MoveParticles (void) } } } - cl_numparticles = maxparticle + 1; - cl_freeparticle = 0; + cl.num_particles = maxparticle + 1; + cl.free_particle = 0; } #define MAX_PARTICLETEXTURES 64 @@ -1697,15 +1381,11 @@ typedef struct particletexture_s } particletexture_t; -#if WORKINGLQUAKE -static int particlefonttexture; -#else static rtexturepool_t *particletexturepool; static rtexture_t *particlefonttexture; -#endif static particletexture_t particletexture[MAX_PARTICLETEXTURES]; -static cvar_t r_drawparticles = {0, "r_drawparticles", "1"}; +static cvar_t r_drawparticles = {0, "r_drawparticles", "1", "enables drawing of particles"}; #define PARTICLETEXTURESIZE 64 #define PARTICLEFONTSIZE (PARTICLETEXTURESIZE*8) @@ -1977,12 +1657,6 @@ static void R_InitParticleTexture (void) setuptex(tex_bulletdecal[i], &data[0][0][0], particletexturedata); } -#if WORKINGLQUAKE - glBindTexture(GL_TEXTURE_2D, (particlefonttexture = gl_extension_number++)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -#else - #if 0 Image_WriteTGARGBA ("particles/particlefont.tga", PARTICLEFONTSIZE, PARTICLEFONTSIZE, particletexturedata); #endif @@ -2019,7 +1693,6 @@ static void R_InitParticleTexture (void) particletexture[tex_beam].t1 = 0; particletexture[tex_beam].s2 = 1; particletexture[tex_beam].t2 = 1; -#endif Mem_Free(particletexturedata); } @@ -2036,39 +1709,20 @@ static void r_part_shutdown(void) static void r_part_newmap(void) { - cl_numparticles = 0; - cl_freeparticle = 0; } void R_Particles_Init (void) { Cvar_RegisterVariable(&r_drawparticles); -#ifdef WORKINGLQUAKE - r_part_start(); -#else R_RegisterModule("R_Particles", r_part_start, r_part_shutdown, r_part_newmap); -#endif -} - -#ifdef WORKINGLQUAKE -void R_InitParticles(void) -{ - CL_Particles_Init(); - R_Particles_Init(); } -#endif float particle_vertex3f[12], particle_texcoord2f[8]; -#ifdef WORKINGLQUAKE -void R_DrawParticle(particle_t *p) -{ -#else -void R_DrawParticleCallback(const void *calldata1, int calldata2) +void R_DrawParticle_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) { - const particle_t *p = (particle_t *)calldata1; + const particle_t *p = cl.particles + surfacenumber; rmeshstate_t m; -#endif pblend_t blendmode; float org[3], up2[3], v[3], right[3], up[3], fog, ifog, cr, cg, cb, ca, size; particletexture_t *tex; @@ -2091,7 +1745,7 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) cb = min(cb, 1); ca = 1; } -#ifndef WORKINGLQUAKE + ca /= cl_particles_quality.value; if (p->type->lighting) { float ambient[3], diffuse[3], diffusenormal[3]; @@ -2115,7 +1769,7 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) } } - R_Mesh_Matrix(&r_identitymatrix); + R_Mesh_Matrix(&identitymatrix); memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(tex->texture); @@ -2133,7 +1787,6 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) GL_BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); GL_DepthMask(false); GL_DepthTest(true); -#endif size = p->size * cl_particles_size.value; if (p->type->orientation == PARTICLE_BILLBOARD || p->type->orientation == PARTICLE_ORIENTED_DOUBLESIDED) { @@ -2200,23 +1853,7 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) return; } -#if WORKINGLQUAKE - if (blendmode == PBLEND_ALPHA) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - else if (blendmode == PBLEND_ADD) - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - else //if (blendmode == PBLEND_MOD) - glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - glColor4f(cr, cg, cb, ca); - glBegin(GL_QUADS); - glTexCoord2f(particle_texcoord2f[0], particle_texcoord2f[1]);glVertex3f(particle_vertex3f[ 0], particle_vertex3f[ 1], particle_vertex3f[ 2]); - glTexCoord2f(particle_texcoord2f[2], particle_texcoord2f[3]);glVertex3f(particle_vertex3f[ 3], particle_vertex3f[ 4], particle_vertex3f[ 5]); - glTexCoord2f(particle_texcoord2f[4], particle_texcoord2f[5]);glVertex3f(particle_vertex3f[ 6], particle_vertex3f[ 7], particle_vertex3f[ 8]); - glTexCoord2f(particle_texcoord2f[6], particle_texcoord2f[7]);glVertex3f(particle_vertex3f[ 9], particle_vertex3f[10], particle_vertex3f[11]); - glEnd(); -#else R_Mesh_Draw(0, 4, 2, polygonelements); -#endif } void R_DrawParticles (void) @@ -2225,31 +1862,14 @@ void R_DrawParticles (void) float minparticledist; particle_t *p; -#ifdef WORKINGLQUAKE - CL_MoveParticles(); -#endif - // LordHavoc: early out conditions - if ((!cl_numparticles) || (!r_drawparticles.integer)) + if ((!cl.num_particles) || (!r_drawparticles.integer)) return; minparticledist = DotProduct(r_vieworigin, r_viewforward) + 4.0f; -#ifdef WORKINGLQUAKE - glBindTexture(GL_TEXTURE_2D, particlefonttexture); - glEnable(GL_BLEND); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glDepthMask(0); // LordHavoc: only render if not too close - for (i = 0, p = particles;i < cl_numparticles;i++, p++) - if (p->type && DotProduct(p->org, r_viewforward) >= minparticledist) - R_DrawParticle(p); - glDepthMask(1); - glDisable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -#else - // LordHavoc: only render if not too close - for (i = 0, p = particles;i < cl_numparticles;i++, p++) + for (i = 0, p = cl.particles;i < cl.num_particles;i++, p++) { if (p->type) { @@ -2257,12 +1877,11 @@ void R_DrawParticles (void) if (DotProduct(p->org, r_viewforward) >= minparticledist || p->type->orientation == PARTICLE_BEAM) { if (p->type == particletype + pt_decal) - R_DrawParticleCallback(p, 0); + R_DrawParticle_TransparentCallback(0, i, 0); else - R_MeshQueue_AddTransparent(p->org, R_DrawParticleCallback, p, 0); + R_MeshQueue_AddTransparent(p->org, R_DrawParticle_TransparentCallback, NULL, i, NULL); } } } -#endif }