diff --git a/include/QF/plugin/vid_render.h b/include/QF/plugin/vid_render.h index 8ed240c84..57e72a92f 100644 --- a/include/QF/plugin/vid_render.h +++ b/include/QF/plugin/vid_render.h @@ -45,38 +45,36 @@ struct mod_sprite_ctx_s; */ typedef struct vid_particle_funcs_s { - void (*R_RocketTrail) (const struct entity_s *ent); - void (*R_GrenadeTrail) (const struct entity_s *ent); - void (*R_BloodTrail) (const struct entity_s *ent); - void (*R_SlightBloodTrail) (const struct entity_s *ent); - void (*R_WizTrail) (const struct entity_s *ent); - void (*R_FlameTrail) (const struct entity_s *ent); - void (*R_VoorTrail) (const struct entity_s *ent); - void (*R_GlowTrail) (const struct entity_s *ent, int glow_color); + void (*R_RocketTrail) (vec4f_t start, vec4f_t end); + void (*R_GrenadeTrail) (vec4f_t start, vec4f_t end); + void (*R_BloodTrail) (vec4f_t start, vec4f_t end); + void (*R_SlightBloodTrail) (vec4f_t start, vec4f_t end); + void (*R_WizTrail) (vec4f_t start, vec4f_t end); + void (*R_FlameTrail) (vec4f_t start, vec4f_t end); + void (*R_VoorTrail) (vec4f_t start, vec4f_t end); + void (*R_GlowTrail) (vec4f_t start, vec4f_t end, int glow_color); - void (*R_RunParticleEffect) (const vec3_t org, const vec3_t dir, - int color, int count); - void (*R_BloodPuffEffect) (const vec3_t org, int count); - void (*R_GunshotEffect) (const vec3_t org, int count); - void (*R_LightningBloodEffect) (const vec3_t org); - void (*R_SpikeEffect) (const vec3_t org); - void (*R_KnightSpikeEffect) (const vec3_t org); - void (*R_SuperSpikeEffect) (const vec3_t org); - void (*R_WizSpikeEffect) (const vec3_t org); + void (*R_RunParticleEffect) (vec4f_t org, vec4f_t dir, int color, int count); + void (*R_BloodPuffEffect) (vec4f_t org, int count); + void (*R_GunshotEffect) (vec4f_t org, int count); + void (*R_LightningBloodEffect) (vec4f_t org); + void (*R_SpikeEffect) (vec4f_t org); + void (*R_KnightSpikeEffect) (vec4f_t org); + void (*R_SuperSpikeEffect) (vec4f_t org); + void (*R_WizSpikeEffect) (vec4f_t org); - void (*R_BlobExplosion) (const vec3_t org); - void (*R_ParticleExplosion) (const vec3_t org); - void (*R_ParticleExplosion2) (const vec3_t org, int colorStart, - int colorLength); - void (*R_LavaSplash) (const vec3_t org); - void (*R_TeleportSplash) (const vec3_t org); - void (*R_DarkFieldParticles) (const struct entity_s *ent); - void (*R_EntityParticles) (const struct entity_s *ent); + void (*R_BlobExplosion) (vec4f_t org); + void (*R_ParticleExplosion) (vec4f_t org); + void (*R_ParticleExplosion2) (vec4f_t org, int colorStart, int colorLength); + void (*R_LavaSplash) (vec4f_t org); + void (*R_TeleportSplash) (vec4f_t org); + void (*R_DarkFieldParticles) (vec4f_t org); + void (*R_EntityParticles) (vec4f_t org); - void (*R_Particle_New) (ptype_t type, int texnum, const vec3_t org, - float scale, const vec3_t vel, float die, + void (*R_Particle_New) (ptype_t type, int texnum, vec4f_t org, + float scale, vec4f_t vel, float die, int color, float alpha, float ramp); - void (*R_Particle_NewRandom) (ptype_t type, int texnum, const vec3_t org, + void (*R_Particle_NewRandom) (ptype_t type, int texnum, vec4f_t org, int org_fuzz, float scale, int vel_fuzz, float die, int color, float alpha, float ramp); diff --git a/include/d_iface.h b/include/d_iface.h index 621ccbaca..873ac2b7b 100644 --- a/include/d_iface.h +++ b/include/d_iface.h @@ -63,28 +63,38 @@ typedef enum { } ptextype_t; typedef struct particle_s particle_t; -typedef void (*pt_phys_func)(particle_t *); - -pt_phys_func R_ParticlePhysics (ptype_t type) __attribute__((pure)); // !!! if this is changed, it must be changed in d_ifacea.h too !!! -struct particle_s -{ -// driver-usable fields - vec3_t org; - int color; - float alpha; +struct particle_s { + vec4f_t pos; + vec4f_t vel; + + union { + struct { + int icolor; + int pad[2]; + float alpha; + }; + vec4f_t color; + }; + ptextype_t tex; - float scale; -// drivers never touch the following fields - vec3_t vel; - ptype_t type; - float die; float ramp; - pt_phys_func phys; - particle_t *next; + float scale; + float live; }; +typedef struct partparm_s { + vec4f_t drag; // drag[3] is grav scale + float ramp; + float ramp_max; + float scale_rate; + float alpha_rate; +} partparm_t; + +partparm_t R_ParticlePhysics (ptype_t type) __attribute__((pure)); +const int *R_ParticleRamp (ptype_t type) __attribute__((pure)); + #define PARTICLE_Z_CLIP 8.0 typedef struct polyvert_s { diff --git a/include/d_ifacea.h b/include/d_ifacea.h index fa61655e0..4f6118b76 100644 --- a/include/d_ifacea.h +++ b/include/d_ifacea.h @@ -50,19 +50,15 @@ // particle_t structure // !!! if this is changed, it must be changed in d_iface.h too !!! -// driver-usable fields -#define pt_org 0 -#define pt_color 12 -#define pt_alpha 16 -#define pt_tex 20 -#define pt_scale 24 -// drivers never touch the following fields -#define pt_vel 28 -#define pt_type 40 -#define pt_die 44 -#define pt_ramp 48 -#define pt_next 52 -#define pt_size 56 +#define pt_pos 0 +#define pt_vel 16 +#define pt_color 32 +#define pt_alpha 44 +#define pt_tex 48 +#define pt_ramp 52 +#define pt_scale 56 +#define pt_live 60 +#define pt_size 64 #define PARTICLE_Z_CLIP 8.0 diff --git a/include/r_dynamic.h b/include/r_dynamic.h index 8968cfa1c..1027879bc 100644 --- a/include/r_dynamic.h +++ b/include/r_dynamic.h @@ -61,9 +61,8 @@ void R_InitSprites (void); extern unsigned int r_maxparticles; extern unsigned int numparticles; -extern struct particle_s *active_particles; -extern struct particle_s *free_particles; extern struct particle_s *particles; -extern struct particle_s **freeparticles; +extern struct partparm_s *partparams; +extern const int **partramps; #endif // _R_DYNAMIC_H diff --git a/libs/client/cl_effects.c b/libs/client/cl_effects.c index c4e66c7ff..faa451839 100644 --- a/libs/client/cl_effects.c +++ b/libs/client/cl_effects.c @@ -118,35 +118,37 @@ CL_ModelEffects (entity_t *ent, int num, int glow_color, double time) { dlight_t *dl; model_t *model = ent->renderer.model; + vec4f_t old_origin = ent->old_origin; + vec4f_t ent_origin = Transform_GetWorldPosition (ent->transform); // add automatic particle trails if (model->flags & EF_ROCKET) { dl = r_funcs->R_AllocDlight (num); if (dl) { - VectorCopy (Transform_GetWorldPosition (ent->transform), - dl->origin); + VectorCopy (ent_origin, dl->origin); dl->radius = 200.0; dl->die = time + 0.1; //FIXME VectorCopy (r_firecolor->vec, dl->color); VectorSet (0.9, 0.7, 0.0, dl->color); dl->color[3] = 0.7; } - r_funcs->particles->R_RocketTrail (ent); + r_funcs->particles->R_RocketTrail (old_origin, ent_origin); } else if (model->flags & EF_GRENADE) - r_funcs->particles->R_GrenadeTrail (ent); + r_funcs->particles->R_GrenadeTrail (old_origin, ent_origin); else if (model->flags & EF_GIB) - r_funcs->particles->R_BloodTrail (ent); + r_funcs->particles->R_BloodTrail (old_origin, ent_origin); else if (model->flags & EF_ZOMGIB) - r_funcs->particles->R_SlightBloodTrail (ent); + r_funcs->particles->R_SlightBloodTrail (old_origin, ent_origin); else if (model->flags & EF_TRACER) - r_funcs->particles->R_WizTrail (ent); + r_funcs->particles->R_WizTrail (old_origin, ent_origin); else if (model->flags & EF_TRACER2) - r_funcs->particles->R_FlameTrail (ent); + r_funcs->particles->R_FlameTrail (old_origin, ent_origin); else if (model->flags & EF_TRACER3) - r_funcs->particles->R_VoorTrail (ent); + r_funcs->particles->R_VoorTrail (old_origin, ent_origin); else if (model->flags & EF_GLOWTRAIL) if (r_funcs->particles->R_GlowTrail) - r_funcs->particles->R_GlowTrail (ent, glow_color); + r_funcs->particles->R_GlowTrail (old_origin, ent_origin, + glow_color); } void @@ -171,10 +173,10 @@ CL_MuzzleFlash (vec4f_t position, vec4f_t fv, float zoffset, int num, void CL_EntityEffects (int num, entity_t *ent, entity_state_t *state, double time) { + vec4f_t position = Transform_GetWorldPosition (ent->transform); if (state->effects & EF_BRIGHTFIELD) - r_funcs->particles->R_EntityParticles (ent); + r_funcs->particles->R_EntityParticles (position); if (state->effects & EF_MUZZLEFLASH) { - vec4f_t position = Transform_GetWorldPosition (ent->transform); vec4f_t fv = Transform_Forward (ent->transform); CL_MuzzleFlash (position, fv, 16, num, time); } diff --git a/libs/client/cl_temp_entities.c b/libs/client/cl_temp_entities.c index 2fe2255c9..412946f65 100644 --- a/libs/client/cl_temp_entities.c +++ b/libs/client/cl_temp_entities.c @@ -323,7 +323,7 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, explosion_t *ex; int colorStart, colorLength; quat_t color; - vec3_t position; + vec4f_t position = {0, 0, 0, 1}; int count; const char *name; @@ -336,11 +336,11 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, break; case TE_Blood: count = MSG_ReadByte (net_message) * 20; - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); r_funcs->particles->R_BloodPuffEffect (position, count); break; case TE_Explosion: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); // particles r_funcs->particles->R_ParticleExplosion (position); @@ -357,7 +357,7 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, } // sound - S_StartSound (-1, 0, cl_sfx_r_exp3, position, 1, 1); + S_StartSound (-1, 0, cl_sfx_r_exp3, &position[0], 1, 1); // sprite to = new_tent_object (); @@ -376,10 +376,10 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, (vec4f_t) {VectorExpand (position), 1}); break; case TE_Explosion2: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); colorStart = MSG_ReadByte (net_message); colorLength = MSG_ReadByte (net_message); - S_StartSound (-1, 0, cl_sfx_r_exp3, position, 1, 1); + S_StartSound (-1, 0, cl_sfx_r_exp3, &position[0], 1, 1); r_funcs->particles->R_ParticleExplosion2 (position, colorStart, colorLength); dl = r_funcs->R_AllocDlight (0); @@ -395,11 +395,11 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, dl->color[3] = 0.7; break; case TE_Explosion3: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); MSG_ReadCoordV (net_message, color); // OUCH! color[3] = 0.7; r_funcs->particles->R_ParticleExplosion (position); - S_StartSound (-1, 0, cl_sfx_r_exp3, position, 1, 1); + S_StartSound (-1, 0, cl_sfx_r_exp3, &position[0], 1, 1); dl = r_funcs->R_AllocDlight (0); if (dl) { VectorCopy (position, dl->origin); @@ -410,21 +410,21 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, } break; case TE_Gunshot1: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); r_funcs->particles->R_GunshotEffect (position, 20); break; case TE_Gunshot2: count = MSG_ReadByte (net_message) * 20; - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); r_funcs->particles->R_GunshotEffect (position, count); break; case TE_KnightSpike: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); r_funcs->particles->R_KnightSpikeEffect (position); - S_StartSound (-1, 0, cl_sfx_knighthit, position, 1, 1); + S_StartSound (-1, 0, cl_sfx_knighthit, &position[0], 1, 1); break; case TE_LavaSplash: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); r_funcs->particles->R_LavaSplash (position); break; case TE_Lightning1: @@ -441,7 +441,7 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, CL_ParseBeam (net_message, Mod_ForName (name, true), time, ctx); break; case TE_LightningBlood: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); // light dl = r_funcs->R_AllocDlight (0); @@ -456,7 +456,7 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, r_funcs->particles->R_LightningBloodEffect (position); break; case TE_Spike: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); r_funcs->particles->R_SpikeEffect (position); { int i; @@ -468,11 +468,11 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, } else { sound = cl_sfx_tink1; } - S_StartSound (-1, 0, sound, position, 1, 1); + S_StartSound (-1, 0, sound, &position[0], 1, 1); } break; case TE_SuperSpike: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); r_funcs->particles->R_SuperSpikeEffect (position); { int i; @@ -484,23 +484,23 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, } else { sound = cl_sfx_tink1; } - S_StartSound (-1, 0, sound, position, 1, 1); + S_StartSound (-1, 0, sound, &position[0], 1, 1); } break; case TE_TarExplosion: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); r_funcs->particles->R_BlobExplosion (position); - S_StartSound (-1, 0, cl_sfx_r_exp3, position, 1, 1); + S_StartSound (-1, 0, cl_sfx_r_exp3, &position[0], 1, 1); break; case TE_Teleport: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); r_funcs->particles->R_TeleportSplash (position); break; case TE_WizSpike: - MSG_ReadCoordV (net_message, position); + MSG_ReadCoordV (net_message, &position[0]); r_funcs->particles->R_WizSpikeEffect (position); - S_StartSound (-1, 0, cl_sfx_wizhit, position, 1, 1); + S_StartSound (-1, 0, cl_sfx_wizhit, &position[0], 1, 1); break; } } @@ -650,9 +650,9 @@ void CL_ParseParticleEffect (qmsg_t *net_message) { int i, count, color; - vec3_t org, dir; + vec4f_t org = {0, 0, 0, 1}, dir = {}; - MSG_ReadCoordV (net_message, org); + MSG_ReadCoordV (net_message, &org[0]); for (i = 0; i < 3; i++) dir[i] = ((signed char) MSG_ReadByte (net_message)) * (15.0 / 16.0); count = MSG_ReadByte (net_message); diff --git a/libs/client/locs.c b/libs/client/locs.c index 2ab477921..4998694bf 100644 --- a/libs/client/locs.c +++ b/libs/client/locs.c @@ -291,6 +291,7 @@ locs_draw (vec4f_t simorg) dlight_t *dl; location_t *nearloc; vec4f_t trueloc; + vec4f_t zero = {}; int i; nearloc = locs_find (simorg); @@ -307,12 +308,12 @@ locs_draw (vec4f_t simorg) } trueloc = nearloc->loc; r_funcs->particles->R_Particle_New (pt_smokecloud, part_tex_smoke, - &trueloc[0], 2.0,//FIXME - vec3_origin, r_data->realtime + 9.0, 254, + trueloc, 2.0, + zero, r_data->realtime + 9.0, 254, 0.25 + qfrandom (0.125), 0.0); for (i = 0; i < 15; i++) r_funcs->particles->R_Particle_NewRandom (pt_fallfade, - part_tex_dot, &trueloc[0], 12,//FIXME + part_tex_dot, trueloc, 12, 0.7, 96, r_data->realtime + 5.0, 104 + (rand () & 7), 1.0, 0.0); } diff --git a/libs/video/renderer/gl/gl_dyn_part.c b/libs/video/renderer/gl/gl_dyn_part.c index b82785660..988c91432 100644 --- a/libs/video/renderer/gl/gl_dyn_part.c +++ b/libs/video/renderer/gl/gl_dyn_part.c @@ -61,10 +61,6 @@ #include "r_internal.h" #include "varrays.h" -static int ramp1[8] = { 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61 }; -//static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 }; -static int ramp3[8] = { 0x6d, 0x6b, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; - static int partUseVA; static int pVAsize; static int *pVAindices; @@ -73,31 +69,30 @@ static varray_t2f_c4ub_v3f_t *particleVertexArray; static mtstate_t mt; // private PRNG state inline static void -particle_new (ptype_t type, int texnum, const vec3_t org, float scale, - const vec3_t vel, float die, int color, float alpha, float ramp) +particle_new (ptype_t type, int texnum, vec4f_t pos, float scale, + vec4f_t vel, float live, int color, float alpha, float ramp) { - particle_t *part; + if (numparticles >= r_maxparticles) + return; + particle_t *p = &particles[numparticles]; + partparm_t *parm = &partparams[numparticles]; + const int **rampptr = &partramps[numparticles]; + numparticles += 1; -/* - // Uncomment this for particle debugging! - if (numparticles >= r_maxparticles) { - Sys_Error ("FAILED PARTICLE ALLOC!"); - return NULL; + p->pos = pos; + p->vel = vel; + p->icolor = color; + p->alpha = alpha; + p->tex = texnum; + p->ramp = ramp; + p->scale = scale; + p->live = live; + + *parm = R_ParticlePhysics (type); + *rampptr = R_ParticleRamp (type); + if (*rampptr) { + p->icolor = (*rampptr) [(int) p->ramp]; } -*/ - - part = &particles[numparticles++]; - - VectorCopy (org, part->org); - part->color = color; - part->tex = texnum; - part->scale = scale; - part->alpha = alpha; - VectorCopy (vel, part->vel); - part->type = type; - part->die = die; - part->ramp = ramp; - part->phys = R_ParticlePhysics (type); } /* @@ -107,30 +102,32 @@ particle_new (ptype_t type, int texnum, const vec3_t org, float scale, going to bother using this function. */ inline static void -particle_new_random (ptype_t type, int texnum, const vec3_t org, int org_fuzz, - float scale, int vel_fuzz, float die, int color, +particle_new_random (ptype_t type, int texnum, vec4f_t org, int org_fuzz, + float scale, int vel_fuzz, float live, int color, float alpha, float ramp) { float o_fuzz = org_fuzz, v_fuzz = vel_fuzz; int rnd; - vec3_t porg, pvel; + vec4f_t porg, pvel; rnd = mtwist_rand (&mt); porg[0] = o_fuzz * ((rnd & 63) - 31.5) / 63.0 + org[0]; porg[1] = o_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0 + org[1]; porg[2] = o_fuzz * (((rnd >> 10) & 63) - 31.5) / 63.0 + org[2]; + porg[3] = 1; rnd = mtwist_rand (&mt); pvel[0] = v_fuzz * ((rnd & 63) - 31.5) / 63.0; pvel[1] = v_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0; pvel[2] = v_fuzz * (((rnd >> 10) & 63) - 31.5) / 63.0; + pvel[3] = 0; - particle_new (type, texnum, porg, scale, pvel, die, color, alpha, ramp); + particle_new (type, texnum, porg, scale, pvel, live, color, alpha, ramp); } /* inline static void -particle_new_veryrandom (ptype_t type, int texnum, const vec3_t org, - int org_fuzz, float scale, int vel_fuzz, float die, +particle_new_veryrandom (ptype_t type, int texnum, vec4f_t org, + int org_fuzz, float scale, int vel_fuzz, float live, int color, float alpha, float ramp) { vec3_t porg, pvel; @@ -141,10 +138,39 @@ particle_new_veryrandom (ptype_t type, int texnum, const vec3_t org, pvel[0] = qfrandom (vel_fuzz * 2) - vel_fuzz; pvel[1] = qfrandom (vel_fuzz * 2) - vel_fuzz; pvel[2] = qfrandom (vel_fuzz * 2) - vel_fuzz; - particle_new (type, texnum, porg, scale, pvel, die, color, alpha, ramp); + particle_new (type, texnum, porg, scale, pvel, live, color, alpha, ramp); } */ +static vec4f_t +roffs (int mod) +{ + vec4f_t offs = { + (mtwist_rand (&mt) % mod) - 0.5 * (mod - 1), + (mtwist_rand (&mt) % mod) - 0.5 * (mod - 1), + (mtwist_rand (&mt) % mod) - 0.5 * (mod - 1), + 0 + }; + return offs; +} + +static vec4f_t +tracer_vel (int tracercount, vec4f_t vec) +{ + if (tracercount & 1) { + return (vec4f_t) { vec[1], -vec[0], 0, 0 }; + } else { + return (vec4f_t) { -vec[1], vec[0], 0, 0 }; + } +} + +static void +add_particle (ptype_t type, vec4f_t pos, vec4f_t vel, float live, int color, + float ramp) +{ + particle_new (type, part_tex_dot, pos, 1, vel, live, color, 1, ramp); +} + void gl_R_ClearParticles (void) { @@ -199,13 +225,13 @@ gl_R_InitParticles (void) } } + void gl_R_ReadPointFile_f (void) { const char *name; char *mapname; - int c, r; - vec3_t org; + int c; QFile *f; mapname = strdup (r_worldentity.renderer.model->path); @@ -224,11 +250,13 @@ gl_R_ReadPointFile_f (void) Sys_MaskPrintf (SYS_dev, "Reading %s...\n", name); c = 0; + vec4f_t zero = {}; for (;;) { char buf[64]; + vec4f_t org = { 0, 0, 0, 1 }; Qgets (f, buf, sizeof (buf)); - r = sscanf (buf, "%f %f %f\n", &org[0], &org[1], &org[2]); + int r = sscanf (buf, "%f %f %f\n", &org[0], &org[1], &org[2]); if (r != 3) break; c++; @@ -237,7 +265,7 @@ gl_R_ReadPointFile_f (void) Sys_MaskPrintf (SYS_dev, "Not enough free particles\n"); break; } else { - particle_new (pt_static, part_tex_dot, org, 1.5, vec3_origin, + particle_new (pt_static, part_tex_dot, org, 1.5, zero, 99999, (-c) & 15, 1.0, 0.0); } } @@ -246,18 +274,18 @@ gl_R_ReadPointFile_f (void) } static void -R_ParticleExplosion_QF (const vec3_t org) +R_ParticleExplosion_QF (vec4f_t org) { // R_NewExplosion (org); if (numparticles >= r_maxparticles) return; particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8, - vr_data.realtime + 5.0, (mtwist_rand (&mt) & 7) + 8, + 5.0, (mtwist_rand (&mt) & 7) + 8, 0.5 + qfrandom (0.25), 0.0); } static void -R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength) +R_ParticleExplosion2_QF (vec4f_t org, int colorStart, int colorLength) { unsigned int i, j = 512; @@ -268,13 +296,13 @@ R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength) for (i = 0; i < j; i++) { particle_new_random (pt_blob, part_tex_dot, org, 16, 2, 256, - vr_data.realtime + 0.3, - colorStart + (i % colorLength), 1.0, 0.0); + 0.3, + colorStart + (i % colorLength), 1.0, 0.0); } } static void -R_BlobExplosion_QF (const vec3_t org) +R_BlobExplosion_QF (vec4f_t org) { unsigned int i; unsigned int j = 1024; @@ -286,28 +314,28 @@ R_BlobExplosion_QF (const vec3_t org) for (i = 0; i < j >> 1; i++) { particle_new_random (pt_blob, part_tex_dot, org, 12, 2, 256, - vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 7) * 0.05, + 1.0 + (mtwist_rand (&mt) & 7) * 0.05, 66 + i % 6, 1.0, 0.0); } for (i = 0; i < j / 2; i++) { particle_new_random (pt_blob2, part_tex_dot, org, 12, 2, 256, - vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 7) * 0.05, + 1.0 + (mtwist_rand (&mt) & 7) * 0.05, 150 + i % 6, 1.0, 0.0); } } static inline void -R_RunSparkEffect_QF (const vec3_t org, int count, int ofuzz) +R_RunSparkEffect_QF (vec4f_t org, int count, int ofuzz) { - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; + + vec4f_t zero = {}; particle_new (pt_smokecloud, part_tex_smoke, org, ofuzz * 0.08, - vec3_origin, vr_data.realtime + 9, 12 + (mtwist_rand (&mt) & 3), + zero, 9, 12 + (mtwist_rand (&mt) & 3), 0.25 + qfrandom (0.125), 0.0); - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - if (count) { + if (count > 0) { int orgfuzz = ofuzz * 3 / 4; if (orgfuzz < 1) orgfuzz = 1; @@ -316,30 +344,30 @@ R_RunSparkEffect_QF (const vec3_t org, int count, int ofuzz) int color = mtwist_rand (&mt) & 7; particle_new_random (pt_fallfadespark, part_tex_dot, org, orgfuzz, - 0.7, 96, vr_data.realtime + 5.0, ramp1[color], - 1.0, color); + 0.7, 96, 5.0, 0, 1.0, color); } } } static inline void -R_BloodPuff_QF (const vec3_t org, int count) +R_BloodPuff_QF (vec4f_t org, int count) { - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - particle_new (pt_bloodcloud, part_tex_smoke, org, count / 5, vec3_origin, - vr_data.realtime + 99.0, 70 + (mtwist_rand (&mt) & 3), 0.5, 0.0); + vec4f_t zero = {}; + particle_new (pt_bloodcloud, part_tex_smoke, org, count / 5, zero, + 99.0, 70 + (mtwist_rand (&mt) & 3), 0.5, 0.0); } static void -R_BloodPuffEffect_QF (const vec3_t org, int count) +R_BloodPuffEffect_QF (vec4f_t org, int count) { R_BloodPuff_QF (org, count); } static void -R_GunshotEffect_QF (const vec3_t org, int count) +R_GunshotEffect_QF (vec4f_t org, int count) { int scale = 16; @@ -348,170 +376,133 @@ R_GunshotEffect_QF (const vec3_t org, int count) } static void -R_LightningBloodEffect_QF (const vec3_t org) +R_LightningBloodEffect_QF (vec4f_t org) { - int count = 7; + if (!r_particles->int_val) + return; R_BloodPuff_QF (org, 50); - if (numparticles >= r_maxparticles) - return; - particle_new (pt_smokecloud, part_tex_smoke, org, 3.0, vec3_origin, - vr_data.realtime + 9.0, 12 + (mtwist_rand (&mt) & 3), + vec4f_t zero = {}; + particle_new (pt_smokecloud, part_tex_smoke, org, 3.0, zero, + 9.0, 12 + (mtwist_rand (&mt) & 3), 0.25 + qfrandom (0.125), 0.0); - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - while (count--) + for (int count = 7; count-- > 0; ) { particle_new_random (pt_fallfade, part_tex_spark, org, 12, 2.0, 128, - vr_data.realtime + 5.0, 244 + (count % 3), 1.0, - 0.0); + 5.0, 244 + (count % 3), 1.0, 0.0); + } } static void -R_RunParticleEffect_QF (const vec3_t org, const vec3_t dir, int color, +R_RunParticleEffect_QF (vec4f_t org, vec4f_t dir, int color, int count) { - float scale; - int i; - vec3_t porg; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - scale = pow (count, 0.23); // calculate scale before clipping to part. max + float scale = pow (count, 0.23); - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - - for (i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { int rnd = mtwist_rand (&mt); - porg[0] = org[0] + scale * (((rnd >> 3) & 15) - 7.5); - porg[1] = org[1] + scale * (((rnd >> 7) & 15) - 7.5); - porg[2] = org[2] + scale * (((rnd >> 11) & 15) - 7.5); // Note that ParseParticleEffect handles (dir * 15) - particle_new (pt_grav, part_tex_dot, porg, 1.5, dir, - vr_data.realtime + 0.1 * (i % 5), + particle_new (pt_grav, part_tex_dot, org + scale * roffs (16), 1.5, + dir, 0.1 * (i % 5), (color & ~7) + (rnd & 7), 1.0, 0.0); } } static void -R_SpikeEffect_QF (const vec3_t org) +R_SpikeEffect_QF (vec4f_t org) { R_RunSparkEffect_QF (org, 5, 8); } static void -R_SuperSpikeEffect_QF (const vec3_t org) +R_SuperSpikeEffect_QF (vec4f_t org) { R_RunSparkEffect_QF (org, 10, 8); } static void -R_KnightSpikeEffect_QF (const vec3_t org) +R_KnightSpikeEffect_QF (vec4f_t org) { - unsigned int count = 10; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - particle_new (pt_smokecloud, part_tex_smoke, org, 1.0, vec3_origin, - vr_data.realtime + 9.0, 234, 0.25 + qfrandom (0.125), 0.0); - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - while (count--) + vec4f_t zero = {}; + particle_new (pt_smokecloud, part_tex_smoke, org, 1.0, zero, + 9.0, 234, 0.25 + qfrandom (0.125), 0.0); + + for (int count = 10; count-- > 0; ) { particle_new_random (pt_fallfade, part_tex_dot, org, 6, 0.7, 96, - vr_data.realtime + 5.0, 234, 1.0, 0.0); + 5.0, 234, 1.0, 0.0); + } } static void -R_WizSpikeEffect_QF (const vec3_t org) +R_WizSpikeEffect_QF (vec4f_t org) { - unsigned int count = 15; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - particle_new (pt_smokecloud, part_tex_smoke, org, 2.0, vec3_origin, - vr_data.realtime + 9.0, 63, 0.25 + qfrandom (0.125), 0.0); - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - while (count--) + vec4f_t zero = {}; + particle_new (pt_smokecloud, part_tex_smoke, org, 2.0, zero, + 9.0, 63, 0.25 + qfrandom (0.125), 0.0); + + for (int count = 15; count-- > 0; ) { particle_new_random (pt_fallfade, part_tex_dot, org, 12, 0.7, 96, - vr_data.realtime + 5.0, 63, 1.0, 0.0); + 5.0, 63, 1.0, 0.0); + } } static void -R_LavaSplash_QF (const vec3_t org) +R_LavaSplash_QF (vec4f_t org) { - float vel; - int rnd, i, j; - int k = 256; - vec3_t dir, porg, pvel; - - if (numparticles + k >= r_maxparticles) { + if (!r_particles->int_val) return; - } // else if (numparticles + k >= r_maxparticles) { -// k = r_maxparticles - numparticles; -// } - dir[2] = 256; - for (i = -128; i < 128; i += 16) { - for (j = -128; j < 128; j += 16) { - rnd = mtwist_rand (&mt); - dir[0] = j + (rnd & 7); - dir[1] = i + ((rnd >> 6) & 7); - - porg[0] = org[0] + dir[0]; - porg[1] = org[1] + dir[1]; - porg[2] = org[2] + ((rnd >> 9) & 63); - - VectorNormalize (dir); - rnd = mtwist_rand (&mt); - vel = 50.0 + 0.5 * (float) (rnd & 127); - VectorScale (dir, vel, pvel); - particle_new (pt_grav, part_tex_dot, porg, 3, pvel, - vr_data.realtime + 2.0 + ((rnd >> 7) & 31) * 0.02, + for (int i = -16; i < 16; i++) { + for (int j = -16; j < 16; j++) { + uint32_t rnd = mtwist_rand (&mt); + float vel = 50.0 + 0.5 * (mtwist_rand (&mt) & 127); + vec4f_t dir = { + j * 8 + (rnd & 7), + i * 8 + ((rnd >> 6) & 7), + 256, + 0 + }; + vec4f_t offs = { dir[0], dir[1], ((rnd >> 9) & 63), 0 }; + dir = normalf (dir); + particle_new (pt_grav, part_tex_dot, org + offs, 3, vel * dir, + 2.0 + ((rnd >> 7) & 31) * 0.02, 224 + ((rnd >> 12) & 7), 0.75, 0.0); } } } static void -R_TeleportSplash_QF (const vec3_t org) +R_TeleportSplash_QF (vec4f_t org) { - float vel; - int rnd, i, j, k; - int l = 896; - vec3_t dir, pdir, porg, pvel; - - if (numparticles + l >= r_maxparticles) { + if (!r_particles->int_val) return; - } // else if (numparticles + l >= r_maxparticles) { -// l = r_maxparticles - numparticles; -// } - for (k = -24; k < 32; k += 4) { - dir[2] = k * 8; - for (i = -16; i < 16; i += 4) { - dir[1] = i * 8; - for (j = -16; j < 16; j += 4) { - dir[0] = j * 8; - - VectorCopy (dir, pdir); - VectorNormalize (pdir); - - rnd = mtwist_rand (&mt); - porg[0] = org[0] + i + (rnd & 3); - porg[1] = org[1] + j + ((rnd >> 2) & 3); - porg[2] = org[2] + k + ((rnd >> 4) & 3); - - vel = 50 + ((rnd >> 6) & 63); - VectorScale (pdir, vel, pvel); - particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel, - (vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 15) * 0.01), + for (int k = -24; k < 32; k += 4) { + for (int i = -16; i < 16; i += 4) { + for (int j = -16; j < 16; j += 4) { + uint32_t rnd = mtwist_rand (&mt); + float vel = 50 + ((rnd >> 6) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + (rnd & 3), + j + ((rnd >> 2) & 3), + k + ((rnd >> 4) & 3), + 0 + }; + particle_new (pt_grav, part_tex_spark, org + offs, 0.6, + vel * dir, + (0.2 + (mtwist_rand (&mt) & 15) * 0.01), (7 + ((rnd >> 12) & 7)), 1.0, 0.0); } } @@ -519,320 +510,272 @@ R_TeleportSplash_QF (const vec3_t org) } static void -R_RocketTrail_QF (const entity_t *ent) +R_RocketTrail_QF (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - vec3_t old_origin, vec; - vec3_t org; - if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 1.5 + qfrandom (1.5); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - 3) * vec; + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; + float pscale = 1.5 + qfrandom (1.5); while (len < maxlen) { - pscalenext = 1.5 + qfrandom (1.5); - dist = (pscale + pscalenext) * 3.0; - percent = len * origlen; + float pscalenext = 1.5 + qfrandom (1.5); + float dist = (pscale + pscalenext) * 3.0; + float percent = len * origlen; - particle_new (pt_smoke, part_tex_smoke, old_origin, - pscale + percent * 4.0, vec3_origin, - vr_data.realtime + 2.0 - percent * 2.0, + particle_new (pt_smoke, part_tex_smoke, pos, + pscale + percent * 4.0, zero, + 2.0 - percent * 2.0, 12 + (mtwist_rand (&mt) & 3), 0.5 + qfrandom (0.125) - percent * 0.40, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorMultAdd (old_origin, len, vec, old_origin); + pos += step; pscale = pscalenext; } } static void -R_GrenadeTrail_QF (const entity_t *ent) +R_GrenadeTrail_QF (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - vec3_t old_origin, vec; - vec3_t org; - if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 6.0 + qfrandom (7.0); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - 3) * vec; + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; + float pscale = 6.0 + qfrandom (7.0); while (len < maxlen) { - pscalenext = 6.0 + qfrandom (7.0); - dist = (pscale + pscalenext) * 2.0; - percent = len * origlen; + float pscalenext = 6.0 + qfrandom (7.0); + float dist = (pscale + pscalenext) * 2.0; + float percent = len * origlen; - particle_new (pt_smoke, part_tex_smoke, old_origin, - pscale + percent * 4.0, vec3_origin, - vr_data.realtime + 2.0 - percent * 2.0, + particle_new (pt_smoke, part_tex_smoke, pos, + pscale + percent * 4.0, zero, + 2.0 - percent * 2.0, 1 + (mtwist_rand (&mt) & 3), 0.625 + qfrandom (0.125) - percent * 0.40, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorMultAdd (old_origin, len, vec, old_origin); + pos += step; pscale = pscalenext; } } static void -R_BloodTrail_QF (const entity_t *ent) +R_BloodTrail_QF (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - int j; - vec3_t old_origin, porg, pvel, vec; - vec3_t org; - if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 5.0 + qfrandom (10.0); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - 3) * vec; + + float len = 0; + vec4f_t pos = start; + float pscale = 5.0 + qfrandom (10.0); while (len < maxlen) { - pscalenext = 5.0 + qfrandom (10.0); - dist = (pscale + pscalenext) * 1.5; + float pscalenext = 5.0 + qfrandom (10.0); + float dist = (pscale + pscalenext) * 1.5; + float percent = len * origlen; + vec4f_t vel = roffs (24); + vel[2] -= percent * 40; - for (j = 0; j < 3; j++) { - pvel[j] = qfrandom (24.0) - 12.0; - porg[j] = old_origin[j] + qfrandom (3.0) - 1.5; - } - - percent = len * origlen; - pvel[2] -= percent * 40.0; - - particle_new (pt_grav, part_tex_smoke, porg, pscale, pvel, - vr_data.realtime + 2.0 - percent * 2.0, + particle_new (pt_grav, part_tex_smoke, pos + roffs (4), pscale, vel, + 2.0 - percent * 2.0, 68 + (mtwist_rand (&mt) & 3), 1.0, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorMultAdd (old_origin, len, vec, old_origin); + pos += step; pscale = pscalenext; } } static void -R_SlightBloodTrail_QF (const entity_t *ent) +R_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - int j; - vec3_t old_origin, porg, pvel, vec; - vec3_t org; - if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 1.5 + qfrandom (7.5); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - 3) * vec; + + float len = 0; + vec4f_t pos = start; + float pscale = 1.5 + qfrandom (7.5); while (len < maxlen) { - pscalenext = 1.5 + qfrandom (7.5); - dist = (pscale + pscalenext) * 1.5; + float pscalenext = 1.5 + qfrandom (7.5); + float dist = (pscale + pscalenext) * 1.5; + float percent = len * origlen; + vec4f_t vel = roffs (12); + vel[2] -= percent * 40; - for (j = 0; j < 3; j++) { - pvel[j] = (qfrandom (12.0) - 6.0); - porg[j] = old_origin[j] + qfrandom (3.0) - 1.5; - } - - percent = len * origlen; - pvel[2] -= percent * 40; - - particle_new (pt_grav, part_tex_smoke, porg, pscale, pvel, - vr_data.realtime + 1.5 - percent * 1.5, + particle_new (pt_grav, part_tex_smoke, pos + roffs (4), pscale, vel, + 1.5 - percent * 1.5, 68 + (mtwist_rand (&mt) & 3), 0.75, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorMultAdd (old_origin, len, vec, old_origin); + pos += step; pscale = pscalenext; } } static void -R_WizTrail_QF (const entity_t *ent) +R_WizTrail_QF (vec4f_t start, vec4f_t end) { - float maxlen, origlen, percent; - float dist = 3.0, len = 0.0; - static int tracercount; - vec3_t old_origin, pvel, subtract, vec; - vec3_t org; + float dist = 3.0; if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t pos = start; while (len < maxlen) { - percent = len * origlen; + static int tracercount; + float percent = len * origlen; - tracercount++; - if (tracercount & 1) { - pvel[0] = 30.0 * vec[1]; - pvel[1] = 30.0 * -vec[0]; - } else { - pvel[0] = 30.0 * -vec[1]; - pvel[1] = 30.0 * vec[0]; - } - pvel[2] = 0.0; - - particle_new (pt_flame, part_tex_smoke, old_origin, - 2.0 + qfrandom (1.0) - percent * 2.0, pvel, - vr_data.realtime + 0.5 - percent * 0.5, + particle_new (pt_flame, part_tex_smoke, pos, + 2.0 + qfrandom (1.0) - percent * 2.0, + 30 * tracer_vel (tracercount++, vec), + 0.5 - percent * 0.5, 52 + (mtwist_rand (&mt) & 4), 1.0 - percent * 0.125, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += step; } } static void -R_FlameTrail_QF (const entity_t *ent) +R_FlameTrail_QF (vec4f_t start, vec4f_t end) { - float maxlen, origlen, percent; - float dist = 3.0, len = 0.0; - static int tracercount; - vec3_t old_origin, pvel, subtract, vec; - vec3_t org; + float dist = 3.0; if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t pos = start; while (len < maxlen) { - percent = len * origlen; + static int tracercount; + float percent = len * origlen; - tracercount++; - if (tracercount & 1) { - pvel[0] = 30.0 * vec[1]; - pvel[1] = 30.0 * -vec[0]; - } else { - pvel[0] = 30.0 * -vec[1]; - pvel[1] = 30.0 * vec[0]; - } - pvel[2] = 0.0; - - particle_new (pt_flame, part_tex_smoke, old_origin, - 2.0 + qfrandom (1.0) - percent * 2.0, pvel, - vr_data.realtime + 0.5 - percent * 0.5, 234, + particle_new (pt_flame, part_tex_smoke, pos, + 2.0 + qfrandom (1.0) - percent * 2.0, + 30 * tracer_vel (tracercount++, vec), + 0.5 - percent * 0.5, 234, 1.0 - percent * 0.125, 0.0); - if (numparticles >= r_maxparticles) - break; len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += step; } } static void -R_VoorTrail_QF (const entity_t *ent) +R_VoorTrail_QF (vec4f_t start, vec4f_t end) { - float maxlen, origlen, percent; - float dist = 3.0, len = 0.0; - int j; - vec3_t subtract, old_origin, porg, vec; - vec3_t org; + float dist = 3.0; if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; while (len < maxlen) { - percent = len * origlen; + float percent = len * origlen; - for (j = 0; j < 3; j++) - porg[j] = old_origin[j] + qfrandom (16.0) - 8.0; - - particle_new (pt_static, part_tex_dot, porg, 1.0 + qfrandom (1.0), - vec3_origin, vr_data.realtime + 0.3 - percent * 0.3, + particle_new (pt_static, part_tex_dot, pos + roffs (16), + 1.0 + qfrandom (1.0), + zero, 0.3 - percent * 0.3, 9 * 16 + 8 + (mtwist_rand (&mt) & 3), 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += step; } } static void -R_GlowTrail_QF (const entity_t *ent, int glow_color) +R_GlowTrail_QF (vec4f_t start, vec4f_t end, int glow_color) { - float maxlen, origlen, percent; - float dist = 3.0, len = 0.0; - int rnd; - vec3_t old_origin, org, subtract, vec; + float dist = 3.0; if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - VectorScale (vec, (maxlen - dist), subtract); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; while (len < maxlen) { - percent = len * origlen; + float percent = len * origlen; - rnd = mtwist_rand (&mt); - org[0] = old_origin[0] + ((rnd >> 12) & 7) * (5.0/7.0) - 2.5; - org[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5; - org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5; - - particle_new (pt_smoke, part_tex_dot, org, 1.0, vec3_origin, - vr_data.realtime + 2.0 - percent * 0.2, - glow_color, 1.0, 0.0); + particle_new (pt_smoke, part_tex_dot, pos + roffs (5), 1.0, zero, + 2.0 - percent * 0.2, glow_color, 1.0, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += step; } } static void -R_ParticleExplosion_EE (const vec3_t org) +R_ParticleExplosion_EE (vec4f_t org) { /* R_NewExplosion (org); @@ -840,41 +783,31 @@ R_ParticleExplosion_EE (const vec3_t org) if (numparticles >= r_maxparticles) return; particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8, - vr_data.realtime + 5.0, mtwist_rand (&mt) & 255, + 5.0, mtwist_rand (&mt) & 255, 0.5 + qfrandom (0.25), 0.0); } static void -R_TeleportSplash_EE (const vec3_t org) +R_TeleportSplash_EE (vec4f_t org) { - float vel; - int rnd, i, j, k; - int l = 896; - vec3_t dir, porg, pvel; - - if (numparticles + l >= r_maxparticles) { + if (!r_particles->int_val) return; - } // else if (numparticles + l >= r_maxparticles) { -// l = r_maxparticles - numparticles; -// } - for (k = -24; k < 32; k += 4) { - dir[2] = k * 8; - for (i = -16; i < 16; i += 4) { - dir[1] = i * 8; - for (j = -16; j < 16; j += 4) { - dir[0] = j * 8; - - rnd = mtwist_rand (&mt); - porg[0] = org[0] + i + (rnd & 3); - porg[1] = org[1] + j + ((rnd >> 2) & 3); - porg[2] = org[2] + k + ((rnd >> 4) & 3); - - VectorNormalize (dir); - vel = 50 + ((rnd >> 6) & 63); - VectorScale (dir, vel, pvel); - particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel, - (vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 15) * 0.01), + for (int k = -24; k < 32; k += 4) { + for (int i = -16; i < 16; i += 4) { + for (int j = -16; j < 16; j += 4) { + uint32_t rnd = mtwist_rand (&mt); + float vel = 50 + ((rnd >> 6) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + (rnd & 3), + j + ((rnd >> 2) & 3), + k + ((rnd >> 4) & 3), + 0 + }; + particle_new (pt_grav, part_tex_spark, org + offs, 0.6, + vel * dir, + (0.2 + (mtwist_rand (&mt) & 15) * 0.01), qfrandom (1.0), 1.0, 0.0); } } @@ -882,347 +815,274 @@ R_TeleportSplash_EE (const vec3_t org) } static void -R_RocketTrail_EE (const entity_t *ent) +R_RocketTrail_EE (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - vec3_t old_origin, subtract, vec; - vec3_t org; - if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 1.5 + qfrandom (1.5); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + float pscale = 1.5 + qfrandom (1.5); + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; while (len < maxlen) { - pscalenext = 1.5 + qfrandom (1.5); - dist = (pscale + pscalenext) * 3.0; - percent = len * origlen; + float pscalenext = 1.5 + qfrandom (1.5); + float dist = (pscale + pscalenext) * 3.0; + float percent = len * origlen; - particle_new (pt_smoke, part_tex_smoke, old_origin, - pscale + percent * 4.0, vec3_origin, - vr_data.realtime + 2.0 - percent * 2.0, + particle_new (pt_smoke, part_tex_smoke, pos, + pscale + percent * 4.0, zero, + 2.0 - percent * 2.0, mtwist_rand (&mt) & 255, 0.5 + qfrandom (0.125) - percent * 0.40, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorScale (vec, len, subtract); - VectorAdd (old_origin, subtract, old_origin); + pos += len * vec; pscale = pscalenext; } } static void -R_GrenadeTrail_EE (const entity_t *ent) +R_GrenadeTrail_EE (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - vec3_t old_origin, subtract, vec; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, ent->old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 6.0 + qfrandom (7.0); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + float pscale = 6.0 + qfrandom (7.0); + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; while (len < maxlen) { - pscalenext = 6.0 + qfrandom (7.0); - dist = (pscale + pscalenext) * 2.0; - percent = len * origlen; + float pscalenext = 6.0 + qfrandom (7.0); + float dist = (pscale + pscalenext) * 2.0; + float percent = len * origlen; - particle_new (pt_smoke, part_tex_smoke, old_origin, - pscale + percent * 4.0, vec3_origin, - vr_data.realtime + 2.0 - percent * 2.0, + particle_new (pt_smoke, part_tex_smoke, pos, + pscale + percent * 4.0, zero, + 2.0 - percent * 2.0, mtwist_rand (&mt) & 255, 0.625 + qfrandom (0.125) - percent * 0.40, 0.0); - if (numparticles >= r_maxparticles) - break; len += dist; - VectorScale (vec, len, subtract); - VectorAdd (old_origin, subtract, old_origin); + pos += len * vec; pscale = pscalenext; } } static void -R_ParticleExplosion_ID (const vec3_t org) +R_ParticleExplosion_ID (vec4f_t org) { - unsigned int i; - unsigned int j = 1024; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - else if (numparticles + j >= r_maxparticles) - j = r_maxparticles - numparticles; - for (i = 0; i < j >> 1; i++) { - particle_new_random (pt_explode, part_tex_dot, org, 16, 1.0, 256, - vr_data.realtime + 5.0, ramp1[0], 1.0, i & 3); - } - for (i = 0; i < j / 2; i++) { - particle_new_random (pt_explode2, part_tex_dot, org, 16, 1.0, 256, - vr_data.realtime + 5.0, ramp1[0], 1.0, i & 3); + for (int i = 0; i < 1024; i++) { + ptype_t type = i & 1 ? pt_explode2 : pt_explode; + add_particle (type, org + roffs (32), roffs (512), 5, + 0, mtwist_rand (&mt) & 3); } } static void -R_BlobExplosion_ID (const vec3_t org) +R_BlobExplosion_ID (vec4f_t org) { - unsigned int i; - unsigned int j = 1024; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - else if (numparticles + j >= r_maxparticles) - j = r_maxparticles - numparticles; - for (i = 0; i < j >> 1; i++) { - particle_new_random (pt_blob, part_tex_dot, org, 12, 1.0, 256, - vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 8) * 0.05, - 66 + i % 6, 1.0, 0.0); - } - for (i = 0; i < j / 2; i++) { - particle_new_random (pt_blob2, part_tex_dot, org, 12, 1.0, 256, - vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 8) * 0.05, - 150 + i % 6, 1.0, 0.0); + for (int i = 0; i < 1024; i++) { + ptype_t type = i & 1 ? pt_blob : pt_blob2; + int color = i & 1 ? 66 : 150; + add_particle (type, org + roffs (32), roffs (512), + color + mtwist_rand (&mt) % 6, + (color & ~7) + (mtwist_rand (&mt) & 7), 0); } } static inline void // FIXME: inline? -R_RunParticleEffect_ID (const vec3_t org, const vec3_t dir, int color, +R_RunParticleEffect_ID (vec4f_t org, vec4f_t dir, int color, int count) { - float scale; - int i; - vec3_t porg; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - if (count > 130) // calculate scale before clipping to particle max - scale = 3.0; - else if (count > 20) - scale = 2.0; - else - scale = 1.0; - - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - - for (i = 0; i < count; i++) { - int rnd = mtwist_rand (&mt); - - porg[0] = org[0] + scale * (((rnd >> 3) & 15) - 8); - porg[1] = org[1] + scale * (((rnd >> 7) & 15) - 8); - porg[2] = org[2] + scale * (((rnd >> 11) & 15) - 8); - - // Note that ParseParticleEffect handles (dir * 15) - particle_new (pt_grav, part_tex_dot, porg, 1.0, dir, - vr_data.realtime + 0.1 * (i % 5), - (color & ~7) + (rnd & 7), 1.0, 0.0); + for (int i = 0; i < count; i++) { + add_particle (pt_slowgrav, org + roffs (16), + dir/* + roffs (300)*/, + 0.1 * (mtwist_rand (&mt) % 5), + (color & ~7) + (mtwist_rand (&mt) & 7), 0); } } static void -R_BloodPuffEffect_ID (const vec3_t org, int count) +R_BloodPuffEffect_ID (vec4f_t org, int count) { - R_RunParticleEffect_ID (org, vec3_origin, 73, count); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 73, count); } static void -R_GunshotEffect_ID (const vec3_t org, int count) +R_GunshotEffect_ID (vec4f_t org, int count) { - R_RunParticleEffect_ID (org, vec3_origin, 0, count); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 0, count); } static void -R_LightningBloodEffect_ID (const vec3_t org) +R_LightningBloodEffect_ID (vec4f_t org) { - R_RunParticleEffect_ID (org, vec3_origin, 225, 50); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 225, 50); } static void -R_SpikeEffect_ID (const vec3_t org) +R_SpikeEffect_ID (vec4f_t org) { - R_RunParticleEffect_ID (org, vec3_origin, 0, 10); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 0, 10); } static void -R_SuperSpikeEffect_ID (const vec3_t org) +R_SuperSpikeEffect_ID (vec4f_t org) { - R_RunParticleEffect_ID (org, vec3_origin, 0, 20); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 0, 20); } static void -R_KnightSpikeEffect_ID (const vec3_t org) +R_KnightSpikeEffect_ID (vec4f_t org) { - R_RunParticleEffect_ID (org, vec3_origin, 226, 20); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 226, 20); } static void -R_WizSpikeEffect_ID (const vec3_t org) +R_WizSpikeEffect_ID (vec4f_t org) { - R_RunParticleEffect_ID (org, vec3_origin, 20, 30); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 20, 30); } static void -R_LavaSplash_ID (const vec3_t org) +R_LavaSplash_ID (vec4f_t org) { - float vel; - int rnd, i, j; - int k = 256; - vec3_t dir, porg, pvel; - - if (numparticles + k >= r_maxparticles) { + if (!r_particles->int_val) return; - } // else if (numparticles + k >= r_maxparticles) { -// k = r_maxparticles - numparticles; -// } - dir[2] = 256; - for (i = -128; i < 128; i += 16) { - for (j = -128; j < 128; j += 16) { - rnd = mtwist_rand (&mt); - dir[0] = j + (rnd & 7); - dir[1] = i + ((rnd >> 6) & 7); - - porg[0] = org[0] + dir[0]; - porg[1] = org[1] + dir[1]; - porg[2] = org[2] + ((rnd >> 9) & 63); - - VectorNormalize (dir); - rnd = mtwist_rand (&mt); - vel = 50 + (rnd & 63); - VectorScale (dir, vel, pvel); - particle_new (pt_grav, part_tex_dot, porg, 1.0, pvel, - vr_data.realtime + 2 + ((rnd >> 7) & 31) * 0.02, - 224 + ((rnd >> 12) & 7), 1.0, 0.0); - } - } -} - -static void -R_TeleportSplash_ID (const vec3_t org) -{ - float vel; - int rnd, i, j, k; - int l = 896; - vec3_t dir, pdir, porg, pvel; - - if (numparticles + l >= r_maxparticles) { - return; - } // else if (numparticles + l >= r_maxparticles) { -// l = r_maxparticles - numparticles; -// } - - for (k = -24; k < 32; k += 4) { - dir[2] = k * 8; - for (i = -16; i < 16; i += 4) { - dir[1] = i * 8; - for (j = -16; j < 16; j += 4) { - dir[0] = j * 8; - - VectorCopy (dir, pdir); - VectorNormalize (pdir); - - rnd = mtwist_rand (&mt); - porg[0] = org[0] + i + (rnd & 3); - porg[1] = org[1] + j + ((rnd >> 2) & 3); - porg[2] = org[2] + k + ((rnd >> 4) & 3); - - vel = 50 + ((rnd >> 6) & 63); - VectorScale (pdir, vel, pvel); - particle_new (pt_grav, part_tex_dot, porg, 1.0, pvel, - (vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 7) * 0.02), - (7 + ((rnd >> 12) & 7)), 1.0, 0.0); + for (int i = -16; i < 16; i++) { + for (int j = -16; j < 16; j++) { + for (int k = 0; k < 1; k++) { + float vel = 50 + (mtwist_rand (&mt) & 63); + vec4f_t dir = { + j * 8 + (mtwist_rand (&mt) & 7), + i * 8 + (mtwist_rand (&mt) & 7), + 256, + 0 + }; + vec4f_t offs = { + dir[0], + dir[1], + (mtwist_rand (&mt) & 63), + 0 + }; + dir = normalf (dir); + add_particle (pt_grav, org + offs, vel * dir, + 2 + (mtwist_rand (&mt) & 31) * 0.02, + 224 + (mtwist_rand (&mt) & 7), 0); } } } } static void -R_DarkFieldParticles_ID (const entity_t *ent) +R_TeleportSplash_ID (vec4f_t org) { - int i, j, k, l = 64; - unsigned int rnd; - float vel; - vec3_t dir, org, porg, pvel; - - if (numparticles + l >= r_maxparticles) { + if (!r_particles->int_val) return; - } // else if (numparticles + l >= r_maxparticles) { -// l = r_maxparticles - numparticles; -// } - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - - for (i = -16; i < 16; i += 8) { - dir [1] = i * 8; - for (j = -16; j < 16; j += 8) { - dir [0] = j * 8; - for (k = 0; k < 32; k += 8) { - dir [2] = k * 8; - rnd = mtwist_rand (&mt); - - porg[0] = org[0] + i + ((rnd >> 3) & 3); - porg[1] = org[1] + j + ((rnd >> 5) & 3); - porg[2] = org[2] + k + ((rnd >> 7) & 3); - - VectorNormalize (dir); - vel = 50 + ((rnd >> 9) & 63); - VectorScale (dir, vel, pvel); - particle_new (pt_slowgrav, part_tex_dot, porg, 1.5, pvel, - (vr_data.realtime + 0.2 + (rnd & 7) * 0.02), - (150 + mtwist_rand (&mt) % 6), 1.0, 0.0); - } + for (int i = -16; i < 16; i += 4) { + for (int j = -16; j < 16; j += 4) { + for (int k = -24; k < 32; k += 4) { + float vel = 50 + (mtwist_rand (&mt) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + (mtwist_rand (&mt) & 3), + j + (mtwist_rand (&mt) & 3), + k + (mtwist_rand (&mt) & 3), + 0 + }; + add_particle (pt_grav, org + offs, vel * dir, + 0.2 + (mtwist_rand (&mt) & 7) * 0.02, + 7 + (mtwist_rand (&mt) & 7), 0); + } } } } -static vec3_t avelocities[NUMVERTEXNORMALS]; - static void -R_EntityParticles_ID (const entity_t *ent) +R_DarkFieldParticles_ID (vec4f_t org) { - int i, j = NUMVERTEXNORMALS; - float angle, sp, sy, cp, cy; // cr, sr - float beamlength = 16.0, dist = 64.0; - vec3_t forward, porg; - vec3_t org; - - if (numparticles + j >= r_maxparticles) { + if (!r_particles->int_val) return; - } else if (numparticles + j >= r_maxparticles) { - j = r_maxparticles - numparticles; - } - VectorCopy (Transform_GetWorldPosition (ent->transform), org); + for (int i = -16; i < 16; i += 8) { + for (int j = -16; j < 16; j += 8) { + for (int k = 0; k < 32; k += 8) { + uint32_t rnd = mtwist_rand (&mt); + float vel = 50 + ((rnd >> 9) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + ((rnd >> 3) & 3), + j + ((rnd >> 5) & 3), + k + ((rnd >> 7) & 3), + 0 + }; - if (!avelocities[0][0]) { - for (i = 0; i < NUMVERTEXNORMALS; i++) { - int k; - for (k = 0; k < 3; k++) { - avelocities[i][k] = (mtwist_rand (&mt) & 255) * 0.01; + add_particle (pt_slowgrav, org + offs, vel * dir, + 0.2 + (rnd & 7) * 0.02, + 150 + mtwist_rand (&mt) % 6, 0); } } } +} - for (i = 0; i < j; i++) { - angle = vr_data.realtime * avelocities[i][0]; +static vec4f_t velocities[NUMVERTEXNORMALS]; +static vec4f_t normals[NUMVERTEXNORMALS] = { +#include "anorms.h" +}; + +static void +R_EntityParticles_ID (vec4f_t org) +{ + int i; + float angle, sp, sy, cp, cy; // cr, sr + float beamlength = 16.0, dist = 64.0; + + if (!r_particles->int_val) + return; + + for (i = 0; i < NUMVERTEXNORMALS; i++) { + int k; + for (k = 0; k < 3; k++) { + velocities[i][k] = (mtwist_rand (&mt) & 255) * 0.01; + } + } + + vec4f_t zero = {}; + for (i = 0; i < NUMVERTEXNORMALS; i++) { + angle = vr_data.realtime * velocities[i][0]; cy = cos (angle); sy = sin (angle); - angle = vr_data.realtime * avelocities[i][1]; + angle = vr_data.realtime * velocities[i][1]; cp = cos (angle); sp = sin (angle); // Next 3 lines results aren't currently used, may be in future. --Despair @@ -1230,262 +1090,152 @@ R_EntityParticles_ID (const entity_t *ent) // sr = sin (angle); // cr = cos (angle); - forward[0] = cp * cy; - forward[1] = cp * sy; - forward[2] = -sp; - - porg[0] = org[0] + r_avertexnormals[i][0] * dist + - forward[0] * beamlength; - porg[1] = org[1] + r_avertexnormals[i][1] * dist + - forward[1] * beamlength; - porg[2] = org[2] + r_avertexnormals[i][2] * dist + - forward[2] * beamlength; - particle_new (pt_explode, part_tex_dot, porg, 1.0, vec3_origin, - vr_data.realtime + 0.01, 0x6f, 1.0, 0); + vec4f_t forward = { cp * cy, cp * sy, -sp, 0 }; + vec4f_t pos = org + normals[i] * dist + forward * beamlength; + //FIXME 0 velocity? + add_particle (pt_explode, pos, zero, 0.01, 0x6f, 0); } } static void -R_RocketTrail_ID (const entity_t *ent) +R_RocketTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - int ramp, rnd; - vec3_t old_origin, org, subtract, vec; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, ent->old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, (maxlen - dist), subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { - rnd = mtwist_rand (&mt); - org[0] = old_origin[0] + ((rnd >> 12) & 7) * (5.0/7.0) - 2.5; - org[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5; - org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5; - ramp = rnd & 3; - - particle_new (pt_fire, part_tex_dot, org, 1.0, vec3_origin, - vr_data.realtime + 2.0, ramp3[ramp], 1.0, ramp); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + vec4f_t zero = {}; + vec4f_t pos = start; + while (len > 0) { + len -= 3; + add_particle (pt_fire, pos + roffs (6), zero, 2, + 0, (mtwist_rand (&mt) & 3)); + pos += vec; } } static void -R_GrenadeTrail_ID (const entity_t *ent) +R_GrenadeTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - unsigned int ramp, rnd; - vec3_t old_origin, org, subtract, vec; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, ent->old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { - rnd = mtwist_rand (&mt); - org[0] = old_origin[0] + ((rnd >> 12) & 7) * (5.0/7.0) - 2.5; - org[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5; - org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5; - ramp = (rnd & 3) + 2; - - particle_new (pt_fire, part_tex_dot, org, 1.0, vec3_origin, - vr_data.realtime + 2.0, ramp3[ramp], 1.0, ramp); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + vec4f_t zero = {}; + vec4f_t pos = start; + while (len > 0) { + len -= 3; + add_particle (pt_fire, pos + roffs (6), zero, 2, + 0, (mtwist_rand (&mt) & 3) + 2); + pos += vec; } } static void -R_BloodTrail_ID (const entity_t *ent) +R_BloodTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - unsigned int rnd; - vec3_t old_origin, subtract, vec, porg; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { - rnd = mtwist_rand (&mt); - porg[0] = old_origin[0] + ((rnd >> 12) & 7) * (5.0/7.0) - 2.5; - porg[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5; - porg[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5; - - particle_new (pt_grav, part_tex_dot, porg, 1.0, vec3_origin, - vr_data.realtime + 2.0, 67 + (rnd & 3), 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + vec4f_t zero = {}; + vec4f_t pos = start; + while (len > 0) { + len -= 3; + add_particle (pt_slowgrav, pos + roffs (6), zero, 2, + 67 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } static void -R_SlightBloodTrail_ID (const entity_t *ent) +R_SlightBloodTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 6.0, len = 0.0; - unsigned int rnd; - vec3_t old_origin, porg, subtract, vec; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { - rnd = mtwist_rand (&mt); - porg[0] = old_origin[0] + ((rnd >> 12) & 7) * (5.0/7.0) - 2.5; - porg[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5; - porg[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5; - - particle_new (pt_grav, part_tex_dot, porg, 1.0, vec3_origin, - vr_data.realtime + 1.5, 67 + (rnd & 3), 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + vec4f_t zero = {}; + vec4f_t pos = start; + while (len > 0) { + len -= 6; + add_particle (pt_slowgrav, pos + roffs (6), zero, 2, + 67 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } static void -R_WizTrail_ID (const entity_t *ent) +R_WizTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - static int tracercount; - vec3_t old_origin, pvel, subtract, vec; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { + vec4f_t pos = start; + while (len > 0) { + static int tracercount; + len -= 3; + add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, + 52 + ((tracercount & 4) << 1), 0); tracercount++; - if (tracercount & 1) { - pvel[0] = 30.0 * vec[1]; - pvel[1] = 30.0 * -vec[0]; - } else { - pvel[0] = 30.0 * -vec[1]; - pvel[1] = 30.0 * vec[0]; - } - pvel[2] = 0.0; - - particle_new (pt_static, part_tex_dot, old_origin, 1.0, pvel, - vr_data.realtime + 0.5, 52 + ((tracercount & 4) << 1), - 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += vec; } } static void -R_FlameTrail_ID (const entity_t *ent) +R_FlameTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - static int tracercount; - vec3_t old_origin, pvel, subtract, vec; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { + vec4f_t pos = start; + while (len > 0) { + static int tracercount; + len -= 3; + add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, + 230 + ((tracercount & 4) << 1), 0); tracercount++; - if (tracercount & 1) { - pvel[0] = 30.0 * vec[1]; - pvel[1] = 30.0 * -vec[0]; - } else { - pvel[0] = 30.0 * -vec[1]; - pvel[1] = 30.0 * vec[0]; - } - pvel[2] = 0.0; - - particle_new (pt_static, part_tex_dot, old_origin, 1.0, pvel, - vr_data.realtime + 0.5, 230 + ((tracercount & 4) << 1), - 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += vec; } } static void -R_VoorTrail_ID (const entity_t *ent) +R_VoorTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - unsigned int rnd; - vec3_t old_origin, porg, subtract, vec; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { - rnd = mtwist_rand (&mt); - porg[0] = old_origin[0] + ((rnd >> 3) & 15) - 7.5; - porg[1] = old_origin[1] + ((rnd >> 7) & 15) - 7.5; - porg[2] = old_origin[2] + ((rnd >> 11) & 15) - 7.5; - - particle_new (pt_static, part_tex_dot, porg, 1.0, vec3_origin, - vr_data.realtime + 0.3, 9 * 16 + 8 + (rnd & 3), - 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + vec4f_t zero = {}; + vec4f_t pos = start; + while (len > 0) { + len -= 3; + add_particle (pt_static, pos + roffs (16), zero, 0.3, + 9 * 16 + 8 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } @@ -1493,10 +1243,8 @@ void gl_R_DrawParticles (void) { unsigned char *at; - int activeparticles, maxparticle, j, vacount; - unsigned int k; + int vacount; float minparticledist, scale; - particle_t *part; vec3_t up_scale, right_scale, up_right_scale, down_right_scale; varray_t2f_c4ub_v3f_t *VA; @@ -1511,26 +1259,43 @@ gl_R_DrawParticles (void) minparticledist = DotProduct (r_refdef.viewposition, vpn) + r_particles_nearclip->value; - activeparticles = 0; vacount = 0; VA = particleVertexArray; - maxparticle = -1; - j = 0; - for (k = 0, part = particles; k < numparticles; k++, part++) { + vec4f_t gravity = {0, 0, -vr_data.gravity, 0}; + + unsigned j = 0; + for (unsigned i = 0; i < numparticles; i++) { + particle_t *p = &particles[i]; + partparm_t *parm = &partparams[i]; + + if (p->live <= 0 || p->ramp >= parm->ramp_max + || p->alpha <= 0 || p->scale <= 0) { + continue; + } + const int *ramp = partramps[j]; + if (i > j) { + particles[j] = *p; + partparams[j] = *parm; + partramps[j] = ramp; + } + p = &particles[j]; + parm = &partparams[j]; + j += 1; + // Don't render particles too close to us. // Note, we must still do physics and such on them. - if (!(DotProduct (part->org, vpn) < minparticledist)) { - at = (byte *) &d_8to24table[(byte) part->color]; + if (!(DotProduct (p->pos, vpn) < minparticledist)) { + at = (byte *) &d_8to24table[(byte) p->icolor]; VA[0].color[0] = at[0]; VA[0].color[1] = at[1]; VA[0].color[2] = at[2]; - VA[0].color[3] = part->alpha * 255; + VA[0].color[3] = p->alpha * 255; memcpy (VA[1].color, VA[0].color, sizeof (VA[0].color)); memcpy (VA[2].color, VA[0].color, sizeof (VA[0].color)); memcpy (VA[3].color, VA[0].color, sizeof (VA[0].color)); - switch (part->tex) { + switch (p->tex) { case part_tex_dot: VA[0].texcoord[0] = 0.0; VA[0].texcoord[1] = 0.0; @@ -1563,7 +1328,7 @@ gl_R_DrawParticles (void) break; } - scale = part->scale; + scale = p->scale; VectorScale (vup, scale, up_scale); VectorScale (vright, scale, right_scale); @@ -1571,10 +1336,10 @@ gl_R_DrawParticles (void) VectorAdd (right_scale, up_scale, up_right_scale); VectorSubtract (right_scale, up_scale, down_right_scale); - VectorAdd (part->org, down_right_scale, VA[0].vertex); - VectorSubtract (part->org, up_right_scale, VA[1].vertex); - VectorSubtract (part->org, down_right_scale, VA[2].vertex); - VectorAdd (part->org, up_right_scale, VA[3].vertex); + VectorAdd (p->pos, down_right_scale, VA[0].vertex); + VectorSubtract (p->pos, up_right_scale, VA[1].vertex); + VectorSubtract (p->pos, down_right_scale, VA[2].vertex); + VectorAdd (p->pos, up_right_scale, VA[3].vertex); VA += 4; vacount += 4; @@ -1587,17 +1352,19 @@ gl_R_DrawParticles (void) } } - part->phys (part); - - // LordHavoc: immediate removal of unnecessary particles (must be done - // to ensure compactor below operates properly in all cases) - if (part->die < vr_data.realtime) { - freeparticles[j++] = part; - } else { - maxparticle = k; - activeparticles++; + float dT = vr_data.frametime; + p->pos += dT * p->vel; + p->vel += dT * (p->vel * parm->drag + gravity * parm->drag[3]); + p->ramp += dT * parm->ramp; + p->live -= dT; + p->alpha -= dT * parm->alpha_rate; + p->scale += dT * parm->scale_rate; + if (ramp) { + p->icolor = ramp[(int)p->ramp]; } } + numparticles = j; + if (vacount) { if (partUseVA) { qfglDrawElements (GL_QUADS, vacount, GL_UNSIGNED_INT, pVAindices); @@ -1615,37 +1382,28 @@ gl_R_DrawParticles (void) } } - k = 0; - while (maxparticle >= activeparticles) { - *freeparticles[k++] = particles[maxparticle--]; - while (maxparticle >= activeparticles && - particles[maxparticle].die <= vr_data.realtime) - maxparticle--; - } - numparticles = activeparticles; - qfglColor3ubv (color_white); qfglDepthMask (GL_TRUE); } static void -gl_R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale, - const vec3_t vel, float die, int color, float alpha, +gl_R_Particle_New (ptype_t type, int texnum, vec4f_t org, float scale, + vec4f_t vel, float live, int color, float alpha, float ramp) { if (numparticles >= r_maxparticles) return; - particle_new (type, texnum, org, scale, vel, die, color, alpha, ramp); + particle_new (type, texnum, org, scale, vel, live, color, alpha, ramp); } static void -gl_R_Particle_NewRandom (ptype_t type, int texnum, const vec3_t org, - int org_fuzz, float scale, int vel_fuzz, float die, +gl_R_Particle_NewRandom (ptype_t type, int texnum, vec4f_t org, + int org_fuzz, float scale, int vel_fuzz, float live, int color, float alpha, float ramp) { if (numparticles >= r_maxparticles) return; - particle_new_random (type, texnum, org, org_fuzz, scale, vel_fuzz, die, + particle_new_random (type, texnum, org, org_fuzz, scale, vel_fuzz, live, color, alpha, ramp); } diff --git a/libs/video/renderer/glsl/glsl_particles.c b/libs/video/renderer/glsl/glsl_particles.c index b8bdf56ca..9975f73f2 100644 --- a/libs/video/renderer/glsl/glsl_particles.c +++ b/libs/video/renderer/glsl/glsl_particles.c @@ -61,21 +61,11 @@ #include "r_internal.h" -static mtstate_t mt; // private PRNG state - //FIXME not part of GLES, but needed for GL #ifndef GL_VERTEX_PROGRAM_POINT_SIZE # define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 #endif -//FIXME should not be here -static int ramp1[8] = { 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61 }; -//static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 }; -static int ramp3[8] = { 0x6d, 0x6b, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; -static vec3_t vertex_normals[NUMVERTEXNORMALS] = { -#include "anorms.h" -}; - static GLushort *pVAindices; static partvert_t *particleVertexArray; @@ -143,32 +133,33 @@ static struct { {"fog", 1}, }; +static mtstate_t mt; // private PRNG state + inline static void -particle_new (ptype_t type, int texnum, const vec3_t org, float scale, - const vec3_t vel, float die, int color, float alpha, float ramp) +particle_new (ptype_t type, int texnum, vec4f_t pos, float scale, + vec4f_t vel, float live, int color, float alpha, float ramp) { - particle_t *part; + if (numparticles >= r_maxparticles) + return; + particle_t *p = &particles[numparticles]; + partparm_t *parm = &partparams[numparticles]; + const int **rampptr = &partramps[numparticles]; + numparticles += 1; -/* - // Uncomment this for particle debugging! - if (numparticles >= r_maxparticles) { - Sys_Error ("FAILED PARTICLE ALLOC!"); - return NULL; + p->pos = pos; + p->vel = vel; + p->icolor = color; + p->alpha = alpha; + p->tex = texnum; + p->ramp = ramp; + p->scale = scale; + p->live = live; + + *parm = R_ParticlePhysics (type); + *rampptr = R_ParticleRamp (type); + if (*rampptr) { + p->icolor = (*rampptr) [(int) p->ramp]; } -*/ - - part = &particles[numparticles++]; - - VectorCopy (org, part->org); - part->color = color; - part->tex = texnum; - part->scale = scale; - part->alpha = alpha; - VectorCopy (vel, part->vel); - part->type = type; - part->die = die; - part->ramp = ramp; - part->phys = R_ParticlePhysics (type); } /* @@ -178,30 +169,32 @@ particle_new (ptype_t type, int texnum, const vec3_t org, float scale, going to bother using this function. */ inline static void -particle_new_random (ptype_t type, int texnum, const vec3_t org, int org_fuzz, - float scale, int vel_fuzz, float die, int color, +particle_new_random (ptype_t type, int texnum, vec4f_t org, int org_fuzz, + float scale, int vel_fuzz, float live, int color, float alpha, float ramp) { float o_fuzz = org_fuzz, v_fuzz = vel_fuzz; int rnd; - vec3_t porg, pvel; + vec4f_t porg, pvel; rnd = mtwist_rand (&mt); porg[0] = o_fuzz * ((rnd & 63) - 31.5) / 63.0 + org[0]; porg[1] = o_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0 + org[1]; porg[2] = o_fuzz * (((rnd >> 10) & 63) - 31.5) / 63.0 + org[2]; + porg[3] = 1; rnd = mtwist_rand (&mt); pvel[0] = v_fuzz * ((rnd & 63) - 31.5) / 63.0; pvel[1] = v_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0; pvel[2] = v_fuzz * (((rnd >> 10) & 63) - 31.5) / 63.0; + pvel[3] = 0; - particle_new (type, texnum, porg, scale, pvel, die, color, alpha, ramp); + particle_new (type, texnum, porg, scale, pvel, live, color, alpha, ramp); } /* inline static void -particle_new_veryrandom (ptype_t type, int texnum, const vec3_t org, - int org_fuzz, float scale, int vel_fuzz, float die, +particle_new_veryrandom (ptype_t type, int texnum, vec4f_t org, + int org_fuzz, float scale, int vel_fuzz, float live, int color, float alpha, float ramp) { vec3_t porg, pvel; @@ -212,10 +205,39 @@ particle_new_veryrandom (ptype_t type, int texnum, const vec3_t org, pvel[0] = qfrandom (vel_fuzz * 2) - vel_fuzz; pvel[1] = qfrandom (vel_fuzz * 2) - vel_fuzz; pvel[2] = qfrandom (vel_fuzz * 2) - vel_fuzz; - particle_new (type, texnum, porg, scale, pvel, die, color, alpha, ramp); + particle_new (type, texnum, porg, scale, pvel, live, color, alpha, ramp); } */ +static vec4f_t +roffs (int mod) +{ + vec4f_t offs = { + (mtwist_rand (&mt) % mod) - 0.5 * (mod - 1), + (mtwist_rand (&mt) % mod) - 0.5 * (mod - 1), + (mtwist_rand (&mt) % mod) - 0.5 * (mod - 1), + 0 + }; + return offs; +} + +static vec4f_t +tracer_vel (int tracercount, vec4f_t vec) +{ + if (tracercount & 1) { + return (vec4f_t) { vec[1], -vec[0], 0, 0 }; + } else { + return (vec4f_t) { -vec[1], vec[0], 0, 0 }; + } +} + +static void +add_particle (ptype_t type, vec4f_t pos, vec4f_t vel, float live, int color, + float ramp) +{ + particle_new (type, part_tex_dot, pos, 1, vel, live, color, 1, ramp); +} + void glsl_R_ClearParticles (void) { @@ -312,8 +334,7 @@ glsl_R_ReadPointFile_f (void) { const char *name; char *mapname; - int c, r; - vec3_t org; + int c; QFile *f; mapname = strdup (r_worldentity.renderer.model->path); @@ -332,11 +353,13 @@ glsl_R_ReadPointFile_f (void) Sys_MaskPrintf (SYS_dev, "Reading %s...\n", name); c = 0; + vec4f_t zero = {}; for (;;) { char buf[64]; + vec4f_t org = { 0, 0, 0, 1 }; Qgets (f, buf, sizeof (buf)); - r = sscanf (buf, "%f %f %f\n", &org[0], &org[1], &org[2]); + int r = sscanf (buf, "%f %f %f\n", &org[0], &org[1], &org[2]); if (r != 3) break; c++; @@ -345,7 +368,7 @@ glsl_R_ReadPointFile_f (void) Sys_MaskPrintf (SYS_dev, "Not enough free particles\n"); break; } else { - particle_new (pt_static, part_tex_dot, org, 1.5, vec3_origin, + particle_new (pt_static, part_tex_dot, org, 1.5, zero, 99999, (-c) & 15, 1.0, 0.0); } } @@ -354,18 +377,18 @@ glsl_R_ReadPointFile_f (void) } static void -R_ParticleExplosion_QF (const vec3_t org) +R_ParticleExplosion_QF (vec4f_t org) { // R_NewExplosion (org); if (numparticles >= r_maxparticles) return; particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8, - vr_data.realtime + 5.0, (mtwist_rand (&mt) & 7) + 8, + 5.0, (mtwist_rand (&mt) & 7) + 8, 0.5 + qfrandom (0.25), 0.0); } static void -R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength) +R_ParticleExplosion2_QF (vec4f_t org, int colorStart, int colorLength) { unsigned int i, j = 512; @@ -376,13 +399,13 @@ R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength) for (i = 0; i < j; i++) { particle_new_random (pt_blob, part_tex_dot, org, 16, 2, 256, - vr_data.realtime + 0.3, + 0.3, colorStart + (i % colorLength), 1.0, 0.0); } } static void -R_BlobExplosion_QF (const vec3_t org) +R_BlobExplosion_QF (vec4f_t org) { unsigned int i; unsigned int j = 1024; @@ -394,28 +417,28 @@ R_BlobExplosion_QF (const vec3_t org) for (i = 0; i < j >> 1; i++) { particle_new_random (pt_blob, part_tex_dot, org, 12, 2, 256, - vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 7) * 0.05, + 1.0 + (mtwist_rand (&mt) & 7) * 0.05, 66 + i % 6, 1.0, 0.0); } for (i = 0; i < j / 2; i++) { particle_new_random (pt_blob2, part_tex_dot, org, 12, 2, 256, - vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 7) * 0.05, + 1.0 + (mtwist_rand (&mt) & 7) * 0.05, 150 + i % 6, 1.0, 0.0); } } static inline void -R_RunSparkEffect_QF (const vec3_t org, int count, int ofuzz) +R_RunSparkEffect_QF (vec4f_t org, int count, int ofuzz) { - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; + + vec4f_t zero = {}; particle_new (pt_smokecloud, part_tex_smoke, org, ofuzz * 0.08, - vec3_origin, vr_data.realtime + 9, 12 + (mtwist_rand (&mt) & 3), + zero, 9, 12 + (mtwist_rand (&mt) & 3), 0.25 + qfrandom (0.125), 0.0); - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - if (count) { + if (count > 0) { int orgfuzz = ofuzz * 3 / 4; if (orgfuzz < 1) orgfuzz = 1; @@ -424,30 +447,30 @@ R_RunSparkEffect_QF (const vec3_t org, int count, int ofuzz) int color = mtwist_rand (&mt) & 7; particle_new_random (pt_fallfadespark, part_tex_dot, org, orgfuzz, - 0.7, 96, vr_data.realtime + 5.0, ramp1[color], - 1.0, color); + 0.7, 96, 5.0, 0, 1.0, color); } } } static inline void -R_BloodPuff_QF (const vec3_t org, int count) +R_BloodPuff_QF (vec4f_t org, int count) { - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - particle_new (pt_bloodcloud, part_tex_smoke, org, count / 5, vec3_origin, - vr_data.realtime + 99.0, 70 + (mtwist_rand (&mt) & 3), 0.5, 0.0); + vec4f_t zero = {}; + particle_new (pt_bloodcloud, part_tex_smoke, org, count / 5, zero, + 99.0, 70 + (mtwist_rand (&mt) & 3), 0.5, 0.0); } static void -R_BloodPuffEffect_QF (const vec3_t org, int count) +R_BloodPuffEffect_QF (vec4f_t org, int count) { R_BloodPuff_QF (org, count); } static void -R_GunshotEffect_QF (const vec3_t org, int count) +R_GunshotEffect_QF (vec4f_t org, int count) { int scale = 16; @@ -456,170 +479,133 @@ R_GunshotEffect_QF (const vec3_t org, int count) } static void -R_LightningBloodEffect_QF (const vec3_t org) +R_LightningBloodEffect_QF (vec4f_t org) { - int count = 7; + if (!r_particles->int_val) + return; R_BloodPuff_QF (org, 50); - if (numparticles >= r_maxparticles) - return; - particle_new (pt_smokecloud, part_tex_smoke, org, 3.0, vec3_origin, - vr_data.realtime + 9.0, 12 + (mtwist_rand (&mt) & 3), + vec4f_t zero = {}; + particle_new (pt_smokecloud, part_tex_smoke, org, 3.0, zero, + 9.0, 12 + (mtwist_rand (&mt) & 3), 0.25 + qfrandom (0.125), 0.0); - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - while (count--) + for (int count = 7; count-- > 0; ) { particle_new_random (pt_fallfade, part_tex_spark, org, 12, 2.0, 128, - vr_data.realtime + 5.0, 244 + (count % 3), - 1.0, 0.0); + 5.0, 244 + (count % 3), 1.0, 0.0); + } } static void -R_RunParticleEffect_QF (const vec3_t org, const vec3_t dir, int color, +R_RunParticleEffect_QF (vec4f_t org, vec4f_t dir, int color, int count) { - float scale; - int i; - vec3_t porg; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - scale = pow (count, 0.23); // calculate scale before clipping to part. max + float scale = pow (count, 0.23); - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - - for (i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { int rnd = mtwist_rand (&mt); - porg[0] = org[0] + scale * (((rnd >> 3) & 15) - 7.5); - porg[1] = org[1] + scale * (((rnd >> 7) & 15) - 7.5); - porg[2] = org[2] + scale * (((rnd >> 11) & 15) - 7.5); // Note that ParseParticleEffect handles (dir * 15) - particle_new (pt_grav, part_tex_dot, porg, 1.5, dir, - vr_data.realtime + 0.1 * (i % 5), + particle_new (pt_grav, part_tex_dot, org + scale * roffs (16), 1.5, + dir, 0.1 * (i % 5), (color & ~7) + (rnd & 7), 1.0, 0.0); } } static void -R_SpikeEffect_QF (const vec3_t org) +R_SpikeEffect_QF (vec4f_t org) { R_RunSparkEffect_QF (org, 5, 8); } static void -R_SuperSpikeEffect_QF (const vec3_t org) +R_SuperSpikeEffect_QF (vec4f_t org) { R_RunSparkEffect_QF (org, 10, 8); } static void -R_KnightSpikeEffect_QF (const vec3_t org) +R_KnightSpikeEffect_QF (vec4f_t org) { - unsigned int count = 10; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - particle_new (pt_smokecloud, part_tex_smoke, org, 1.0, vec3_origin, - vr_data.realtime + 9.0, 234, 0.25 + qfrandom (0.125), 0.0); - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - while (count--) + vec4f_t zero = {}; + particle_new (pt_smokecloud, part_tex_smoke, org, 1.0, zero, + 9.0, 234, 0.25 + qfrandom (0.125), 0.0); + + for (int count = 10; count-- > 0; ) { particle_new_random (pt_fallfade, part_tex_dot, org, 6, 0.7, 96, - vr_data.realtime + 5.0, 234, 1.0, 0.0); + 5.0, 234, 1.0, 0.0); + } } static void -R_WizSpikeEffect_QF (const vec3_t org) +R_WizSpikeEffect_QF (vec4f_t org) { - unsigned int count = 15; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - particle_new (pt_smokecloud, part_tex_smoke, org, 2.0, vec3_origin, - vr_data.realtime + 9.0, 63, 0.25 + qfrandom (0.125), 0.0); - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - while (count--) + vec4f_t zero = {}; + particle_new (pt_smokecloud, part_tex_smoke, org, 2.0, zero, + 9.0, 63, 0.25 + qfrandom (0.125), 0.0); + + for (int count = 15; count-- > 0; ) { particle_new_random (pt_fallfade, part_tex_dot, org, 12, 0.7, 96, - vr_data.realtime + 5.0, 63, 1.0, 0.0); + 5.0, 63, 1.0, 0.0); + } } static void -R_LavaSplash_QF (const vec3_t org) +R_LavaSplash_QF (vec4f_t org) { - float vel; - int rnd, i, j; - int k = 256; - vec3_t dir, porg, pvel; - - if (numparticles + k >= r_maxparticles) { + if (!r_particles->int_val) return; - } // else if (numparticles + k >= r_maxparticles) { -// k = r_maxparticles - numparticles; -// } - dir[2] = 256; - for (i = -128; i < 128; i += 16) { - for (j = -128; j < 128; j += 16) { - rnd = mtwist_rand (&mt); - dir[0] = j + (rnd & 7); - dir[1] = i + ((rnd >> 6) & 7); - - porg[0] = org[0] + dir[0]; - porg[1] = org[1] + dir[1]; - porg[2] = org[2] + ((rnd >> 9) & 63); - - VectorNormalize (dir); - rnd = mtwist_rand (&mt); - vel = 50.0 + 0.5 * (float) (rnd & 127); - VectorScale (dir, vel, pvel); - particle_new (pt_grav, part_tex_dot, porg, 3, pvel, - vr_data.realtime + 2.0 + ((rnd >> 7) & 31) * 0.02, + for (int i = -16; i < 16; i++) { + for (int j = -16; j < 16; j++) { + uint32_t rnd = mtwist_rand (&mt); + float vel = 50.0 + 0.5 * (mtwist_rand (&mt) & 127); + vec4f_t dir = { + j * 8 + (rnd & 7), + i * 8 + ((rnd >> 6) & 7), + 256, + 0 + }; + vec4f_t offs = { dir[0], dir[1], ((rnd >> 9) & 63), 0 }; + dir = normalf (dir); + particle_new (pt_grav, part_tex_dot, org + offs, 3, vel * dir, + 2.0 + ((rnd >> 7) & 31) * 0.02, 224 + ((rnd >> 12) & 7), 0.75, 0.0); } } } static void -R_TeleportSplash_QF (const vec3_t org) +R_TeleportSplash_QF (vec4f_t org) { - float vel; - int rnd, i, j, k; - int l = 896; - vec3_t dir, pdir, porg, pvel; - - if (numparticles + l >= r_maxparticles) { + if (!r_particles->int_val) return; - } // else if (numparticles + l >= r_maxparticles) { -// l = r_maxparticles - numparticles; -// } - for (k = -24; k < 32; k += 4) { - dir[2] = k * 8; - for (i = -16; i < 16; i += 4) { - dir[1] = i * 8; - for (j = -16; j < 16; j += 4) { - dir[0] = j * 8; - - VectorCopy (dir, pdir); - VectorNormalize (pdir); - - rnd = mtwist_rand (&mt); - porg[0] = org[0] + i + (rnd & 3); - porg[1] = org[1] + j + ((rnd >> 2) & 3); - porg[2] = org[2] + k + ((rnd >> 4) & 3); - - vel = 50 + ((rnd >> 6) & 63); - VectorScale (pdir, vel, pvel); - particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel, - (vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 15) * 0.01), + for (int k = -24; k < 32; k += 4) { + for (int i = -16; i < 16; i += 4) { + for (int j = -16; j < 16; j += 4) { + uint32_t rnd = mtwist_rand (&mt); + float vel = 50 + ((rnd >> 6) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + (rnd & 3), + j + ((rnd >> 2) & 3), + k + ((rnd >> 4) & 3), + 0 + }; + particle_new (pt_grav, part_tex_spark, org + offs, 0.6, + vel * dir, + (0.2 + (mtwist_rand (&mt) & 15) * 0.01), (7 + ((rnd >> 12) & 7)), 1.0, 0.0); } } @@ -627,320 +613,272 @@ R_TeleportSplash_QF (const vec3_t org) } static void -R_RocketTrail_QF (const entity_t *ent) +R_RocketTrail_QF (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - vec3_t old_origin, vec; - vec3_t org; - if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 1.5 + qfrandom (1.5); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - 3) * vec; + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; + float pscale = 1.5 + qfrandom (1.5); while (len < maxlen) { - pscalenext = 1.5 + qfrandom (1.5); - dist = (pscale + pscalenext) * 3.0; - percent = len * origlen; + float pscalenext = 1.5 + qfrandom (1.5); + float dist = (pscale + pscalenext) * 3.0; + float percent = len * origlen; - particle_new (pt_smoke, part_tex_smoke, old_origin, - pscale + percent * 4.0, vec3_origin, - vr_data.realtime + 2.0 - percent * 2.0, + particle_new (pt_smoke, part_tex_smoke, pos, + pscale + percent * 4.0, zero, + 2.0 - percent * 2.0, 12 + (mtwist_rand (&mt) & 3), 0.5 + qfrandom (0.125) - percent * 0.40, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorMultAdd (old_origin, len, vec, old_origin); + pos += step; pscale = pscalenext; } } static void -R_GrenadeTrail_QF (const entity_t *ent) +R_GrenadeTrail_QF (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - vec3_t old_origin, vec; - vec3_t org; - if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 6.0 + qfrandom (7.0); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - 3) * vec; + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; + float pscale = 6.0 + qfrandom (7.0); while (len < maxlen) { - pscalenext = 6.0 + qfrandom (7.0); - dist = (pscale + pscalenext) * 2.0; - percent = len * origlen; + float pscalenext = 6.0 + qfrandom (7.0); + float dist = (pscale + pscalenext) * 2.0; + float percent = len * origlen; - particle_new (pt_smoke, part_tex_smoke, old_origin, - pscale + percent * 4.0, vec3_origin, - vr_data.realtime + 2.0 - percent * 2.0, + particle_new (pt_smoke, part_tex_smoke, pos, + pscale + percent * 4.0, zero, + 2.0 - percent * 2.0, 1 + (mtwist_rand (&mt) & 3), 0.625 + qfrandom (0.125) - percent * 0.40, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorMultAdd (old_origin, len, vec, old_origin); + pos += step; pscale = pscalenext; } } static void -R_BloodTrail_QF (const entity_t *ent) +R_BloodTrail_QF (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - int j; - vec3_t old_origin, porg, pvel, vec; - vec3_t org; - if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 5.0 + qfrandom (10.0); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - 3) * vec; + + float len = 0; + vec4f_t pos = start; + float pscale = 5.0 + qfrandom (10.0); while (len < maxlen) { - pscalenext = 5.0 + qfrandom (10.0); - dist = (pscale + pscalenext) * 1.5; + float pscalenext = 5.0 + qfrandom (10.0); + float dist = (pscale + pscalenext) * 1.5; + float percent = len * origlen; + vec4f_t vel = roffs (24); + vel[2] -= percent * 40; - for (j = 0; j < 3; j++) { - pvel[j] = qfrandom (24.0) - 12.0; - porg[j] = old_origin[j] + qfrandom (3.0) - 1.5; - } - - percent = len * origlen; - pvel[2] -= percent * 40.0; - - particle_new (pt_grav, part_tex_smoke, porg, pscale, pvel, - vr_data.realtime + 2.0 - percent * 2.0, + particle_new (pt_grav, part_tex_smoke, pos + roffs (4), pscale, vel, + 2.0 - percent * 2.0, 68 + (mtwist_rand (&mt) & 3), 1.0, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorMultAdd (old_origin, len, vec, old_origin); + pos += step; pscale = pscalenext; } } static void -R_SlightBloodTrail_QF (const entity_t *ent) +R_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - int j; - vec3_t old_origin, porg, pvel, vec; - vec3_t org; - if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 1.5 + qfrandom (7.5); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - 3) * vec; + + float len = 0; + vec4f_t pos = start; + float pscale = 1.5 + qfrandom (7.5); while (len < maxlen) { - pscalenext = 1.5 + qfrandom (7.5); - dist = (pscale + pscalenext) * 1.5; + float pscalenext = 1.5 + qfrandom (7.5); + float dist = (pscale + pscalenext) * 1.5; + float percent = len * origlen; + vec4f_t vel = roffs (12); + vel[2] -= percent * 40; - for (j = 0; j < 3; j++) { - pvel[j] = (qfrandom (12.0) - 6.0); - porg[j] = old_origin[j] + qfrandom (3.0) - 1.5; - } - - percent = len * origlen; - pvel[2] -= percent * 40; - - particle_new (pt_grav, part_tex_smoke, porg, pscale, pvel, - vr_data.realtime + 1.5 - percent * 1.5, + particle_new (pt_grav, part_tex_smoke, pos + roffs (4), pscale, vel, + 1.5 - percent * 1.5, 68 + (mtwist_rand (&mt) & 3), 0.75, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorMultAdd (old_origin, len, vec, old_origin); + pos += step; pscale = pscalenext; } } static void -R_WizTrail_QF (const entity_t *ent) +R_WizTrail_QF (vec4f_t start, vec4f_t end) { - float maxlen, origlen, percent; - float dist = 3.0, len = 0.0; - static int tracercount; - vec3_t old_origin, pvel, subtract, vec; - vec3_t org; + float dist = 3.0; if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t pos = start; while (len < maxlen) { - percent = len * origlen; + static int tracercount; + float percent = len * origlen; - tracercount++; - if (tracercount & 1) { - pvel[0] = 30.0 * vec[1]; - pvel[1] = 30.0 * -vec[0]; - } else { - pvel[0] = 30.0 * -vec[1]; - pvel[1] = 30.0 * vec[0]; - } - pvel[2] = 0.0; - - particle_new (pt_flame, part_tex_smoke, old_origin, - 2.0 + qfrandom (1.0) - percent * 2.0, pvel, - vr_data.realtime + 0.5 - percent * 0.5, + particle_new (pt_flame, part_tex_smoke, pos, + 2.0 + qfrandom (1.0) - percent * 2.0, + 30 * tracer_vel (tracercount++, vec), + 0.5 - percent * 0.5, 52 + (mtwist_rand (&mt) & 4), 1.0 - percent * 0.125, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += step; } } static void -R_FlameTrail_QF (const entity_t *ent) +R_FlameTrail_QF (vec4f_t start, vec4f_t end) { - float maxlen, origlen, percent; - float dist = 3.0, len = 0.0; - static int tracercount; - vec3_t old_origin, pvel, subtract, vec; - vec3_t org; + float dist = 3.0; if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t pos = start; while (len < maxlen) { - percent = len * origlen; + static int tracercount; + float percent = len * origlen; - tracercount++; - if (tracercount & 1) { - pvel[0] = 30.0 * vec[1]; - pvel[1] = 30.0 * -vec[0]; - } else { - pvel[0] = 30.0 * -vec[1]; - pvel[1] = 30.0 * vec[0]; - } - pvel[2] = 0.0; - - particle_new (pt_flame, part_tex_smoke, old_origin, - 2.0 + qfrandom (1.0) - percent * 2.0, pvel, - vr_data.realtime + 0.5 - percent * 0.5, 234, + particle_new (pt_flame, part_tex_smoke, pos, + 2.0 + qfrandom (1.0) - percent * 2.0, + 30 * tracer_vel (tracercount++, vec), + 0.5 - percent * 0.5, 234, 1.0 - percent * 0.125, 0.0); - if (numparticles >= r_maxparticles) - break; len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += step; } } static void -R_VoorTrail_QF (const entity_t *ent) +R_VoorTrail_QF (vec4f_t start, vec4f_t end) { - float maxlen, origlen, percent; - float dist = 3.0, len = 0.0; - int j; - vec3_t subtract, old_origin, porg, vec; - vec3_t org; + float dist = 3.0; if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; while (len < maxlen) { - percent = len * origlen; + float percent = len * origlen; - for (j = 0; j < 3; j++) - porg[j] = old_origin[j] + qfrandom (16.0) - 8.0; - - particle_new (pt_static, part_tex_dot, porg, 1.0 + qfrandom (1.0), - vec3_origin, vr_data.realtime + 0.3 - percent * 0.3, + particle_new (pt_static, part_tex_dot, pos + roffs (16), + 1.0 + qfrandom (1.0), + zero, 0.3 - percent * 0.3, 9 * 16 + 8 + (mtwist_rand (&mt) & 3), 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += step; } } static void -R_GlowTrail_QF (const entity_t *ent, int glow_color) +R_GlowTrail_QF (vec4f_t start, vec4f_t end, int glow_color) { - float maxlen, origlen, percent; - float dist = 3.0, len = 0.0; - int rnd; - vec3_t old_origin, org, subtract, vec; + float dist = 3.0; if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - VectorScale (vec, (maxlen - dist), subtract); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; while (len < maxlen) { - percent = len * origlen; + float percent = len * origlen; - rnd = mtwist_rand (&mt); - org[0] = old_origin[0] + ((rnd >> 12) & 7) * (5.0/7.0) - 2.5; - org[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5; - org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5; - - particle_new (pt_smoke, part_tex_dot, org, 1.0, vec3_origin, - vr_data.realtime + 2.0 - percent * 0.2, glow_color, - 1.0, 0.0); + particle_new (pt_smoke, part_tex_dot, pos + roffs (5), 1.0, zero, + 2.0 - percent * 0.2, glow_color, 1.0, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += step; } } static void -R_ParticleExplosion_EE (const vec3_t org) +R_ParticleExplosion_EE (vec4f_t org) { /* R_NewExplosion (org); @@ -948,41 +886,31 @@ R_ParticleExplosion_EE (const vec3_t org) if (numparticles >= r_maxparticles) return; particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8, - vr_data.realtime + 5.0, mtwist_rand (&mt) & 255, + 5.0, mtwist_rand (&mt) & 255, 0.5 + qfrandom (0.25), 0.0); } static void -R_TeleportSplash_EE (const vec3_t org) +R_TeleportSplash_EE (vec4f_t org) { - float vel; - int rnd, i, j, k; - int l = 896; - vec3_t dir, porg, pvel; - - if (numparticles + l >= r_maxparticles) { + if (!r_particles->int_val) return; - } // else if (numparticles + l >= r_maxparticles) { -// l = r_maxparticles - numparticles; -// } - for (k = -24; k < 32; k += 4) { - dir[2] = k * 8; - for (i = -16; i < 16; i += 4) { - dir[1] = i * 8; - for (j = -16; j < 16; j += 4) { - dir[0] = j * 8; - - rnd = mtwist_rand (&mt); - porg[0] = org[0] + i + (rnd & 3); - porg[1] = org[1] + j + ((rnd >> 2) & 3); - porg[2] = org[2] + k + ((rnd >> 4) & 3); - - VectorNormalize (dir); - vel = 50 + ((rnd >> 6) & 63); - VectorScale (dir, vel, pvel); - particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel, - (vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 15) * 0.01), + for (int k = -24; k < 32; k += 4) { + for (int i = -16; i < 16; i += 4) { + for (int j = -16; j < 16; j += 4) { + uint32_t rnd = mtwist_rand (&mt); + float vel = 50 + ((rnd >> 6) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + (rnd & 3), + j + ((rnd >> 2) & 3), + k + ((rnd >> 4) & 3), + 0 + }; + particle_new (pt_grav, part_tex_spark, org + offs, 0.6, + vel * dir, + (0.2 + (mtwist_rand (&mt) & 15) * 0.01), qfrandom (1.0), 1.0, 0.0); } } @@ -990,345 +918,274 @@ R_TeleportSplash_EE (const vec3_t org) } static void -R_RocketTrail_EE (const entity_t *ent) +R_RocketTrail_EE (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - vec3_t old_origin, subtract, vec; - vec3_t org; - if (numparticles >= r_maxparticles) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 1.5 + qfrandom (1.5); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + float pscale = 1.5 + qfrandom (1.5); + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; while (len < maxlen) { - pscalenext = 1.5 + qfrandom (1.5); - dist = (pscale + pscalenext) * 3.0; - percent = len * origlen; + float pscalenext = 1.5 + qfrandom (1.5); + float dist = (pscale + pscalenext) * 3.0; + float percent = len * origlen; - particle_new (pt_smoke, part_tex_smoke, old_origin, - pscale + percent * 4.0, vec3_origin, - vr_data.realtime + 2.0 - percent * 2.0, + particle_new (pt_smoke, part_tex_smoke, pos, + pscale + percent * 4.0, zero, + 2.0 - percent * 2.0, mtwist_rand (&mt) & 255, 0.5 + qfrandom (0.125) - percent * 0.40, 0.0); if (numparticles >= r_maxparticles) break; len += dist; - VectorScale (vec, len, subtract); - VectorAdd (old_origin, subtract, old_origin); + pos += len * vec; pscale = pscalenext; } } static void -R_GrenadeTrail_EE (const entity_t *ent) +R_GrenadeTrail_EE (vec4f_t start, vec4f_t end) { - float dist, maxlen, origlen, percent, pscale, pscalenext; - float len = 0.0; - vec3_t old_origin, subtract, vec; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, ent->old_origin, vec); - maxlen = VectorNormalize (vec); - origlen = vr_data.frametime / maxlen; - pscale = 6.0 + qfrandom (7.0); + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + float origlen = vr_data.frametime / maxlen; + float pscale = 6.0 + qfrandom (7.0); + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; while (len < maxlen) { - pscalenext = 6.0 + qfrandom (7.0); - dist = (pscale + pscalenext) * 2.0; - percent = len * origlen; + float pscalenext = 6.0 + qfrandom (7.0); + float dist = (pscale + pscalenext) * 2.0; + float percent = len * origlen; - particle_new (pt_smoke, part_tex_smoke, old_origin, - pscale + percent * 4.0, vec3_origin, - vr_data.realtime + 2.0 - percent * 2.0, + particle_new (pt_smoke, part_tex_smoke, pos, + pscale + percent * 4.0, zero, + 2.0 - percent * 2.0, mtwist_rand (&mt) & 255, 0.625 + qfrandom (0.125) - percent * 0.40, 0.0); - if (numparticles >= r_maxparticles) - break; len += dist; - VectorScale (vec, len, subtract); - VectorAdd (old_origin, subtract, old_origin); + pos += len * vec; pscale = pscalenext; } } static void -R_ParticleExplosion_ID (const vec3_t org) +R_ParticleExplosion_ID (vec4f_t org) { - unsigned int i; - unsigned int j = 1024; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - else if (numparticles + j >= r_maxparticles) - j = r_maxparticles - numparticles; - for (i = 0; i < j >> 1; i++) { - particle_new_random (pt_explode, part_tex_dot, org, 16, 1.0, 256, - vr_data.realtime + 5.0, ramp1[0], 1.0, i & 3); - } - for (i = 0; i < j / 2; i++) { - particle_new_random (pt_explode2, part_tex_dot, org, 16, 1.0, 256, - vr_data.realtime + 5.0, ramp1[0], 1.0, i & 3); + for (int i = 0; i < 1024; i++) { + ptype_t type = i & 1 ? pt_explode2 : pt_explode; + add_particle (type, org + roffs (32), roffs (512), 5, + 0, mtwist_rand (&mt) & 3); } } static void -R_BlobExplosion_ID (const vec3_t org) +R_BlobExplosion_ID (vec4f_t org) { - unsigned int i; - unsigned int j = 1024; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - else if (numparticles + j >= r_maxparticles) - j = r_maxparticles - numparticles; - for (i = 0; i < j >> 1; i++) { - particle_new_random (pt_blob, part_tex_dot, org, 12, 1.0, 256, - vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 8) * 0.05, - 66 + i % 6, 1.0, 0.0); - } - for (i = 0; i < j / 2; i++) { - particle_new_random (pt_blob2, part_tex_dot, org, 12, 1.0, 256, - vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 8) * 0.05, - 150 + i % 6, 1.0, 0.0); + for (int i = 0; i < 1024; i++) { + ptype_t type = i & 1 ? pt_blob : pt_blob2; + int color = i & 1 ? 66 : 150; + add_particle (type, org + roffs (32), roffs (512), + color + mtwist_rand (&mt) % 6, + (color & ~7) + (mtwist_rand (&mt) & 7), 0); } } static inline void // FIXME: inline? -R_RunParticleEffect_ID (const vec3_t org, const vec3_t dir, int color, +R_RunParticleEffect_ID (vec4f_t org, vec4f_t dir, int color, int count) { - float scale; - int i; - vec3_t porg; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - if (count > 130) // calculate scale before clipping to particle max - scale = 3.0; - else if (count > 20) - scale = 2.0; - else - scale = 1.0; - - if (numparticles + count >= r_maxparticles) - count = r_maxparticles - numparticles; - - for (i = 0; i < count; i++) { - int rnd = mtwist_rand (&mt); - - porg[0] = org[0] + scale * (((rnd >> 3) & 15) - 8); - porg[1] = org[1] + scale * (((rnd >> 7) & 15) - 8); - porg[2] = org[2] + scale * (((rnd >> 11) & 15) - 8); - - // Note that ParseParticleEffect handles (dir * 15) - particle_new (pt_grav, part_tex_dot, porg, 1.0, dir, - vr_data.realtime + 0.1 * (i % 5), - (color & ~7) + (rnd & 7), 1.0, 0.0); + for (int i = 0; i < count; i++) { + add_particle (pt_slowgrav, org + roffs (16), + dir/* + roffs (300)*/, + 0.1 * (mtwist_rand (&mt) % 5), + (color & ~7) + (mtwist_rand (&mt) & 7), 0); } } static void -R_BloodPuffEffect_ID (const vec3_t org, int count) +R_BloodPuffEffect_ID (vec4f_t org, int count) { - R_RunParticleEffect_ID (org, vec3_origin, 73, count); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 73, count); } static void -R_GunshotEffect_ID (const vec3_t org, int count) +R_GunshotEffect_ID (vec4f_t org, int count) { - R_RunParticleEffect_ID (org, vec3_origin, 0, count); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 0, count); } static void -R_LightningBloodEffect_ID (const vec3_t org) +R_LightningBloodEffect_ID (vec4f_t org) { - R_RunParticleEffect_ID (org, vec3_origin, 225, 50); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 225, 50); } static void -R_SpikeEffect_ID (const vec3_t org) +R_SpikeEffect_ID (vec4f_t org) { - R_RunParticleEffect_ID (org, vec3_origin, 0, 10); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 0, 10); } static void -R_SuperSpikeEffect_ID (const vec3_t org) +R_SuperSpikeEffect_ID (vec4f_t org) { - R_RunParticleEffect_ID (org, vec3_origin, 0, 20); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 0, 20); } static void -R_KnightSpikeEffect_ID (const vec3_t org) +R_KnightSpikeEffect_ID (vec4f_t org) { - R_RunParticleEffect_ID (org, vec3_origin, 226, 20); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 226, 20); } static void -R_WizSpikeEffect_ID (const vec3_t org) +R_WizSpikeEffect_ID (vec4f_t org) { - R_RunParticleEffect_ID (org, vec3_origin, 20, 30); + vec4f_t zero = {}; + R_RunParticleEffect_ID (org, zero, 20, 30); } static void -R_LavaSplash_ID (const vec3_t org) +R_LavaSplash_ID (vec4f_t org) { - float vel; - int rnd, i, j; - int k = 256; - vec3_t dir, porg, pvel; - - if (numparticles + k >= r_maxparticles) { + if (!r_particles->int_val) return; - } // else if (numparticles + k >= r_maxparticles) { -// k = r_maxparticles - numparticles; -// } - dir[2] = 256; - for (i = -128; i < 128; i += 16) { - for (j = -128; j < 128; j += 16) { - rnd = mtwist_rand (&mt); - dir[0] = j + (rnd & 7); - dir[1] = i + ((rnd >> 6) & 7); - - porg[0] = org[0] + dir[0]; - porg[1] = org[1] + dir[1]; - porg[2] = org[2] + ((rnd >> 9) & 63); - - VectorNormalize (dir); - rnd = mtwist_rand (&mt); - vel = 50 + (rnd & 63); - VectorScale (dir, vel, pvel); - particle_new (pt_grav, part_tex_dot, porg, 1.0, pvel, - vr_data.realtime + 2 + ((rnd >> 7) & 31) * 0.02, - 224 + ((rnd >> 12) & 7), 1.0, 0.0); - } - } -} - -static void -R_TeleportSplash_ID (const vec3_t org) -{ - float vel; - int rnd, i, j, k; - int l = 896; - vec3_t dir, pdir, porg, pvel; - - if (numparticles + l >= r_maxparticles) { - return; - } // else if (numparticles + l >= r_maxparticles) { -// l = r_maxparticles - numparticles; -// } - - for (k = -24; k < 32; k += 4) { - dir[2] = k * 8; - for (i = -16; i < 16; i += 4) { - dir[1] = i * 8; - for (j = -16; j < 16; j += 4) { - dir[0] = j * 8; - - VectorCopy (dir, pdir); - VectorNormalize (pdir); - - rnd = mtwist_rand (&mt); - porg[0] = org[0] + i + (rnd & 3); - porg[1] = org[1] + j + ((rnd >> 2) & 3); - porg[2] = org[2] + k + ((rnd >> 4) & 3); - - vel = 50 + ((rnd >> 6) & 63); - VectorScale (pdir, vel, pvel); - particle_new (pt_grav, part_tex_dot, porg, 1.0, pvel, - (vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 7) * 0.02), - (7 + ((rnd >> 12) & 7)), 1.0, 0.0); + for (int i = -16; i < 16; i++) { + for (int j = -16; j < 16; j++) { + for (int k = 0; k < 1; k++) { + float vel = 50 + (mtwist_rand (&mt) & 63); + vec4f_t dir = { + j * 8 + (mtwist_rand (&mt) & 7), + i * 8 + (mtwist_rand (&mt) & 7), + 256, + 0 + }; + vec4f_t offs = { + dir[0], + dir[1], + (mtwist_rand (&mt) & 63), + 0 + }; + dir = normalf (dir); + add_particle (pt_grav, org + offs, vel * dir, + 2 + (mtwist_rand (&mt) & 31) * 0.02, + 224 + (mtwist_rand (&mt) & 7), 0); } } } } static void -R_DarkFieldParticles_ID (const entity_t *ent) +R_TeleportSplash_ID (vec4f_t org) { - int i, j, k, l = 64; - unsigned int rnd; - float vel; - vec3_t dir, org, porg, pvel; - - if (numparticles + l >= r_maxparticles) { + if (!r_particles->int_val) return; - } // else if (numparticles + l >= r_maxparticles) { -// l = r_maxparticles - numparticles; -// } - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - - for (i = -16; i < 16; i += 8) { - dir [1] = i * 8; - for (j = -16; j < 16; j += 8) { - dir [0] = j * 8; - for (k = 0; k < 32; k += 8) { - dir [2] = k * 8; - rnd = mtwist_rand (&mt); - - porg[0] = org[0] + i + ((rnd >> 3) & 3); - porg[1] = org[1] + j + ((rnd >> 5) & 3); - porg[2] = org[2] + k + ((rnd >> 7) & 3); - - VectorNormalize (dir); - vel = 50 + ((rnd >> 9) & 63); - VectorScale (dir, vel, pvel); - particle_new (pt_slowgrav, part_tex_dot, porg, 1.5, pvel, - (vr_data.realtime + 0.2 + (rnd & 7) * 0.02), - (150 + mtwist_rand (&mt) % 6), 1.0, 0.0); - } + for (int i = -16; i < 16; i += 4) { + for (int j = -16; j < 16; j += 4) { + for (int k = -24; k < 32; k += 4) { + float vel = 50 + (mtwist_rand (&mt) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + (mtwist_rand (&mt) & 3), + j + (mtwist_rand (&mt) & 3), + k + (mtwist_rand (&mt) & 3), + 0 + }; + add_particle (pt_grav, org + offs, vel * dir, + 0.2 + (mtwist_rand (&mt) & 7) * 0.02, + 7 + (mtwist_rand (&mt) & 7), 0); + } } } } -static vec3_t avelocities[NUMVERTEXNORMALS]; +static void +R_DarkFieldParticles_ID (vec4f_t org) +{ + if (!r_particles->int_val) + return; + + for (int i = -16; i < 16; i += 8) { + for (int j = -16; j < 16; j += 8) { + for (int k = 0; k < 32; k += 8) { + uint32_t rnd = mtwist_rand (&mt); + float vel = 50 + ((rnd >> 9) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + ((rnd >> 3) & 3), + j + ((rnd >> 5) & 3), + k + ((rnd >> 7) & 3), + 0 + }; + + add_particle (pt_slowgrav, org + offs, vel * dir, + 0.2 + (rnd & 7) * 0.02, + 150 + mtwist_rand (&mt) % 6, 0); + } + } + } +} + +static vec4f_t velocities[NUMVERTEXNORMALS]; +static vec4f_t normals[NUMVERTEXNORMALS] = { +#include "anorms.h" +}; static void -R_EntityParticles_ID (const entity_t *ent) +R_EntityParticles_ID (vec4f_t org) { - int i, j = NUMVERTEXNORMALS; - float angle, sp, sy, cp, cy; // cr, sr - float beamlength = 16.0, dist = 64.0; - vec3_t forward, porg; - vec3_t org; + int i; + float angle, sp, sy, cp, cy; // cr, sr + float beamlength = 16.0, dist = 64.0; - if (numparticles + j >= r_maxparticles) { + if (!r_particles->int_val) return; - } else if (numparticles + j >= r_maxparticles) { - j = r_maxparticles - numparticles; - } - - VectorCopy (Transform_GetWorldPosition (ent->transform), org); for (i = 0; i < NUMVERTEXNORMALS; i++) { int k; for (k = 0; k < 3; k++) { - avelocities[i][k] = (mtwist_rand (&mt) & 255) * 0.01; + velocities[i][k] = (mtwist_rand (&mt) & 255) * 0.01; } } - for (i = 0; i < j; i++) { - angle = vr_data.realtime * avelocities[i][0]; + vec4f_t zero = {}; + for (i = 0; i < NUMVERTEXNORMALS; i++) { + angle = vr_data.realtime * velocities[i][0]; cy = cos (angle); sy = sin (angle); - angle = vr_data.realtime * avelocities[i][1]; + angle = vr_data.realtime * velocities[i][1]; cp = cos (angle); sp = sin (angle); // Next 3 lines results aren't currently used, may be in future. --Despair @@ -1336,262 +1193,152 @@ R_EntityParticles_ID (const entity_t *ent) // sr = sin (angle); // cr = cos (angle); - forward[0] = cp * cy; - forward[1] = cp * sy; - forward[2] = -sp; - - porg[0] = org[0] + vertex_normals[i][0] * dist + - forward[0] * beamlength; - porg[1] = org[1] + vertex_normals[i][1] * dist + - forward[1] * beamlength; - porg[2] = org[2] + vertex_normals[i][2] * dist + - forward[2] * beamlength; - particle_new (pt_explode, part_tex_dot, porg, 1.0, vec3_origin, - vr_data.realtime + 0.01, 0x6f, 1.0, 0); + vec4f_t forward = { cp * cy, cp * sy, -sp, 0 }; + vec4f_t pos = org + normals[i] * dist + forward * beamlength; + //FIXME 0 velocity? + add_particle (pt_explode, pos, zero, 0.01, 0x6f, 0); } } static void -R_RocketTrail_ID (const entity_t *ent) +R_RocketTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - int ramp, rnd; - vec3_t old_origin, org, subtract, vec; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, ent->old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, (maxlen - dist), subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { - rnd = mtwist_rand (&mt); - org[0] = old_origin[0] + ((rnd >> 12) & 7) * (5.0/7.0) - 2.5; - org[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5; - org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5; - ramp = rnd & 3; - - particle_new (pt_fire, part_tex_dot, org, 1.0, vec3_origin, - vr_data.realtime + 2.0, ramp3[ramp], 1.0, ramp); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + vec4f_t zero = {}; + vec4f_t pos = start; + while (len > 0) { + len -= 3; + add_particle (pt_fire, pos + roffs (6), zero, 2, + 0, (mtwist_rand (&mt) & 3)); + pos += vec; } } static void -R_GrenadeTrail_ID (const entity_t *ent) +R_GrenadeTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - unsigned int ramp, rnd; - vec3_t old_origin, org, subtract, vec; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, ent->old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { - rnd = mtwist_rand (&mt); - org[0] = old_origin[0] + ((rnd >> 12) & 7) * (5.0/7.0) - 2.5; - org[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5; - org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5; - ramp = (rnd & 3) + 2; - - particle_new (pt_fire, part_tex_dot, org, 1.0, vec3_origin, - vr_data.realtime + 2.0, ramp3[ramp], 1.0, ramp); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + vec4f_t zero = {}; + vec4f_t pos = start; + while (len > 0) { + len -= 3; + add_particle (pt_fire, pos + roffs (6), zero, 2, + 0, (mtwist_rand (&mt) & 3) + 2); + pos += vec; } } static void -R_BloodTrail_ID (const entity_t *ent) +R_BloodTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - unsigned int rnd; - vec3_t old_origin, subtract, vec, porg; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { - rnd = mtwist_rand (&mt); - porg[0] = old_origin[0] + ((rnd >> 12) & 7) * (5.0/7.0) - 2.5; - porg[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5; - porg[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5; - - particle_new (pt_grav, part_tex_dot, porg, 1.0, vec3_origin, - vr_data.realtime + 2.0, 67 + (rnd & 3), 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + vec4f_t zero = {}; + vec4f_t pos = start; + while (len > 0) { + len -= 3; + add_particle (pt_slowgrav, pos + roffs (6), zero, 2, + 67 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } static void -R_SlightBloodTrail_ID (const entity_t *ent) +R_SlightBloodTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 6.0, len = 0.0; - unsigned int rnd; - vec3_t old_origin, porg, subtract, vec; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { - rnd = mtwist_rand (&mt); - porg[0] = old_origin[0] + ((rnd >> 12) & 7) * (5.0/7.0) - 2.5; - porg[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5; - porg[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5; - - particle_new (pt_grav, part_tex_dot, porg, 1.0, vec3_origin, - vr_data.realtime + 1.5, 67 + (rnd & 3), 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + vec4f_t zero = {}; + vec4f_t pos = start; + while (len > 0) { + len -= 6; + add_particle (pt_slowgrav, pos + roffs (6), zero, 2, + 67 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } static void -R_WizTrail_ID (const entity_t *ent) +R_WizTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - static int tracercount; - vec3_t old_origin, pvel, subtract, vec; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { + vec4f_t pos = start; + while (len > 0) { + static int tracercount; + len -= 3; + add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, + 52 + ((tracercount & 4) << 1), 0); tracercount++; - if (tracercount & 1) { - pvel[0] = 30.0 * vec[1]; - pvel[1] = 30.0 * -vec[0]; - } else { - pvel[0] = 30.0 * -vec[1]; - pvel[1] = 30.0 * vec[0]; - } - pvel[2] = 0.0; - - particle_new (pt_static, part_tex_dot, old_origin, 1.0, pvel, - vr_data.realtime + 0.5, 52 + ((tracercount & 4) << 1), - 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += vec; } } static void -R_FlameTrail_ID (const entity_t *ent) +R_FlameTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - static int tracercount; - vec3_t old_origin, pvel, subtract, vec; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { + vec4f_t pos = start; + while (len > 0) { + static int tracercount; + len -= 3; + add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, + 230 + ((tracercount & 4) << 1), 0); tracercount++; - if (tracercount & 1) { - pvel[0] = 30.0 * vec[1]; - pvel[1] = 30.0 * -vec[0]; - } else { - pvel[0] = 30.0 * -vec[1]; - pvel[1] = 30.0 * vec[0]; - } - pvel[2] = 0.0; - - particle_new (pt_static, part_tex_dot, old_origin, 1.0, pvel, - vr_data.realtime + 0.5, 230 + ((tracercount & 4) << 1), - 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + pos += vec; } } static void -R_VoorTrail_ID (const entity_t *ent) +R_VoorTrail_ID (vec4f_t start, vec4f_t end) { - float maxlen; - float dist = 3.0, len = 0.0; - unsigned int rnd; - vec3_t old_origin, porg, subtract, vec; - vec3_t org; - - if (numparticles >= r_maxparticles) + if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - maxlen = VectorNormalize (vec); - VectorScale (vec, maxlen - dist, subtract); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); - while (len < maxlen) { - rnd = mtwist_rand (&mt); - porg[0] = old_origin[0] + ((rnd >> 3) & 15) - 7.5; - porg[1] = old_origin[1] + ((rnd >> 7) & 15) - 7.5; - porg[2] = old_origin[2] + ((rnd >> 11) & 15) - 7.5; - - particle_new (pt_static, part_tex_dot, porg, 1.0, vec3_origin, - vr_data.realtime + 0.3, 9 * 16 + 8 + (rnd & 3), - 1.0, 0.0); - if (numparticles >= r_maxparticles) - break; - len += dist; - VectorAdd (old_origin, subtract, old_origin); + vec4f_t zero = {}; + vec4f_t pos = start; + while (len > 0) { + len -= 3; + add_particle (pt_static, pos + roffs (16), zero, 0.3, + 9 * 16 + 8 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } @@ -1599,10 +1346,8 @@ static void draw_qf_particles (void) { byte *at; - int activeparticles, maxparticle, j, vacount; - unsigned k; + int vacount; float minparticledist, scale; - particle_t *part; vec3_t up_scale, right_scale, up_right_scale, down_right_scale; partvert_t *VA; mat4f_t vp_mat; @@ -1634,26 +1379,43 @@ draw_qf_particles (void) minparticledist = DotProduct (r_refdef.viewposition, vpn) + r_particles_nearclip->value; - activeparticles = 0; vacount = 0; VA = particleVertexArray; - maxparticle = -1; - j = 0; - for (k = 0, part = particles; k < numparticles; k++, part++) { + vec4f_t gravity = {0, 0, -vr_data.gravity, 0}; + + unsigned j = 0; + for (unsigned i = 0; i < numparticles; i++) { + particle_t *p = &particles[i]; + partparm_t *parm = &partparams[i]; + + if (p->live <= 0 || p->ramp >= parm->ramp_max + || p->alpha <= 0 || p->scale <= 0) { + continue; + } + const int *ramp = partramps[j]; + if (i > j) { + particles[j] = *p; + partparams[j] = *parm; + partramps[j] = ramp; + } + p = &particles[j]; + parm = &partparams[j]; + j += 1; + // Don't render particles too close to us. // Note, we must still do physics and such on them. - if (!(DotProduct (part->org, vpn) < minparticledist)) { - at = (byte *) &d_8to24table[(byte) part->color]; + if (!(DotProduct (p->pos, vpn) < minparticledist)) { + at = (byte *) &d_8to24table[(byte) p->icolor]; VA[0].color[0] = at[0]; VA[0].color[1] = at[1]; VA[0].color[2] = at[2]; - VA[0].color[3] = part->alpha * 255; + VA[0].color[3] = p->alpha * 255; memcpy (VA[1].color, VA[0].color, sizeof (VA[0].color)); memcpy (VA[2].color, VA[0].color, sizeof (VA[0].color)); memcpy (VA[3].color, VA[0].color, sizeof (VA[0].color)); - switch (part->tex) { + switch (p->tex) { case part_tex_dot: VA[0].texcoord[0] = 0.0; VA[0].texcoord[1] = 0.0; @@ -1686,7 +1448,7 @@ draw_qf_particles (void) break; } - scale = part->scale; + scale = p->scale; VectorScale (vup, scale, up_scale); VectorScale (vright, scale, right_scale); @@ -1694,26 +1456,28 @@ draw_qf_particles (void) VectorAdd (right_scale, up_scale, up_right_scale); VectorSubtract (right_scale, up_scale, down_right_scale); - VectorAdd (part->org, down_right_scale, VA[0].vertex); - VectorSubtract (part->org, up_right_scale, VA[1].vertex); - VectorSubtract (part->org, down_right_scale, VA[2].vertex); - VectorAdd (part->org, up_right_scale, VA[3].vertex); + VectorAdd (p->pos, down_right_scale, VA[0].vertex); + VectorSubtract (p->pos, up_right_scale, VA[1].vertex); + VectorSubtract (p->pos, down_right_scale, VA[2].vertex); + VectorAdd (p->pos, up_right_scale, VA[3].vertex); VA += 4; vacount += 6; } - part->phys (part); - - // LordHavoc: immediate removal of unnecessary particles (must be done - // to ensure compactor below operates properly in all cases) - if (part->die < vr_data.realtime) { - freeparticles[j++] = part; - } else { - maxparticle = k; - activeparticles++; + float dT = vr_data.frametime; + p->pos += dT * p->vel; + p->vel += dT * (p->vel * parm->drag + gravity * parm->drag[3]); + p->ramp += dT * parm->ramp; + p->live -= dT; + p->alpha -= dT * parm->alpha_rate; + p->scale += dT * parm->scale_rate; + if (ramp) { + p->icolor = ramp[(int)p->ramp]; } } + numparticles = j; + qfeglVertexAttribPointer (quake_part.vertex.location, 3, GL_FLOAT, 0, sizeof (partvert_t), &particleVertexArray[0].vertex); @@ -1725,15 +1489,6 @@ draw_qf_particles (void) &particleVertexArray[0].texcoord); qfeglDrawElements (GL_TRIANGLES, vacount, GL_UNSIGNED_SHORT, pVAindices); - k = 0; - while (maxparticle >= activeparticles) { - *freeparticles[k++] = particles[maxparticle--]; - while (maxparticle >= activeparticles && - particles[maxparticle].die <= vr_data.realtime) - maxparticle--; - } - numparticles = activeparticles; - qfeglDepthMask (GL_TRUE); qfeglDisableVertexAttribArray (quake_part.vertex.location); qfeglDisableVertexAttribArray (quake_part.color.location); @@ -1745,10 +1500,8 @@ draw_qf_particles (void) static void draw_id_particles (void) { - int activeparticles, maxparticle, j, vacount; - unsigned k; + int vacount; float minparticledist; - particle_t *part; partvert_t *VA; mat4f_t vp_mat; quat_t fog; @@ -1776,33 +1529,52 @@ draw_id_particles (void) minparticledist = DotProduct (r_refdef.viewposition, vpn) + r_particles_nearclip->value; - activeparticles = 0; vacount = 0; VA = particleVertexArray; - maxparticle = -1; - j = 0; - for (k = 0, part = particles; k < numparticles; k++, part++) { + vec4f_t gravity = {0, 0, -vr_data.gravity, 0}; + + unsigned j = 0; + for (unsigned i = 0; i < numparticles; i++) { + particle_t *p = &particles[i]; + partparm_t *parm = &partparams[i]; + + if (p->live <= 0 || p->ramp >= parm->ramp_max + || p->alpha <= 0 || p->scale <= 0) { + continue; + } + const int *ramp = partramps[j]; + if (i > j) { + particles[j] = *p; + partparams[j] = *parm; + partramps[j] = ramp; + } + p = &particles[j]; + parm = &partparams[j]; + j += 1; + // Don't render particles too close to us. // Note, we must still do physics and such on them. - if (!(DotProduct (part->org, vpn) < minparticledist)) { - VA[0].color[0] = (byte) part->color; - VectorCopy (part->org, VA[0].vertex); + if (!(DotProduct (p->pos, vpn) < minparticledist)) { + VA[0].color[0] = (byte) p->icolor; + VectorCopy (p->pos, VA[0].vertex); VA++; vacount++; } - part->phys (part); - - // LordHavoc: immediate removal of unnecessary particles (must be done - // to ensure compactor below operates properly in all cases) - if (part->die < vr_data.realtime) { - freeparticles[j++] = part; - } else { - maxparticle = k; - activeparticles++; + float dT = vr_data.frametime; + p->pos += dT * p->vel; + p->vel += dT * (p->vel * parm->drag + gravity * parm->drag[3]); + p->ramp += dT * parm->ramp; + p->live -= dT; + p->alpha -= dT * parm->alpha_rate; + p->scale += dT * parm->scale_rate; + if (ramp) { + p->icolor = ramp[(int)p->ramp]; } } + numparticles = j; + qfeglVertexAttribPointer (quake_point.vertex.location, 3, GL_FLOAT, 0, sizeof (partvert_t), &particleVertexArray[0].vertex); @@ -1811,15 +1583,6 @@ draw_id_particles (void) &particleVertexArray[0].color); qfeglDrawArrays (GL_POINTS, 0, vacount); - k = 0; - while (maxparticle >= activeparticles) { - *freeparticles[k++] = particles[maxparticle--]; - while (maxparticle >= activeparticles && - particles[maxparticle].die <= vr_data.realtime) - maxparticle--; - } - numparticles = activeparticles; - qfeglDepthMask (GL_TRUE); qfeglDisableVertexAttribArray (quake_point.vertex.location); qfeglDisableVertexAttribArray (quake_point.color.location); @@ -1840,23 +1603,23 @@ glsl_R_DrawParticles (void) } static void -glsl_R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale, - const vec3_t vel, float die, int color, float alpha, +glsl_R_Particle_New (ptype_t type, int texnum, vec4f_t org, float scale, + vec4f_t vel, float live, int color, float alpha, float ramp) { if (numparticles >= r_maxparticles) return; - particle_new (type, texnum, org, scale, vel, die, color, alpha, ramp); + particle_new (type, texnum, org, scale, vel, live, color, alpha, ramp); } static void -glsl_R_Particle_NewRandom (ptype_t type, int texnum, const vec3_t org, - int org_fuzz, float scale, int vel_fuzz, float die, +glsl_R_Particle_NewRandom (ptype_t type, int texnum, vec4f_t org, + int org_fuzz, float scale, int vel_fuzz, float live, int color, float alpha, float ramp) { if (numparticles >= r_maxparticles) return; - particle_new_random (type, texnum, org, org_fuzz, scale, vel_fuzz, die, + particle_new_random (type, texnum, org, org_fuzz, scale, vel_fuzz, live, color, alpha, ramp); } diff --git a/libs/video/renderer/r_part.c b/libs/video/renderer/r_part.c index d49c224b7..5a610f9f3 100644 --- a/libs/video/renderer/r_part.c +++ b/libs/video/renderer/r_part.c @@ -36,9 +36,11 @@ #include "compat.h" #include "r_internal.h" -unsigned int r_maxparticles, numparticles; -particle_t *active_particles, *free_particles, *particles, **freeparticles; -vec3_t r_pright, r_pup, r_ppn; +unsigned int r_maxparticles, numparticles; +particle_t *particles; +partparm_t *partparams; +const int **partramps; +vec3_t r_pright, r_pup, r_ppn; /* R_MaxParticlesCheck @@ -50,34 +52,30 @@ vec3_t r_pright, r_pup, r_ppn; void R_MaxParticlesCheck (cvar_t *r_particles, cvar_t *r_particles_max) { -/* - Catchall. If the user changed the setting to a number less than zero *or* - if we had a wacky cfg get past the init code check, this will make sure we - don't have problems. Also note that grabbing the var->int_val is IMPORTANT: - Prevents a segfault since if we grabbed the int_val of r_particles_max - we'd sig11 right here at startup. -*/ - if (r_particles && r_particles->int_val) - r_maxparticles = r_particles_max ? r_particles_max->int_val : 0; - else - r_maxparticles = 0; + unsigned maxparticles = 0; + if (r_particles && r_particles->int_val) { + maxparticles = r_particles_max ? r_particles_max->int_val : 0; + } -/* - Be very careful the next time we do something like this. calloc/free are - IMPORTANT and the compiler doesn't know when we do bad things with them. -*/ - if (particles) - free (particles); - if (freeparticles) - free (freeparticles); + if (r_maxparticles == maxparticles) { + return; + } - particles = 0; - freeparticles = 0; + size_t size = sizeof (particle_t) + sizeof (partparm_t) + + sizeof (int *); + + if (particles) { + Sys_Free (particles, r_maxparticles * size); + particles = 0; + partparams = 0; + partramps = 0; + } + r_maxparticles = maxparticles; if (r_maxparticles) { - particles = (particle_t *) calloc (r_maxparticles, sizeof (particle_t)); - freeparticles = (particle_t **) calloc (r_maxparticles, - sizeof (particle_t *)); + particles = Sys_Alloc (r_maxparticles * size); + partparams = (partparm_t *) &particles[r_maxparticles]; + partramps = (const int **) &partparams[r_maxparticles]; } vr_funcs->R_ClearParticles (); @@ -86,226 +84,53 @@ R_MaxParticlesCheck (cvar_t *r_particles, cvar_t *r_particles_max) vr_funcs->R_InitParticles (); } -static int ramp1[8] = { 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61 }; -static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 }; -static int ramp3[8] = { 0x6d, 0x6b, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; - -static inline float -slow_grav (void) -{ - return -vr_data.frametime * vr_data.gravity * 0.0375; -} - -static inline float -grav (void) -{ - return -vr_data.frametime * vr_data.gravity * 0.05; -} - -static inline float -fast_grav (void) -{ - return -vr_data.frametime * vr_data.gravity; -} - -static inline void -add_vel (particle_t *part) -{ - VectorMultAdd (part->org, vr_data.frametime, part->vel, part->org); -} - -static inline void -sub_slowgrav (particle_t *part) -{ - part->vel[2] -= slow_grav (); -} - -static inline void -add_grav (particle_t *part) -{ - part->vel[2] += grav (); -} - -static inline void -sub_grav (particle_t *part) -{ - part->vel[2] -= grav (); -} - -static inline void -add_fastgrav (particle_t *part) -{ - part->vel[2] += fast_grav (); -} - -static inline qboolean -add_ramp (particle_t *part, float time, int max) -{ - part->ramp += vr_data.frametime * time; - if (part->ramp >= max) { - part->die = -1; - return true; - } - return false; -} - -static inline qboolean -fade_alpha (particle_t *part, float time) -{ - part->alpha -= vr_data.frametime * time; - if (part->alpha <= 0.0) { - part->die = -1; - return true; - } - return false; -} - -static void -part_phys_static (particle_t *part) -{ - add_vel (part); -} - -static void -part_phys_grav (particle_t *part) -{ - add_vel (part); - add_grav (part); -} - -static void -part_phys_fire (particle_t *part) -{ - if (add_ramp (part, 5.0, 6)) - return; - add_vel (part); - part->color = ramp3[(int) part->ramp]; - part->alpha = (6.0 - part->ramp) / 6.0; - sub_grav (part); -} - -static void -part_phys_explode (particle_t *part) -{ - if (add_ramp (part, 10.0, 8)) - return; - add_vel (part); - part->color = ramp1[(int) part->ramp]; - VectorMultAdd (part->vel, vr_data.frametime * 4.0, part->vel, part->vel); - add_grav (part); -} - -static void -part_phys_explode2 (particle_t *part) -{ - if (add_ramp (part, 15.0, 8)) - return; - add_vel (part); - part->color = ramp2[(int) part->ramp]; - VectorMultAdd (part->vel, vr_data.frametime, part->vel, part->vel); - add_grav (part); -} - -static void -part_phys_blob (particle_t *part) -{ - add_vel (part); - VectorMultAdd (part->vel, vr_data.frametime * 4.0, part->vel, part->vel); - add_grav (part); -} - -static void -part_phys_blob2 (particle_t *part) -{ - add_vel (part); - part->vel[0] -= part->vel[0] * vr_data.frametime * 4.0; - part->vel[1] -= part->vel[1] * vr_data.frametime * 4.0; - add_grav (part); -} - -static void -part_phys_smoke (particle_t *part) -{ - if (fade_alpha (part, 0.4)) - return; - add_vel (part); - part->scale += vr_data.frametime * 4.0; - //sub_slowgrav (part); -} - -static void -part_phys_smokecloud (particle_t *part) -{ - if (fade_alpha (part, 0.55)) - return; - add_vel (part); - part->scale += vr_data.frametime * 50.0; - sub_slowgrav (part); -} - -static void -part_phys_bloodcloud (particle_t *part) -{ - if (fade_alpha (part, 0.25)) - return; - add_vel (part); - part->scale += vr_data.frametime * 4.0; - add_grav (part); -} - -static void -part_phys_fallfade (particle_t *part) -{ - if (fade_alpha (part, 1.0)) - return; - add_vel (part); - add_fastgrav (part); -} - -static void -part_phys_fallfadespark (particle_t *part) -{ - if (add_ramp (part, 15.0, 8)) - return; - if (fade_alpha (part, 1.0)) - return; - part->color = ramp1[(int) part->ramp]; - add_vel (part); - add_fastgrav (part); -} - -static void -part_phys_flame (particle_t *part) -{ - if (fade_alpha (part, 0.125)) - return; - add_vel (part); - part->scale -= vr_data.frametime * 2.0; -} - -static pt_phys_func part_phys[] = { - part_phys_static, // pt_static - part_phys_grav, // pt_grav - part_phys_grav, // pt_slowgrav - part_phys_fire, // pt_fire - part_phys_explode, // pt_explode - part_phys_explode2, // pt_explode2 - part_phys_blob, // pt_blob - part_phys_blob2, // pt_blob2 - part_phys_smoke, // pt_smoke - part_phys_smokecloud, // pt_smokecloud - part_phys_bloodcloud, // pt_bloodcloud - part_phys_static, // pt_fadespark - part_phys_static, // pt_fadespark2 - part_phys_fallfade, // pt_fallfade - part_phys_fallfadespark,// pt_fallfadespark - part_phys_flame, // pt_flame +static int ramp[] = { + /*ramp1*/ 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61, + /*ramp2*/ 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66, + /*ramp3*/ 0x6d, 0x6b, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, }; -pt_phys_func +static partparm_t part_params[] = { + [pt_static] = {{0, 0, 0, 0}, 0, 1, 0, 0}, + [pt_grav] = {{0, 0, 0, 0.05}, 0, 1, 0, 0}, + [pt_slowgrav] = {{0, 0, 0, 0.05}, 0, 1, 0, 0}, + [pt_fire] = {{0, 0, 0, 0.05}, 5, 6, 0, 5./6}, + [pt_explode] = {{4, 4, 4, 0.05}, 10, 8, 0, 0}, + [pt_explode2] = {{1, 1, 1, 0.05}, 15, 8, 0, 0}, + [pt_blob] = {{4, 4, 4, 0.05}, 0, 1, 0, 0}, + [pt_blob2] = {{4, 4, 0, 0.05}, 0, 1, 0, 0}, + [pt_smoke] = {{0, 0, 0, 0}, 0, 1, 4, 0.4}, + [pt_smokecloud] = {{0, 0, 0, 0.0375}, 0, 1, 50, 0.55}, + [pt_bloodcloud] = {{0, 0, 0, 0.05}, 0, 1, 4, 0.25}, + [pt_fadespark] = {{0, 0, 0, 0}, 0, 1, 0, 0}, + [pt_fadespark2] = {{0, 0, 0, 0}, 0, 1, 0, 0}, + [pt_fallfade] = {{0, 0, 0, 1}, 0, 1, 0, 1}, + [pt_fallfadespark] = {{0, 0, 0, 1}, 15, 8, 0, 1}, + [pt_flame] = {{0, 0, 0, 0}, 0, 1, -2, 0.125}, +}; + +static const int *part_ramps[] = { + [pt_fire] = ramp + 2 * 8, // ramp3 + [pt_explode] = ramp + 0 * 8, // ramp1 + [pt_explode2] = ramp + 1 * 8, // ramp2 + [pt_fallfadespark] = ramp + 0 * 8, // ramp1 + [pt_flame] = 0, +}; + +partparm_t R_ParticlePhysics (ptype_t type) { - if (type > pt_flame) + if (type > pt_flame) { Sys_Error ("R_ParticlePhysics: invalid particle type"); - return part_phys[type]; + } + return part_params[type]; +} + +const int * +R_ParticleRamp (ptype_t type) +{ + if (type > pt_flame) { + Sys_Error ("R_ParticleRamp: invalid particle type"); + } + return part_ramps[type]; } diff --git a/libs/video/renderer/sw/d_part.c b/libs/video/renderer/sw/d_part.c index 38de44a09..b8b5b1c82 100644 --- a/libs/video/renderer/sw/d_part.c +++ b/libs/video/renderer/sw/d_part.c @@ -47,7 +47,7 @@ D_DrawParticle (particle_t *pparticle) int i, izi, pix, count, u, v; // transform point - VectorSubtract (pparticle->org, r_origin, local); + VectorSubtract (pparticle->pos, r_origin, local); transformed[0] = DotProduct (local, r_pright); transformed[1] = DotProduct (local, r_pup); @@ -84,7 +84,7 @@ D_DrawParticle (particle_t *pparticle) for (; count; count--, pz += d_zwidth, pdest += screenwidth) { if (pz[0] <= izi) { pz[0] = izi; - pdest[0] = pparticle->color; + pdest[0] = pparticle->icolor; } } break; @@ -94,12 +94,12 @@ D_DrawParticle (particle_t *pparticle) for (; count; count--, pz += d_zwidth, pdest += screenwidth) { if (pz[0] <= izi) { pz[0] = izi; - pdest[0] = pparticle->color; + pdest[0] = pparticle->icolor; } if (pz[1] <= izi) { pz[1] = izi; - pdest[1] = pparticle->color; + pdest[1] = pparticle->icolor; } } break; @@ -109,17 +109,17 @@ D_DrawParticle (particle_t *pparticle) for (; count; count--, pz += d_zwidth, pdest += screenwidth) { if (pz[0] <= izi) { pz[0] = izi; - pdest[0] = pparticle->color; + pdest[0] = pparticle->icolor; } if (pz[1] <= izi) { pz[1] = izi; - pdest[1] = pparticle->color; + pdest[1] = pparticle->icolor; } if (pz[2] <= izi) { pz[2] = izi; - pdest[2] = pparticle->color; + pdest[2] = pparticle->icolor; } } break; @@ -129,22 +129,22 @@ D_DrawParticle (particle_t *pparticle) for (; count; count--, pz += d_zwidth, pdest += screenwidth) { if (pz[0] <= izi) { pz[0] = izi; - pdest[0] = pparticle->color; + pdest[0] = pparticle->icolor; } if (pz[1] <= izi) { pz[1] = izi; - pdest[1] = pparticle->color; + pdest[1] = pparticle->icolor; } if (pz[2] <= izi) { pz[2] = izi; - pdest[2] = pparticle->color; + pdest[2] = pparticle->icolor; } if (pz[3] <= izi) { pz[3] = izi; - pdest[3] = pparticle->color; + pdest[3] = pparticle->icolor; } } break; @@ -155,7 +155,7 @@ D_DrawParticle (particle_t *pparticle) for (i = 0; i < pix; i++) { if (pz[i] <= izi) { pz[i] = izi; - pdest[i] = pparticle->color; + pdest[i] = pparticle->icolor; } } } diff --git a/libs/video/renderer/sw/sw_rpart.c b/libs/video/renderer/sw/sw_rpart.c index 8dc268955..ede081f77 100644 --- a/libs/video/renderer/sw/sw_rpart.c +++ b/libs/video/renderer/sw/sw_rpart.c @@ -49,12 +49,57 @@ #include "compat.h" #include "r_internal.h" -static int ramp1[8] = { 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61 }; -//static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 }; -static int ramp3[8] = { 0x6d, 0x6b, 6, 5, 4, 3 }; - static mtstate_t mt; // private PRNG state +static vec4f_t +roffs (int mod) +{ + vec4f_t offs = { + (mtwist_rand (&mt) % mod) - 0.5 * (mod - 1), + (mtwist_rand (&mt) % mod) - 0.5 * (mod - 1), + (mtwist_rand (&mt) % mod) - 0.5 * (mod - 1), + 0 + }; + return offs; +} + +static vec4f_t +tracer_vel (int tracercount, vec4f_t vec) +{ + if (tracercount & 1) { + return (vec4f_t) { vec[1], -vec[0], 0, 0 }; + } else { + return (vec4f_t) { -vec[1], vec[0], 0, 0 }; + } +} + +static void +add_particle (ptype_t type, vec4f_t pos, vec4f_t vel, float live, int color, + float ramp) +{ + if (numparticles >= r_maxparticles) + return; + particle_t *p = &particles[numparticles]; + partparm_t *parm = &partparams[numparticles]; + const int **rampptr = &partramps[numparticles]; + numparticles += 1; + + p->pos = pos; + p->vel = vel; + p->icolor = color; + p->alpha = 1; + p->tex = 0; + p->ramp = ramp; + p->scale = 1; + p->live = live; + + *parm = R_ParticlePhysics (type); + *rampptr = R_ParticleRamp (type); + if (*rampptr) { + p->icolor = (*rampptr) [(int) p->ramp]; + } +} + void R_InitParticles (void) { @@ -64,26 +109,19 @@ R_InitParticles (void) void R_ClearParticles (void) { - unsigned int i; - - free_particles = &particles[0]; - active_particles = NULL; - - for (i = 0; i < r_maxparticles; i++) - particles[i].next = &particles[i + 1]; - if (r_maxparticles) - particles[r_maxparticles - 1].next = NULL; + if (r_maxparticles) { + memset (particles, 0, r_maxparticles * sizeof (*particles)); + } } void R_ReadPointFile_f (void) { QFile *f; - vec3_t org; int c, r; - particle_t *p; const char *name; char *mapname; + vec4f_t zero = {}; mapname = strdup (r_worldentity.renderer.model->path); if (!mapname) @@ -103,6 +141,7 @@ R_ReadPointFile_f (void) c = 0; for (;;) { char buf[64]; + vec4f_t org = { 0, 0, 0, 1 }; Qgets (f, buf, sizeof (buf)); r = sscanf (buf, "%f %f %f\n", &org[0], &org[1], &org[2]); @@ -110,21 +149,11 @@ R_ReadPointFile_f (void) break; c++; - if (!free_particles) { - Sys_Printf ("Not enough free particles\n"); - break; - } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = 99999; - p->color = (-c) & 15; - p->type = pt_static; - p->phys = R_ParticlePhysics (p->type); - VectorZero (p->vel); - VectorCopy (org, p->org); + //if (!free_particles) { + // Sys_Printf ("Not enough free particles\n"); + // break; + //} + add_particle (pt_static, org, zero, INFINITY, (-c) & 15, 0); } Qclose (f); @@ -132,324 +161,218 @@ R_ReadPointFile_f (void) } static void -R_ParticleExplosion_QF (const vec3_t org) +R_ParticleExplosion_QF (vec4f_t org) { - int i, j; - particle_t *p; - if (!r_particles->int_val) return; - for (i = 0; i < 1024; i++) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 5; - p->color = ramp1[0]; - p->ramp = mtwist_rand (&mt) & 3; - if (i & 1) - p->type = pt_explode; - else - p->type = pt_explode2; - p->phys = R_ParticlePhysics (p->type); - for (j = 0; j < 3; j++) { - p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16); - p->vel[j] = (mtwist_rand (&mt) % 512) - 256; - } + for (int i = 0; i < 1024; i++) { + ptype_t type = i & 1 ? pt_explode2 : pt_explode; + add_particle (type, org + roffs (32), roffs (512), 5, + 0, mtwist_rand (&mt) & 3); } } static void -R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength) +R_ParticleExplosion2_QF (vec4f_t org, int colorStart, int colorLength) { - int i, j; int colorMod = 0; - particle_t *p; - for (i=0; i<512; i++) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.3; - p->color = colorStart + (colorMod % colorLength); - colorMod++; - - p->type = pt_blob; - p->phys = R_ParticlePhysics (p->type); - for (j=0 ; j<3 ; j++) { - p->org[j] = org[j] + ((mtwist_rand (&mt)%32)-16); - p->vel[j] = (mtwist_rand (&mt)%512)-256; - } + for (int i=0; i<512; i++) { + add_particle (pt_blob, org + roffs (32), roffs (512), 0.3, + colorStart + (colorMod % colorLength), 0); } } static void -R_BlobExplosion_QF (const vec3_t org) +R_BlobExplosion_QF (vec4f_t org) { - int i, j; - particle_t *p; - if (!r_particles->int_val) return; - for (i = 0; i < 1024; i++) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 1 + (mtwist_rand (&mt) & 8) * 0.05; - - if (i & 1) { - p->type = pt_blob; - p->color = 66 + mtwist_rand (&mt) % 6; - } else { - p->type = pt_blob2; - p->color = 150 + mtwist_rand (&mt) % 6; - } - p->phys = R_ParticlePhysics (p->type); - for (j = 0; j < 3; j++) { - p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16); - p->vel[j] = (mtwist_rand (&mt) % 512) - 256; - } + for (int i = 0; i < 1024; i++) { + ptype_t type = i & 1 ? pt_blob : pt_blob2; + int color = i & 1 ? 66 : 150; + add_particle (type, org + roffs (32), roffs (512), + color + mtwist_rand (&mt) % 6, + (color & ~7) + (mtwist_rand (&mt) & 7), 0); } } static void -R_RunParticleEffect_QF (const vec3_t org, const vec3_t dir, int color, - int count) +R_RunParticleEffect_QF (vec4f_t org, vec4f_t dir, int color, int count) { - int i, j; - particle_t *p; - if (!r_particles->int_val) return; - for (i = 0; i < count; i++) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.1 * (mtwist_rand (&mt) % 5); - p->color = (color & ~7) + (mtwist_rand (&mt) & 7); - p->type = pt_grav; - p->phys = R_ParticlePhysics (p->type); - for (j = 0; j < 3; j++) { - p->org[j] = org[j] + ((mtwist_rand (&mt) & 15) - 8); - p->vel[j] = dir[j]; // + (mtwist_rand (&mt)%300)-150; - } + for (int i = 0; i < count; i++) { + add_particle (pt_slowgrav, org + roffs (16), + dir/* + roffs (300)*/, + 0.1 * (mtwist_rand (&mt) % 5), + (color & ~7) + (mtwist_rand (&mt) & 7), 0); } } static void -R_SpikeEffect_QF (const vec3_t org) +R_SpikeEffect_QF (vec4f_t org) { - R_RunParticleEffect_QF (org, vec3_origin, 0, 10); + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 0, 10); } static void -R_SuperSpikeEffect_QF (const vec3_t org) +R_SuperSpikeEffect_QF (vec4f_t org) { - R_RunParticleEffect_QF (org, vec3_origin, 0, 20); + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 0, 20); } static void -R_KnightSpikeEffect_QF (const vec3_t org) +R_KnightSpikeEffect_QF (vec4f_t org) { - R_RunParticleEffect_QF (org, vec3_origin, 226, 20); + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 226, 20); } static void -R_WizSpikeEffect_QF (const vec3_t org) +R_WizSpikeEffect_QF (vec4f_t org) { - R_RunParticleEffect_QF (org, vec3_origin, 20, 30); + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 20, 30); } static void -R_BloodPuffEffect_QF (const vec3_t org, int count) +R_BloodPuffEffect_QF (vec4f_t org, int count) { - R_RunParticleEffect_QF (org, vec3_origin, 73, count); + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 73, count); } static void -R_GunshotEffect_QF (const vec3_t org, int count) +R_GunshotEffect_QF (vec4f_t org, int count) { - R_RunParticleEffect_QF (org, vec3_origin, 0, count); + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 0, count); } static void -R_LightningBloodEffect_QF (const vec3_t org) +R_LightningBloodEffect_QF (vec4f_t org) { - R_RunParticleEffect_QF (org, vec3_origin, 225, 50); + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 225, 50); } static void -R_LavaSplash_QF (const vec3_t org) +R_LavaSplash_QF (vec4f_t org) { - int i, j, k; - particle_t *p; - float vel; - vec3_t dir; - if (!r_particles->int_val) return; - for (i = -16; i < 16; i++) - for (j = -16; j < 16; j++) - for (k = 0; k < 1; k++) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 2 + (mtwist_rand (&mt) & 31) * 0.02; - p->color = 224 + (mtwist_rand (&mt) & 7); - p->type = pt_grav; - p->phys = R_ParticlePhysics (p->type); - - dir[0] = j * 8 + (mtwist_rand (&mt) & 7); - dir[1] = i * 8 + (mtwist_rand (&mt) & 7); - dir[2] = 256; - - p->org[0] = org[0] + dir[0]; - p->org[1] = org[1] + dir[1]; - p->org[2] = org[2] + (mtwist_rand (&mt) & 63); - - VectorNormalize (dir); - vel = 50 + (mtwist_rand (&mt) & 63); - VectorScale (dir, vel, p->vel); - } -} - -static void -R_TeleportSplash_QF (const vec3_t org) -{ - int i, j, k; - particle_t *p; - float vel; - vec3_t dir; - - if (!r_particles->int_val) - return; - - for (i = -16; i < 16; i += 4) - for (j = -16; j < 16; j += 4) - for (k = -24; k < 32; k += 4) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 7) * 0.02; - p->color = 7 + (mtwist_rand (&mt) & 7); - p->type = pt_grav; - p->phys = R_ParticlePhysics (p->type); - - dir[0] = j * 8; - dir[1] = i * 8; - dir[2] = k * 8; - - p->org[0] = org[0] + i + (mtwist_rand (&mt) & 3); - p->org[1] = org[1] + j + (mtwist_rand (&mt) & 3); - p->org[2] = org[2] + k + (mtwist_rand (&mt) & 3); - - VectorNormalize (dir); - vel = 50 + (mtwist_rand (&mt) & 63); - VectorScale (dir, vel, p->vel); - } -} - -static void -R_DarkFieldParticles_ID (const entity_t *ent) -{ - int i, j, k; - unsigned int rnd; - float vel; - particle_t *p; - vec3_t dir, org; - - if (!r_particles->int_val) - return; - - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - for (i = -16; i < 16; i += 8) { - for (j = -16; j < 16; j += 8) { - for (k = 0; k < 32; k += 8) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - rnd = mtwist_rand (&mt); - - p->die = vr_data.realtime + 0.2 + (rnd & 7) * 0.02; - p->color = 150 + mtwist_rand (&mt) % 6; - p->type = pt_slowgrav; - p->phys = R_ParticlePhysics (p->type); - dir[0] = j * 8; - dir[1] = i * 8; - dir[2] = k * 8; - - p->org[0] = org[0] + i + ((rnd >> 3) & 3); - p->org[1] = org[1] + j + ((rnd >> 5) & 3); - p->org[2] = org[2] + k + ((rnd >> 7) & 3); - - VectorNormalize (dir); - vel = 50 + ((rnd >> 9) & 63); - VectorScale (dir, vel, p->vel); + for (int i = -16; i < 16; i++) { + for (int j = -16; j < 16; j++) { + for (int k = 0; k < 1; k++) { + float vel = 50 + (mtwist_rand (&mt) & 63); + vec4f_t dir = { + j * 8 + (mtwist_rand (&mt) & 7), + i * 8 + (mtwist_rand (&mt) & 7), + 256, + 0 + }; + vec4f_t offs = { + dir[0], + dir[1], + (mtwist_rand (&mt) & 63), + 0 + }; + dir = normalf (dir); + add_particle (pt_grav, org + offs, vel * dir, + 2 + (mtwist_rand (&mt) & 31) * 0.02, + 224 + (mtwist_rand (&mt) & 7), 0); } } } } -static vec3_t avelocities[NUMVERTEXNORMALS]; +static void +R_TeleportSplash_QF (vec4f_t org) +{ + if (!r_particles->int_val) + return; + + for (int i = -16; i < 16; i += 4) { + for (int j = -16; j < 16; j += 4) { + for (int k = -24; k < 32; k += 4) { + float vel = 50 + (mtwist_rand (&mt) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + (mtwist_rand (&mt) & 3), + j + (mtwist_rand (&mt) & 3), + k + (mtwist_rand (&mt) & 3), + 0 + }; + add_particle (pt_grav, org + offs, vel * dir, + 0.2 + (mtwist_rand (&mt) & 7) * 0.02, + 7 + (mtwist_rand (&mt) & 7), 0); + } + } + } +} static void -R_EntityParticles_ID (const entity_t *ent) +R_DarkFieldParticles_ID (vec4f_t org) +{ + if (!r_particles->int_val) + return; + + for (int i = -16; i < 16; i += 8) { + for (int j = -16; j < 16; j += 8) { + for (int k = 0; k < 32; k += 8) { + uint32_t rnd = mtwist_rand (&mt); + float vel = 50 + ((rnd >> 9) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + ((rnd >> 3) & 3), + j + ((rnd >> 5) & 3), + k + ((rnd >> 7) & 3), + 0 + }; + + add_particle (pt_slowgrav, org + offs, vel * dir, + 0.2 + (rnd & 7) * 0.02, + 150 + mtwist_rand (&mt) % 6, 0); + } + } + } +} + +static vec4f_t velocities[NUMVERTEXNORMALS]; +static vec4f_t normals[NUMVERTEXNORMALS] = { +#include "anorms.h" +}; + +static void +R_EntityParticles_ID (vec4f_t org) { int i; float angle, sp, sy, cp, cy; // cr, sr float beamlength = 16.0, dist = 64.0; - particle_t *p; - vec3_t forward; - vec3_t org; if (!r_particles->int_val) return; - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - for (i = 0; i < NUMVERTEXNORMALS; i++) { int k; for (k = 0; k < 3; k++) { - avelocities[i][k] = (mtwist_rand (&mt) & 255) * 0.01; + velocities[i][k] = (mtwist_rand (&mt) & 255) * 0.01; } } + vec4f_t zero = {}; for (i = 0; i < NUMVERTEXNORMALS; i++) { - angle = vr_data.realtime * avelocities[i][0]; + angle = vr_data.realtime * velocities[i][0]; cy = cos (angle); sy = sin (angle); - angle = vr_data.realtime * avelocities[i][1]; + angle = vr_data.realtime * velocities[i][1]; cp = cos (angle); sp = sin (angle); // Next 3 lines results aren't currently used, may be in future. --Despair @@ -457,355 +380,194 @@ R_EntityParticles_ID (const entity_t *ent) // sr = sin (angle); // cr = cos (angle); - forward[0] = cp * cy; - forward[1] = cp * sy; - forward[2] = -sp; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.01; - p->color = 0x6f; - p->type = pt_explode; - p->phys = R_ParticlePhysics (p->type); - - p->org[0] = org[0] + r_avertexnormals[i][0] * dist + - forward[0] * beamlength; - p->org[1] = org[1] + r_avertexnormals[i][1] * dist + - forward[1] * beamlength; - p->org[2] = org[2] + r_avertexnormals[i][2] * dist + - forward[2] * beamlength; + vec4f_t forward = { cp * cy, cp * sy, -sp, 0 }; + vec4f_t pos = org + normals[i] * dist + forward * beamlength; + //FIXME 0 velocity? + add_particle (pt_explode, pos, zero, 0.01, 0x6f, 0); } } static void -R_RocketTrail_QF (const entity_t *ent) +R_RocketTrail_QF (vec4f_t start, vec4f_t end) { - float len; - int j; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorCopy (ent->old_origin, old_origin); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t zero = {}; + vec4f_t pos = start; while (len > 0) { len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorZero (p->vel); - - p->die = vr_data.realtime + 2; - p->ramp = (mtwist_rand (&mt) & 3); - p->color = ramp3[(int) p->ramp]; - p->type = pt_fire; - p->phys = R_ParticlePhysics (p->type); - for (j = 0; j < 3; j++) - p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3); - - VectorAdd (old_origin, vec, old_origin); + add_particle (pt_fire, pos + roffs (6), zero, 2, + 0, (mtwist_rand (&mt) & 3)); + pos += vec; } } static void -R_GrenadeTrail_QF (const entity_t *ent) +R_GrenadeTrail_QF (vec4f_t start, vec4f_t end) { - float len; - int j; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t zero = {}; + vec4f_t pos = start; while (len > 0) { len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorZero (p->vel); - - p->die = vr_data.realtime + 2; - p->ramp = (mtwist_rand (&mt) & 3) + 2; - p->color = ramp3[(int) p->ramp]; - p->type = pt_fire; - p->phys = R_ParticlePhysics (p->type); - for (j = 0; j < 3; j++) - p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3); - - VectorAdd (old_origin, vec, old_origin); + add_particle (pt_fire, pos + roffs (6), zero, 2, + 0, (mtwist_rand (&mt) & 3) + 2); + pos += vec; } } static void -R_BloodTrail_QF (const entity_t *ent) +R_BloodTrail_QF (vec4f_t start, vec4f_t end) { - float len; - int j; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t zero = {}; + vec4f_t pos = start; while (len > 0) { len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorZero (p->vel); - - p->die = vr_data.realtime + 2; - p->type = pt_slowgrav; - p->phys = R_ParticlePhysics (p->type); - p->color = 67 + (mtwist_rand (&mt) & 3); - for (j = 0; j < 3; j++) - p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3); - - VectorAdd (old_origin, vec, old_origin); + add_particle (pt_slowgrav, pos + roffs (6), zero, 2, + 67 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } static void -R_SlightBloodTrail_QF (const entity_t *ent) +R_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) { - float len; - int j; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t zero = {}; + vec4f_t pos = start; while (len > 0) { len -= 6; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorZero (p->vel); - - p->die = vr_data.realtime + 2; - p->type = pt_slowgrav; - p->phys = R_ParticlePhysics (p->type); - p->color = 67 + (mtwist_rand (&mt) & 3); - for (j = 0; j < 3; j++) - p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3); - - VectorAdd (old_origin, vec, old_origin); + add_particle (pt_slowgrav, pos + roffs (6), zero, 2, + 67 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } static void -R_WizTrail_QF (const entity_t *ent) +R_WizTrail_QF (vec4f_t start, vec4f_t end) { - float len; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t pos = start; while (len > 0) { static int tracercount; - len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.5; - p->type = pt_static; - p->phys = R_ParticlePhysics (p->type); - p->color = 52 + ((tracercount & 4) << 1); - + add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, + 52 + ((tracercount & 4) << 1), 0); tracercount++; - - VectorCopy (old_origin, p->org); - if (tracercount & 1) { - p->vel[0] = 30.0 * vec[1]; - p->vel[1] = 30.0 * -vec[0]; - } else { - p->vel[0] = 30.0 * -vec[1]; - p->vel[1] = 30.0 * vec[0]; - } - p->vel[2] = 0.0; - - VectorAdd (old_origin, vec, old_origin); + pos += vec; } } static void -R_FlameTrail_QF (const entity_t *ent) +R_FlameTrail_QF (vec4f_t start, vec4f_t end) { - float len; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t pos = start; while (len > 0) { static int tracercount; - len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.5; - p->type = pt_static; - p->phys = R_ParticlePhysics (p->type); - p->color = 230 + ((tracercount & 4) << 1); - + add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, + 230 + ((tracercount & 4) << 1), 0); tracercount++; - - VectorCopy (old_origin, p->org); - if (tracercount & 1) { - p->vel[0] = 30 * vec[1]; - p->vel[1] = 30 * -vec[0]; - } else { - p->vel[0] = 30 * -vec[1]; - p->vel[1] = 30 * vec[0]; - } - p->vel[2] = 0.0; - - VectorAdd (old_origin, vec, old_origin); + pos += vec; } } static void -R_VoorTrail_QF (const entity_t *ent) +R_VoorTrail_QF (vec4f_t start, vec4f_t end) { - float len; - int j; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t zero = {}; + vec4f_t pos = start; while (len > 0) { len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorZero (p->vel); - - p->die = vr_data.realtime + 0.3; - p->type = pt_static; - p->phys = R_ParticlePhysics (p->type); - p->color = 9 * 16 + 8 + (mtwist_rand (&mt) & 3); - for (j = 0; j < 3; j++) - p->org[j] = old_origin[j] + ((mtwist_rand (&mt) & 15) - 8); - - VectorAdd (old_origin, vec, old_origin); + add_particle (pt_static, pos + roffs (16), zero, 0.3, + 9 * 16 + 8 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } void R_DrawParticles (void) { - particle_t *p, **particle; - VectorScale (vright, xscaleshrink, r_pright); VectorScale (vup, yscaleshrink, r_pup); VectorCopy (vpn, r_ppn); - for (particle = &active_particles; *particle;) { - if ((*particle)->die < vr_data.realtime) { - p = (*particle)->next; - (*particle)->next = free_particles; - free_particles = (*particle); - (*particle) = p; - } else { - p = *particle; - particle = &(*particle)->next; + vec4f_t gravity = {0, 0, -vr_data.gravity, 0}; - D_DrawParticle (p); + unsigned j = 0; + for (unsigned i = 0; i < numparticles; i++) { + particle_t *p = &particles[i]; + partparm_t *parm = &partparams[i]; - p->phys (p); + if (p->live <= 0 || p->ramp >= parm->ramp_max) { + continue; + } + const int *ramp = partramps[j]; + if (i > j) { + particles[j] = *p; + partparams[j] = *parm; + partramps[j] = ramp; + } + p = &particles[j]; + parm = &partparams[j]; + j += 1; + + D_DrawParticle (p); + + float dT = vr_data.frametime; + p->pos += dT * p->vel; + p->vel += dT * (p->vel * parm->drag + gravity * parm->drag[3]); + p->ramp += dT * parm->ramp; + p->live -= dT; + if (ramp) { + p->icolor = ramp[(int)p->ramp]; } } + numparticles = j; } void @@ -819,49 +581,33 @@ r_particles_style_f (cvar_t *var) } static void -R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale, - const vec3_t vel, float die, int color, float alpha, float ramp) +R_Particle_New (ptype_t type, int texnum, vec4f_t pos, float scale, + vec4f_t vel, float live, int color, float alpha, float ramp) { - particle_t *p; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorCopy (org, p->org); - p->color = color; - p->tex = texnum; - p->scale = scale; - p->alpha = alpha; - VectorCopy (vel, p->vel); - p->type = type; - p->phys = R_ParticlePhysics (p->type); - p->die = die; - p->ramp = ramp; + add_particle (type, pos, vel, live, color, ramp); } static void -R_Particle_NewRandom (ptype_t type, int texnum, const vec3_t org, int org_fuzz, - float scale, int vel_fuzz, float die, int color, +R_Particle_NewRandom (ptype_t type, int texnum, vec4f_t org, int org_fuzz, + float scale, int vel_fuzz, float live, int color, float alpha, float ramp) { float o_fuzz = org_fuzz, v_fuzz = vel_fuzz; int rnd; - vec3_t porg, pvel; + vec4f_t pos, vel; rnd = mtwist_rand (&mt); - porg[0] = o_fuzz * ((rnd & 63) - 31.5) / 63.0 + org[0]; - porg[1] = o_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0 + org[1]; - porg[2] = o_fuzz * (((rnd >> 10) & 63) - 31.5) / 63.0 + org[2]; + pos[0] = o_fuzz * ((rnd & 63) - 31.5) / 63.0 + org[0]; + pos[1] = o_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0 + org[1]; + pos[2] = o_fuzz * (((rnd >> 10) & 63) - 31.5) / 63.0 + org[2]; + pos[3] = 1; rnd = mtwist_rand (&mt); - pvel[0] = v_fuzz * ((rnd & 63) - 31.5) / 63.0; - pvel[1] = v_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0; - pvel[2] = v_fuzz * (((rnd >> 10) & 63) - 31.5) / 63.0; + vel[0] = v_fuzz * ((rnd & 63) - 31.5) / 63.0; + vel[1] = v_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0; + vel[2] = v_fuzz * (((rnd >> 10) & 63) - 31.5) / 63.0; + vel[3] = 0; - R_Particle_New (type, texnum, porg, scale, pvel, die, color, alpha, ramp); + add_particle (type, pos, vel, live, color, ramp); } static vid_particle_funcs_t particles_QF = { diff --git a/libs/video/renderer/sw32/d_part.c b/libs/video/renderer/sw32/d_part.c index 4b30fc398..8ac57af54 100644 --- a/libs/video/renderer/sw32/d_part.c +++ b/libs/video/renderer/sw32/d_part.c @@ -48,7 +48,7 @@ sw32_D_DrawParticle (particle_t *pparticle) int i, izi, pix, count, u, v; // transform point - VectorSubtract (pparticle->org, r_origin, local); + VectorSubtract (pparticle->pos, r_origin, local); transformed[0] = DotProduct (local, r_pright); transformed[1] = DotProduct (local, r_pup); @@ -84,7 +84,7 @@ sw32_D_DrawParticle (particle_t *pparticle) case 1: { byte *pdest = (byte *) sw32_d_viewbuffer + sw32_d_scantable[v] + u, - pixcolor = pparticle->color; + pixcolor = pparticle->icolor; switch (pix) { case 1: count = 1 << sw32_d_y_aspect_shift; @@ -180,7 +180,7 @@ sw32_D_DrawParticle (particle_t *pparticle) { unsigned short *pdest = (unsigned short *) sw32_d_viewbuffer + sw32_d_scantable[v] + u, - pixcolor = sw32_8to16table[(int) pparticle->color]; + pixcolor = sw32_8to16table[(int) pparticle->icolor]; switch (pix) { case 1: count = 1 << sw32_d_y_aspect_shift; @@ -275,7 +275,7 @@ sw32_D_DrawParticle (particle_t *pparticle) case 4: { int *pdest = (int *) sw32_d_viewbuffer + sw32_d_scantable[v] + u, - pixcolor = d_8to24table[(int) pparticle->color]; + pixcolor = d_8to24table[(int) pparticle->icolor]; switch (pix) { case 1: count = 1 << sw32_d_y_aspect_shift; diff --git a/libs/video/renderer/sw32/sw32_rpart.c b/libs/video/renderer/sw32/sw32_rpart.c index 45e48a9ed..26a9255ed 100644 --- a/libs/video/renderer/sw32/sw32_rpart.c +++ b/libs/video/renderer/sw32/sw32_rpart.c @@ -52,12 +52,56 @@ #include "compat.h" #include "r_internal.h" -static int ramp1[8] = { 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61 }; -//static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 }; -static int ramp3[8] = { 0x6d, 0x6b, 6, 5, 4, 3 }; - static mtstate_t mt; // private PRNG state +static vec4f_t +roffs (int mod) +{ + vec4f_t offs = { + (mtwist_rand (&mt) & mod) - 0.5 * (mod - 1), + (mtwist_rand (&mt) & mod) - 0.5 * (mod - 1), + (mtwist_rand (&mt) & mod) - 0.5 * (mod - 1), + 0 + }; + return offs; +} + +static vec4f_t +tracer_vel (int tracercount, vec4f_t vec) +{ + if (tracercount & 1) { + return (vec4f_t) { vec[1], -vec[0], 0, 0 }; + } else { + return (vec4f_t) { -vec[1], vec[0], 0, 0 }; + } +} + +static void +add_particle (ptype_t type, vec4f_t pos, vec4f_t vel, float live, int color, + float ramp) +{ + if (numparticles >= r_maxparticles) + return; + particle_t *p = &particles[numparticles]; + partparm_t *parm = &partparams[numparticles]; + const int **rampptr = &partramps[numparticles]; + numparticles += 1; + + p->pos = pos; + p->vel = vel; + p->icolor = color; + p->alpha = 1; + p->tex = 0; + p->ramp = ramp; + p->scale = 1; + p->live = live; + + *parm = R_ParticlePhysics (type); + *rampptr = R_ParticleRamp (type); + if (*rampptr) { + p->icolor = (*rampptr) [(int) p->ramp]; + } +} void sw32_R_InitParticles (void) @@ -68,27 +112,19 @@ sw32_R_InitParticles (void) void sw32_R_ClearParticles (void) { - unsigned int i; - - free_particles = &particles[0]; - active_particles = NULL; - - for (i = 0; i < r_maxparticles; i++) - particles[i].next = &particles[i + 1]; - if (r_maxparticles) - particles[r_maxparticles - 1].next = NULL; + if (r_maxparticles) { + memset (particles, 0, r_maxparticles * sizeof (*particles)); + } } void sw32_R_ReadPointFile_f (void) { QFile *f; - vec3_t org; - int r; - int c; - particle_t *p; + int c, r; const char *name; char *mapname; + vec4f_t zero = {}; mapname = strdup (r_worldentity.renderer.model->path); if (!mapname) @@ -108,6 +144,7 @@ sw32_R_ReadPointFile_f (void) c = 0; for (;;) { char buf[64]; + vec4f_t org = { 0, 0, 0, 1 }; Qgets (f, buf, sizeof (buf)); r = sscanf (buf, "%f %f %f\n", &org[0], &org[1], &org[2]); @@ -115,21 +152,11 @@ sw32_R_ReadPointFile_f (void) break; c++; - if (!free_particles) { - Sys_Printf ("Not enough free particles\n"); - break; - } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = 99999; - p->color = (-c) & 15; - p->type = pt_static; - p->phys = R_ParticlePhysics (p->type); - VectorZero (p->vel); - VectorCopy (org, p->org); + //if (!free_particles) { + // Sys_Printf ("Not enough free particles\n"); + // break; + //} + add_particle (pt_static, org, zero, INFINITY, (-c) & 15, 0); } Qclose (f); @@ -137,261 +164,218 @@ sw32_R_ReadPointFile_f (void) } static void -R_ParticleExplosion_QF (const vec3_t org) +R_ParticleExplosion_QF (vec4f_t org) { - int i, j; - particle_t *p; - if (!r_particles->int_val) return; - for (i = 0; i < 1024; i++) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 5; - p->color = ramp1[0]; - p->ramp = mtwist_rand (&mt) & 3; - if (i & 1) { - p->type = pt_explode; - for (j = 0; j < 3; j++) { - p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16); - p->vel[j] = (mtwist_rand (&mt) % 512) - 256; - } - } else { - p->type = pt_explode2; - for (j = 0; j < 3; j++) { - p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16); - p->vel[j] = (mtwist_rand (&mt) % 512) - 256; - } - } - p->phys = R_ParticlePhysics (p->type); + for (int i = 0; i < 1024; i++) { + ptype_t type = i & 1 ? pt_explode2 : pt_explode; + add_particle (type, org + roffs (32), roffs (512), 5, + 0, mtwist_rand (&mt) & 3); } } static void -R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength) +R_ParticleExplosion2_QF (vec4f_t org, int colorStart, int colorLength) { - int i, j; - particle_t *p; int colorMod = 0; - for (i=0; i<512; i++) - { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.3; - p->color = colorStart + (colorMod % colorLength); - colorMod++; - - p->type = pt_blob; - p->phys = R_ParticlePhysics (p->type); - for (j=0 ; j<3 ; j++) - { - p->org[j] = org[j] + ((mtwist_rand (&mt)%32)-16); - p->vel[j] = (mtwist_rand (&mt)%512)-256; - } + for (int i=0; i<512; i++) { + add_particle (pt_blob, org + roffs (32), roffs (512), 0.3, + colorStart + (colorMod % colorLength), 0); } } static void -R_BlobExplosion_QF (const vec3_t org) +R_BlobExplosion_QF (vec4f_t org) { - int i, j; - particle_t *p; - if (!r_particles->int_val) return; - for (i = 0; i < 1024; i++) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 1 + (mtwist_rand (&mt) & 8) * 0.05; - - if (i & 1) { - p->type = pt_blob; - p->color = 66 + mtwist_rand (&mt) % 6; - for (j = 0; j < 3; j++) { - p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16); - p->vel[j] = (mtwist_rand (&mt) % 512) - 256; - } - } else { - p->type = pt_blob2; - p->color = 150 + mtwist_rand (&mt) % 6; - for (j = 0; j < 3; j++) { - p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16); - p->vel[j] = (mtwist_rand (&mt) % 512) - 256; - } - } - p->phys = R_ParticlePhysics (p->type); + for (int i = 0; i < 1024; i++) { + ptype_t type = i & 1 ? pt_blob : pt_blob2; + int color = i & 1 ? 66 : 150; + add_particle (type, org + roffs (32), roffs (512), + color + mtwist_rand (&mt) % 6, + (color & ~7) + (mtwist_rand (&mt) & 7), 0); } } static void -R_LavaSplash_QF (const vec3_t org) +R_RunParticleEffect_QF (vec4f_t org, vec4f_t dir, int color, int count) { - int i, j, k; - particle_t *p; - float vel; - vec3_t dir; - if (!r_particles->int_val) return; - for (i = -16; i < 16; i++) - for (j = -16; j < 16; j++) - for (k = 0; k < 1; k++) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 2 + (mtwist_rand (&mt) & 31) * 0.02; - p->color = 224 + (mtwist_rand (&mt) & 7); - p->type = pt_grav; - p->phys = R_ParticlePhysics (p->type); - - dir[0] = j * 8 + (mtwist_rand (&mt) & 7); - dir[1] = i * 8 + (mtwist_rand (&mt) & 7); - dir[2] = 256; - - p->org[0] = org[0] + dir[0]; - p->org[1] = org[1] + dir[1]; - p->org[2] = org[2] + (mtwist_rand (&mt) & 63); - - VectorNormalize (dir); - vel = 50 + (mtwist_rand (&mt) & 63); - VectorScale (dir, vel, p->vel); - } + for (int i = 0; i < count; i++) { + add_particle (pt_slowgrav, org + roffs (16), + dir/* + roffs (300)*/, + 0.1 * (mtwist_rand (&mt) % 5), + (color & ~7) + (mtwist_rand (&mt) & 7), 0); + } } static void -R_TeleportSplash_QF (const vec3_t org) +R_SpikeEffect_QF (vec4f_t org) { - float vel; - int i, j, k; - particle_t *p; - vec3_t dir; + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 0, 10); +} +static void +R_SuperSpikeEffect_QF (vec4f_t org) +{ + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 0, 20); +} + +static void +R_KnightSpikeEffect_QF (vec4f_t org) +{ + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 226, 20); +} + +static void +R_WizSpikeEffect_QF (vec4f_t org) +{ + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 20, 30); +} + +static void +R_BloodPuffEffect_QF (vec4f_t org, int count) +{ + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 73, count); +} + +static void +R_GunshotEffect_QF (vec4f_t org, int count) +{ + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 0, count); +} + +static void +R_LightningBloodEffect_QF (vec4f_t org) +{ + vec4f_t zero = {}; + R_RunParticleEffect_QF (org, zero, 225, 50); +} + +static void +R_LavaSplash_QF (vec4f_t org) +{ if (!r_particles->int_val) return; - for (i = -16; i < 16; i += 4) { - for (j = -16; j < 16; j += 4) { - for (k = -24; k < 32; k += 4) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 7) * 0.02; - p->color = 7 + (mtwist_rand (&mt) & 7); - p->type = pt_grav; - p->phys = R_ParticlePhysics (p->type); - - dir[0] = j * 8; - dir[1] = i * 8; - dir[2] = k * 8; - - p->org[0] = org[0] + i + (mtwist_rand (&mt) & 3); - p->org[1] = org[1] + j + (mtwist_rand (&mt) & 3); - p->org[2] = org[2] + k + (mtwist_rand (&mt) & 3); - - VectorNormalize (dir); - vel = 50 + (mtwist_rand (&mt) & 63); - VectorScale (dir, vel, p->vel); + for (int i = -16; i < 16; i++) { + for (int j = -16; j < 16; j++) { + for (int k = 0; k < 1; k++) { + float vel = 50 + (mtwist_rand (&mt) & 63); + vec4f_t dir = { + j * 8 + (mtwist_rand (&mt) & 7), + i * 8 + (mtwist_rand (&mt) & 7), + 256, + 0 + }; + vec4f_t offs = { + dir[0], + dir[1], + (mtwist_rand (&mt) & 63), + 0 + }; + dir = normalf (dir); + add_particle (pt_grav, org + offs, vel * dir, + 2 + (mtwist_rand (&mt) & 31) * 0.02, + 224 + (mtwist_rand (&mt) & 7), 0); } } } } static void -R_DarkFieldParticles_ID (const entity_t *ent) +R_TeleportSplash_QF (vec4f_t org) { - int i, j, k; - unsigned int rnd; - float vel; - particle_t *p; - vec3_t dir, org; + if (!r_particles->int_val) + return; - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - for (i = -16; i < 16; i += 8) { - for (j = -16; j < 16; j += 8) { - for (k = 0; k < 32; k += 8) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - rnd = mtwist_rand (&mt); - - p->die = vr_data.realtime + 0.2 + (rnd & 7) * 0.02; - p->color = 150 + mtwist_rand (&mt) % 6; - p->type = pt_slowgrav; - p->phys = R_ParticlePhysics (p->type); - - dir[0] = j * 8; - dir[1] = i * 8; - dir[2] = k * 8; - - p->org[0] = org[0] + i + ((rnd >> 3) & 3); - p->org[1] = org[1] + j + ((rnd >> 5) & 3); - p->org[2] = org[2] + k + ((rnd >> 7) & 3); - - VectorNormalize (dir); - vel = 50 + ((rnd >> 9) & 63); - VectorScale (dir, vel, p->vel); + for (int i = -16; i < 16; i += 4) { + for (int j = -16; j < 16; j += 4) { + for (int k = -24; k < 32; k += 4) { + float vel = 50 + (mtwist_rand (&mt) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + (mtwist_rand (&mt) & 3), + j + (mtwist_rand (&mt) & 3), + k + (mtwist_rand (&mt) & 3), + 0 + }; + add_particle (pt_grav, org + offs, vel * dir, + 0.2 + (mtwist_rand (&mt) & 7) * 0.02, + 7 + (mtwist_rand (&mt) & 7), 0); } } } } -static vec3_t avelocities[NUMVERTEXNORMALS]; +static void +R_DarkFieldParticles_ID (vec4f_t org) +{ + if (!r_particles->int_val) + return; + + for (int i = -16; i < 16; i += 8) { + for (int j = -16; j < 16; j += 8) { + for (int k = 0; k < 32; k += 8) { + uint32_t rnd = mtwist_rand (&mt); + float vel = 50 + ((rnd >> 9) & 63); + vec4f_t dir = normalf ((vec4f_t) { j, i, k, 0 } * 8); + vec4f_t offs = { + i + ((rnd >> 3) & 3), + j + ((rnd >> 5) & 3), + k + ((rnd >> 7) & 3), + 0 + }; + + add_particle (pt_slowgrav, org + offs, vel * dir, + 0.2 + (rnd & 7) * 0.02, + 150 + mtwist_rand (&mt) % 6, 0); + } + } + } +} + +static vec4f_t velocities[NUMVERTEXNORMALS]; +static vec4f_t normals[NUMVERTEXNORMALS] = { +#include "anorms.h" +}; static void -R_EntityParticles_ID (const entity_t *ent) +R_EntityParticles_ID (vec4f_t org) { int i; float angle, sp, sy, cp, cy; // cr, sr float beamlength = 16.0, dist = 64.0; - particle_t *p; - vec3_t forward; - vec3_t org; - VectorCopy (Transform_GetWorldPosition (ent->transform), org); + if (!r_particles->int_val) + return; for (i = 0; i < NUMVERTEXNORMALS; i++) { int k; for (k = 0; k < 3; k++) { - avelocities[i][k] = (mtwist_rand (&mt) & 255) * 0.01; + velocities[i][k] = (mtwist_rand (&mt) & 255) * 0.01; } } + vec4f_t zero = {}; for (i = 0; i < NUMVERTEXNORMALS; i++) { - angle = vr_data.realtime * avelocities[i][0]; + angle = vr_data.realtime * velocities[i][0]; cy = cos (angle); sy = sin (angle); - angle = vr_data.realtime * avelocities[i][1]; + angle = vr_data.realtime * velocities[i][1]; cp = cos (angle); sp = sin (angle); // Next 3 lines results aren't currently used, may be in future. --Despair @@ -399,426 +383,194 @@ R_EntityParticles_ID (const entity_t *ent) // sr = sin (angle); // cr = cos (angle); - forward[0] = cp * cy; - forward[1] = cp * sy; - forward[2] = -sp; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.01; - p->color = 0x6f; - p->type = pt_explode; - p->phys = R_ParticlePhysics (p->type); - - p->org[0] = org[0] + r_avertexnormals[i][0] * dist + - forward[0] * beamlength; - p->org[1] = org[1] + r_avertexnormals[i][1] * dist + - forward[1] * beamlength; - p->org[2] = org[2] + r_avertexnormals[i][2] * dist + - forward[2] * beamlength; + vec4f_t forward = { cp * cy, cp * sy, -sp, 0 }; + vec4f_t pos = org + normals[i] * dist + forward * beamlength; + //FIXME 0 velocity? + add_particle (pt_explode, pos, zero, 0.01, 0x6f, 0); } } static void -R_RunParticleEffect_QF (const vec3_t org, const vec3_t dir, int color, - int count) +R_RocketTrail_QF (vec4f_t start, vec4f_t end) { - int i, j; - particle_t *p; - if (!r_particles->int_val) return; - for (i = 0; i < count; i++) { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.1 * (mtwist_rand (&mt) % 5); - p->color = (color & ~7) + (mtwist_rand (&mt) & 7); - p->type = pt_slowgrav; - p->phys = R_ParticlePhysics (p->type); - for (j = 0; j < 3; j++) { - p->org[j] = org[j] + ((mtwist_rand (&mt) & 15) - 8); - p->vel[j] = dir[j]; // + (mtwist_rand (&mt)%300)-150; - } - } -} - -static void -R_SpikeEffect_QF (const vec3_t org) -{ - R_RunParticleEffect_QF (org, vec3_origin, 0, 10); -} - -static void -R_SuperSpikeEffect_QF (const vec3_t org) -{ - R_RunParticleEffect_QF (org, vec3_origin, 0, 20); -} - -static void -R_KnightSpikeEffect_QF (const vec3_t org) -{ - R_RunParticleEffect_QF (org, vec3_origin, 226, 20); -} - -static void -R_WizSpikeEffect_QF (const vec3_t org) -{ - R_RunParticleEffect_QF (org, vec3_origin, 20, 30); -} - -static void -R_BloodPuffEffect_QF (const vec3_t org, int count) -{ - R_RunParticleEffect_QF (org, vec3_origin, 73, count); -} - -static void -R_GunshotEffect_QF (const vec3_t org, int count) -{ - R_RunParticleEffect_QF (org, vec3_origin, 0, count); -} - -static void -R_LightningBloodEffect_QF (const vec3_t org) -{ - R_RunParticleEffect_QF (org, vec3_origin, 225, 50); -} - -static void -R_RocketTrail_QF (const entity_t *ent) -{ - float len; - int j; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - - if (!r_particles->int_val) - return; - - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, ent->old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t zero = {}; + vec4f_t pos = start; while (len > 0) { len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorZero (p->vel); - - p->die = vr_data.realtime + 2; - p->ramp = (mtwist_rand (&mt) & 3); - p->color = ramp3[(int) p->ramp]; - p->type = pt_fire; - p->phys = R_ParticlePhysics (p->type); - for (j = 0; j < 3; j++) - p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3); - - VectorAdd (old_origin, vec, old_origin); + add_particle (pt_fire, pos + roffs (6), zero, 2, + 0, (mtwist_rand (&mt) & 3)); + pos += vec; } } static void -R_GrenadeTrail_QF (const entity_t *ent) +R_GrenadeTrail_QF (vec4f_t start, vec4f_t end) { - float len; - int j; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t zero = {}; + vec4f_t pos = start; while (len > 0) { len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorZero (p->vel); - - p->die = vr_data.realtime + 2; - p->ramp = (mtwist_rand (&mt) & 3) + 2; - p->color = ramp3[(int) p->ramp]; - p->type = pt_fire; - p->phys = R_ParticlePhysics (p->type); - for (j = 0; j < 3; j++) - p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3); - - VectorAdd (old_origin, vec, old_origin); + add_particle (pt_fire, pos + roffs (6), zero, 2, + 0, (mtwist_rand (&mt) & 3) + 2); + pos += vec; } } static void -R_BloodTrail_QF (const entity_t *ent) +R_BloodTrail_QF (vec4f_t start, vec4f_t end) { - float len; - int j; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t zero = {}; + vec4f_t pos = start; while (len > 0) { len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorZero (p->vel); - - p->die = vr_data.realtime + 2; - p->type = pt_slowgrav; - p->phys = R_ParticlePhysics (p->type); - p->color = 67 + (mtwist_rand (&mt) & 3); - for (j = 0; j < 3; j++) - p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3); - - VectorAdd (old_origin, vec, old_origin); + add_particle (pt_slowgrav, pos + roffs (6), zero, 2, + 67 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } static void -R_SlightBloodTrail_QF (const entity_t *ent) +R_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) { - float len; - int j; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t zero = {}; + vec4f_t pos = start; while (len > 0) { len -= 6; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorZero (p->vel); - - p->die = vr_data.realtime + 2; - p->type = pt_slowgrav; - p->phys = R_ParticlePhysics (p->type); - p->color = 67 + (mtwist_rand (&mt) & 3); - for (j = 0; j < 3; j++) - p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3); - - VectorAdd (old_origin, vec, old_origin); + add_particle (pt_slowgrav, pos + roffs (6), zero, 2, + 67 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } static void -R_WizTrail_QF (const entity_t *ent) +R_WizTrail_QF (vec4f_t start, vec4f_t end) { - float len; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t pos = start; while (len > 0) { static int tracercount; - len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.5; - p->type = pt_static; - p->phys = R_ParticlePhysics (p->type); - p->color = 52 + ((tracercount & 4) << 1); - + add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, + 52 + ((tracercount & 4) << 1), 0); tracercount++; - - VectorCopy (old_origin, p->org); - if (tracercount & 1) { - p->vel[0] = 30.0 * vec[1]; - p->vel[1] = 30.0 * -vec[0]; - } else { - p->vel[0] = 30.0 * -vec[1]; - p->vel[1] = 30.0 * vec[0]; - } - p->vel[2] = 0.0; - - VectorAdd (old_origin, vec, old_origin); + pos += vec; } } static void -R_FlameTrail_QF (const entity_t *ent) +R_FlameTrail_QF (vec4f_t start, vec4f_t end) { - float len; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t pos = start; while (len > 0) { static int tracercount; - len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = vr_data.realtime + 0.5; - p->type = pt_static; - p->phys = R_ParticlePhysics (p->type); - p->color = 230 + ((tracercount & 4) << 1); - + add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, + 230 + ((tracercount & 4) << 1), 0); tracercount++; - - VectorCopy (old_origin, p->org); - if (tracercount & 1) { - p->vel[0] = 30.0 * vec[1]; - p->vel[1] = 30.0 * -vec[0]; - } else { - p->vel[0] = 30.0 * -vec[1]; - p->vel[1] = 30.0 * vec[0]; - } - p->vel[2] = 0.0; - - VectorAdd (old_origin, vec, old_origin); + pos += vec; } } static void -R_VoorTrail_QF (const entity_t *ent) +R_VoorTrail_QF (vec4f_t start, vec4f_t end) { - float len; - int j; - particle_t *p; - vec3_t old_origin, vec; - vec3_t org; - if (!r_particles->int_val) return; - VectorCopy (ent->old_origin, old_origin); - VectorCopy (Transform_GetWorldPosition (ent->transform), org); - VectorSubtract (org, old_origin, vec); - len = VectorNormalize (vec); + vec4f_t vec = end - start; + float len = magnitudef (vec)[0]; + vec = normalf (vec); + vec4f_t zero = {}; + vec4f_t pos = start; while (len > 0) { len -= 3; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorZero (p->vel); - - p->die = vr_data.realtime + 0.3; - p->type = pt_static; - p->phys = R_ParticlePhysics (p->type); - p->color = 9 * 16 + 8 + (mtwist_rand (&mt) & 3); - for (j = 0; j < 3; j++) - p->org[j] = old_origin[j] + ((mtwist_rand (&mt) & 15) - 8); - - VectorAdd (old_origin, vec, old_origin); + add_particle (pt_static, pos + roffs (16), zero, 0.3, + 9 * 16 + 8 + (mtwist_rand (&mt) & 3), 0); + pos += vec; } } void sw32_R_DrawParticles (void) { - particle_t *p, **particle; - - VectorScale (vright, sw32_xscaleshrink, r_pright); - VectorScale (vup, sw32_yscaleshrink, r_pup); + VectorScale (vright, xscaleshrink, r_pright); + VectorScale (vup, yscaleshrink, r_pup); VectorCopy (vpn, r_ppn); - for (particle = &active_particles; *particle;) { - if ((*particle)->die < vr_data.realtime) { - p = (*particle)->next; - (*particle)->next = free_particles; - free_particles = (*particle); - (*particle) = p; - } else { - p = *particle; - particle = &(*particle)->next; + vec4f_t gravity = {0, 0, -vr_data.gravity, 0}; - sw32_D_DrawParticle (p); + unsigned j = 0; + for (unsigned i = 0; i < numparticles; i++) { + particle_t *p = &particles[i]; + partparm_t *parm = &partparams[i]; - p->phys (p); + if (p->live <= 0 || p->ramp >= parm->ramp_max) { + continue; + } + const int *ramp = partramps[j]; + if (i > j) { + particles[j] = *p; + partparams[j] = *parm; + partramps[j] = ramp; + } + p = &particles[j]; + parm = &partparams[j]; + j += 1; + + sw32_D_DrawParticle (p); + + float dT = vr_data.frametime; + p->pos += dT * p->vel; + p->vel += dT * (p->vel * parm->drag + gravity * parm->drag[3]); + p->ramp += dT * parm->ramp; + p->live -= dT; + if (ramp) { + p->icolor = ramp[(int)p->ramp]; } } + numparticles = j; } void @@ -832,50 +584,34 @@ sw32_r_particles_style_f (cvar_t *var) } static void -sw32_R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale, - const vec3_t vel, float die, int color, float alpha, +sw32_R_Particle_New (ptype_t type, int texnum, vec4f_t pos, float scale, + vec4f_t vel, float live, int color, float alpha, float ramp) { - particle_t *p; - - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorCopy (org, p->org); - p->color = color; - p->tex = texnum; - p->scale = scale; - p->alpha = alpha; - VectorCopy (vel, p->vel); - p->type = type; - p->phys = R_ParticlePhysics (p->type); - p->die = die; - p->ramp = ramp; + add_particle (type, pos, vel, live, color, ramp); } static void -sw32_R_Particle_NewRandom (ptype_t type, int texnum, const vec3_t org, - int org_fuzz, float scale, int vel_fuzz, float die, +sw32_R_Particle_NewRandom (ptype_t type, int texnum, vec4f_t org, + int org_fuzz, float scale, int vel_fuzz, float live, int color, float alpha, float ramp) { float o_fuzz = org_fuzz, v_fuzz = vel_fuzz; int rnd; - vec3_t porg, pvel; + vec4f_t pos, vel; rnd = mtwist_rand (&mt); - porg[0] = o_fuzz * ((rnd & 63) - 31.5) / 63.0 + org[0]; - porg[1] = o_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0 + org[1]; - porg[2] = o_fuzz * (((rnd >> 12) & 63) - 31.5) / 63.0 + org[2]; + pos[0] = o_fuzz * ((rnd & 63) - 31.5) / 63.0 + org[0]; + pos[1] = o_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0 + org[1]; + pos[2] = o_fuzz * (((rnd >> 12) & 63) - 31.5) / 63.0 + org[2]; + pos[3] = 1; rnd = mtwist_rand (&mt); - pvel[0] = v_fuzz * ((rnd & 63) - 31.5) / 63.0; - pvel[1] = v_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0; - pvel[2] = v_fuzz * (((rnd >> 12) & 63) - 31.5) / 63.0; + vel[0] = v_fuzz * ((rnd & 63) - 31.5) / 63.0; + vel[1] = v_fuzz * (((rnd >> 6) & 63) - 31.5) / 63.0; + vel[2] = v_fuzz * (((rnd >> 12) & 63) - 31.5) / 63.0; + vel[3] = 0; - sw32_R_Particle_New (type, texnum, porg, scale, pvel, die, color, alpha, ramp); + add_particle (type, pos, vel, live, color, ramp); } static vid_particle_funcs_t particles_QF = { diff --git a/libs/video/renderer/vulkan/vulkan_particles.c b/libs/video/renderer/vulkan/vulkan_particles.c index a20e66b25..8c6679ba2 100644 --- a/libs/video/renderer/vulkan/vulkan_particles.c +++ b/libs/video/renderer/vulkan/vulkan_particles.c @@ -67,130 +67,130 @@ Vulkan_InitParticles (vulkan_ctx_t *ctx) } static void -R_RocketTrail_QF (const entity_t *ent) +R_RocketTrail_QF (vec4f_t start, vec4f_t end) { } static void -R_GrenadeTrail_QF (const entity_t *ent) +R_GrenadeTrail_QF (vec4f_t start, vec4f_t end) { } static void -R_BloodTrail_QF (const entity_t *ent) +R_BloodTrail_QF (vec4f_t start, vec4f_t end) { } static void -R_SlightBloodTrail_QF (const entity_t *ent) +R_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) { } static void -R_WizTrail_QF (const entity_t *ent) +R_WizTrail_QF (vec4f_t start, vec4f_t end) { } static void -R_FlameTrail_QF (const entity_t *ent) +R_FlameTrail_QF (vec4f_t start, vec4f_t end) { } static void -R_VoorTrail_QF (const entity_t *ent) +R_VoorTrail_QF (vec4f_t start, vec4f_t end) { } static void -R_GlowTrail_QF (const entity_t *ent, int glow_color) +R_GlowTrail_QF (vec4f_t start, vec4f_t end, int glow_color) { } static void -R_RunParticleEffect_QF (const vec3_t org, const vec3_t dir, int color, +R_RunParticleEffect_QF (vec4f_t org, vec4f_t dir, int color, int count) { } static void -R_BloodPuffEffect_QF (const vec3_t org, int count) +R_BloodPuffEffect_QF (vec4f_t org, int count) { } static void -R_GunshotEffect_QF (const vec3_t org, int count) +R_GunshotEffect_QF (vec4f_t org, int count) { } static void -R_LightningBloodEffect_QF (const vec3_t org) +R_LightningBloodEffect_QF (vec4f_t org) { } static void -R_SpikeEffect_QF (const vec3_t org) +R_SpikeEffect_QF (vec4f_t org) { } static void -R_KnightSpikeEffect_QF (const vec3_t org) +R_KnightSpikeEffect_QF (vec4f_t org) { } static void -R_SuperSpikeEffect_QF (const vec3_t org) +R_SuperSpikeEffect_QF (vec4f_t org) { } static void -R_WizSpikeEffect_QF (const vec3_t org) +R_WizSpikeEffect_QF (vec4f_t org) { } static void -R_BlobExplosion_QF (const vec3_t org) +R_BlobExplosion_QF (vec4f_t org) { } static void -R_ParticleExplosion_QF (const vec3_t org) +R_ParticleExplosion_QF (vec4f_t org) { } static void -R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength) +R_ParticleExplosion2_QF (vec4f_t org, int colorStart, int colorLength) { } static void -R_LavaSplash_QF (const vec3_t org) +R_LavaSplash_QF (vec4f_t org) { } static void -R_TeleportSplash_QF (const vec3_t org) +R_TeleportSplash_QF (vec4f_t org) { } static void -R_DarkFieldParticles_ID (const entity_t *ent) +R_DarkFieldParticles_ID (vec4f_t org) { } static void -R_EntityParticles_ID (const entity_t *ent) +R_EntityParticles_ID (vec4f_t org) { } static void -R_Particle_New (ptype_t type, int texnum, const vec3_t org, - float scale, const vec3_t vel, float die, +R_Particle_New (ptype_t type, int texnum, vec4f_t org, + float scale, vec4f_t vel, float die, int color, float alpha, float ramp) { } static void -R_Particle_NewRandom (ptype_t type, int texnum, const vec3_t org, +R_Particle_NewRandom (ptype_t type, int texnum, vec4f_t org, int org_fuzz, float scale, int vel_fuzz, float die, int color, float alpha, float ramp)