diff --git a/include/QF/Vulkan/qf_particles.h b/include/QF/Vulkan/qf_particles.h index 45754fc85..52a228299 100644 --- a/include/QF/Vulkan/qf_particles.h +++ b/include/QF/Vulkan/qf_particles.h @@ -60,10 +60,7 @@ typedef struct particlectx_s { struct cvar_s; struct vulkan_ctx_s;; -void Vulkan_ClearParticles (struct vulkan_ctx_s *ctx); -void Vulkan_InitParticles (struct vulkan_ctx_s *ctx); -void Vulkan_r_easter_eggs_f (struct cvar_s *var, struct vulkan_ctx_s *ctx); -void Vulkan_r_particles_style_f (struct cvar_s *var, struct vulkan_ctx_s *ctx); +struct r_particle_ctx_s *Vulkan_ParticleContext (struct vulkan_ctx_s *ctx); void Vulkan_Particles_Init (struct vulkan_ctx_s *ctx); void Vulkan_Particles_Shutdown (struct vulkan_ctx_s *ctx); void Vulkan_DrawParticles (struct vulkan_ctx_s *ctx); diff --git a/include/QF/plugin/vid_render.h b/include/QF/plugin/vid_render.h index 57e72a92f..e3fba0342 100644 --- a/include/QF/plugin/vid_render.h +++ b/include/QF/plugin/vid_render.h @@ -44,42 +44,6 @@ struct mod_sprite_ctx_s; All video plugins must export these functions */ -typedef struct vid_particle_funcs_s { - 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) (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) (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, 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, vec4f_t org, - int org_fuzz, float scale, int vel_fuzz, - float die, int color, float alpha, - float ramp); -} vid_particle_funcs_t; - typedef struct vid_model_funcs_s { size_t texture_render_size;// size of renderer specific texture data void (*Mod_LoadLighting) (model_t *mod, bsp_t *bsp); @@ -159,13 +123,8 @@ typedef struct vid_render_funcs_s { void (*R_DecayLights) (double frametime); void (*R_ViewChanged) (void); - void (*R_ClearParticles) (void); - void (*R_InitParticles) (void); void (*SCR_ScreenShot_f) (void); - void (*r_easter_eggs_f) (struct cvar_s *var); - void (*r_particles_style_f) (struct cvar_s *var); - vid_particle_funcs_t *particles; vid_model_funcs_t *model_funcs; } vid_render_funcs_t; diff --git a/include/QF/render.h b/include/QF/render.h index b10c6585e..617952ed3 100644 --- a/include/QF/render.h +++ b/include/QF/render.h @@ -54,6 +54,49 @@ typedef enum { pt_flame } ptype_t; +typedef enum { + part_tex_dot, + part_tex_spark, + part_tex_smoke, +} ptextype_t; + +typedef struct particle_s particle_t; + +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +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 ramp; + 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; + +// FIXME these really shouldn't be global, but they speed up particle creation +extern unsigned int r_maxparticles; +extern unsigned int numparticles; +extern struct particle_s *particles; +extern struct partparm_s *partparams; +extern const int **partramps; + extern struct vid_render_funcs_s *r_funcs; extern struct vid_render_data_s *r_data; diff --git a/include/client/particles.h b/include/client/particles.h new file mode 100644 index 000000000..0e499f53b --- /dev/null +++ b/include/client/particles.h @@ -0,0 +1,74 @@ +/* + particles.h + + Client particles handling + + Copyright (C) 2021 Bill Currie + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifndef __client_particles_h_ +#define __client_particles_h_ + +#include "QF/render.h" + +typedef struct cl_particle_funcs_s { + void (*RocketTrail) (vec4f_t start, vec4f_t end); + void (*GrenadeTrail) (vec4f_t start, vec4f_t end); + void (*BloodTrail) (vec4f_t start, vec4f_t end); + void (*SlightBloodTrail) (vec4f_t start, vec4f_t end); + void (*WizTrail) (vec4f_t start, vec4f_t end); + void (*FlameTrail) (vec4f_t start, vec4f_t end); + void (*VoorTrail) (vec4f_t start, vec4f_t end); + void (*GlowTrail) (vec4f_t start, vec4f_t end, int glow_color); + + void (*RunParticleEffect) (vec4f_t org, vec4f_t dir, int color, int count); + void (*BloodPuffEffect) (vec4f_t org, int count); + void (*GunshotEffect) (vec4f_t org, int count); + void (*LightningBloodEffect) (vec4f_t org); + void (*SpikeEffect) (vec4f_t org); + void (*KnightSpikeEffect) (vec4f_t org); + void (*SuperSpikeEffect) (vec4f_t org); + void (*WizSpikeEffect) (vec4f_t org); + + void (*BlobExplosion) (vec4f_t org); + void (*ParticleExplosion) (vec4f_t org); + void (*ParticleExplosion2) (vec4f_t org, int colorStart, int colorLength); + void (*LavaSplash) (vec4f_t org); + void (*TeleportSplash) (vec4f_t org); + void (*DarkFieldParticles) (vec4f_t org); + void (*EntityParticles) (vec4f_t org); + + void (*Particle_New) (ptype_t type, int texnum, vec4f_t org, + float scale, vec4f_t vel, float die, + int color, float alpha, float ramp); + void (*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); +} cl_particle_funcs_t; + +extern cl_particle_funcs_t *clp_funcs; +extern float cl_frametime; +extern float cl_realtime; + +void CL_Particles_Init (void); + +#endif // __client_particles_h_ diff --git a/include/d_iface.h b/include/d_iface.h index 873ac2b7b..f4272e508 100644 --- a/include/d_iface.h +++ b/include/d_iface.h @@ -56,45 +56,6 @@ typedef struct float zi; } emitpoint_t; -typedef enum { - part_tex_dot, - part_tex_spark, - part_tex_smoke, -} ptextype_t; - -typedef struct particle_s particle_t; - -// !!! if this is changed, it must be changed in d_ifacea.h too !!! -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 ramp; - 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/r_cvar.h b/include/r_cvar.h index e8a85a679..c8b02f489 100644 --- a/include/r_cvar.h +++ b/include/r_cvar.h @@ -1,9 +1,5 @@ #include "QF/mathlib.h" -extern struct cvar_s *easter_eggs; -extern void r_easter_eggs_f (struct cvar_s *var); -extern void r_particles_style_f (struct cvar_s *var); - extern void gl_overbright_f (struct cvar_s *cvar); extern struct cvar_s *cl_crossx; @@ -80,7 +76,6 @@ extern struct cvar_s *r_numsurfs; extern struct cvar_s *r_particles; extern struct cvar_s *r_particles_max; extern struct cvar_s *r_particles_nearclip; -extern struct cvar_s *r_particles_style; extern struct cvar_s *r_reportedgeout; extern struct cvar_s *r_reportsurfout; extern struct cvar_s *r_shadows; diff --git a/include/r_dynamic.h b/include/r_dynamic.h index 1027879bc..611d2a158 100644 --- a/include/r_dynamic.h +++ b/include/r_dynamic.h @@ -59,10 +59,4 @@ void R_MaxParticlesCheck (struct cvar_s *r_particles, struct cvar_s *r_particles_max); void R_InitSprites (void); -extern unsigned int r_maxparticles; -extern unsigned int numparticles; -extern struct particle_s *particles; -extern struct partparm_s *partparams; -extern const int **partramps; - #endif // _R_DYNAMIC_H diff --git a/libs/client/Makemodule.am b/libs/client/Makemodule.am index 24e28397f..0d926b242 100644 --- a/libs/client/Makemodule.am +++ b/libs/client/Makemodule.am @@ -6,6 +6,7 @@ libs_client_libQFclient_la_SOURCES= \ libs/client/cl_effects.c \ libs/client/cl_entities.c \ libs/client/cl_input.c \ + libs/client/cl_particles.c \ libs/client/cl_temp_entities.c \ libs/client/locs.c \ libs/client/old_keys.c diff --git a/libs/client/cl_effects.c b/libs/client/cl_effects.c index faa451839..f327a1e6d 100644 --- a/libs/client/cl_effects.c +++ b/libs/client/cl_effects.c @@ -45,6 +45,7 @@ #include "client/entities.h" #include "client/effects.h" +#include "client/particles.h" void CL_NewDlight (int key, vec4f_t org, int effects, byte glow_size, @@ -132,23 +133,21 @@ CL_ModelEffects (entity_t *ent, int num, int glow_color, double time) VectorSet (0.9, 0.7, 0.0, dl->color); dl->color[3] = 0.7; } - r_funcs->particles->R_RocketTrail (old_origin, ent_origin); + clp_funcs->RocketTrail (old_origin, ent_origin); } else if (model->flags & EF_GRENADE) - r_funcs->particles->R_GrenadeTrail (old_origin, ent_origin); + clp_funcs->GrenadeTrail (old_origin, ent_origin); else if (model->flags & EF_GIB) - r_funcs->particles->R_BloodTrail (old_origin, ent_origin); + clp_funcs->BloodTrail (old_origin, ent_origin); else if (model->flags & EF_ZOMGIB) - r_funcs->particles->R_SlightBloodTrail (old_origin, ent_origin); + clp_funcs->SlightBloodTrail (old_origin, ent_origin); else if (model->flags & EF_TRACER) - r_funcs->particles->R_WizTrail (old_origin, ent_origin); + clp_funcs->WizTrail (old_origin, ent_origin); else if (model->flags & EF_TRACER2) - r_funcs->particles->R_FlameTrail (old_origin, ent_origin); + clp_funcs->FlameTrail (old_origin, ent_origin); else if (model->flags & EF_TRACER3) - r_funcs->particles->R_VoorTrail (old_origin, ent_origin); + clp_funcs->VoorTrail (old_origin, ent_origin); else if (model->flags & EF_GLOWTRAIL) - if (r_funcs->particles->R_GlowTrail) - r_funcs->particles->R_GlowTrail (old_origin, ent_origin, - glow_color); + clp_funcs->GlowTrail (old_origin, ent_origin, glow_color); } void @@ -175,7 +174,7 @@ 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 (position); + clp_funcs->EntityParticles (position); if (state->effects & EF_MUZZLEFLASH) { vec4f_t fv = Transform_Forward (ent->transform); CL_MuzzleFlash (position, fv, 16, num, time); diff --git a/libs/client/cl_particles.c b/libs/client/cl_particles.c new file mode 100644 index 000000000..f13a765f0 --- /dev/null +++ b/libs/client/cl_particles.c @@ -0,0 +1,1347 @@ +/* + cl_particles.c + + OpenGL particle system. + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include + +#include "QF/cmd.h" +#include "QF/cvar.h" +#include "QF/mersenne.h" +#include "QF/qargs.h" +#include "QF/quakefs.h" +#include "QF/render.h" +#include "QF/sys.h" +#include "QF/va.h" + +#include "QF/scene/entity.h" + +#include "compat.h" + +#include "client/particles.h" + +float cl_frametime; +float cl_realtime; +cl_particle_funcs_t *clp_funcs; + +static mtstate_t mt; // private PRNG state + +static cvar_t *easter_eggs; +static cvar_t *particles_style; + +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, +}; + +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, +}; + +static partparm_t __attribute__((pure)) +particle_params (ptype_t type) +{ + if (type > pt_flame) { + Sys_Error ("particle_params: invalid particle type"); + } + return part_params[type]; +} + +static const int * __attribute__((pure)) +particle_ramp (ptype_t type) +{ + if (type > pt_flame) { + Sys_Error ("particle_ramp: invalid particle type"); + } + return part_ramps[type]; +} + +inline static int +particle_new (ptype_t type, int texnum, vec4f_t pos, float scale, + vec4f_t vel, float live, int color, float alpha, float ramp) +{ + if (numparticles >= r_maxparticles) + return 0; + 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 = alpha; + p->tex = texnum; + p->ramp = ramp; + p->scale = scale; + p->live = live; + + *parm = particle_params (type); + *rampptr = particle_ramp (type); + if (*rampptr) { + p->icolor = (*rampptr) [(int) p->ramp]; + } + return 1; +} + +/* + particle_new_random + + note that org_fuzz & vel_fuzz should be ints greater than 0 if you are + going to bother using this function. +*/ +inline static int +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; + 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; + + return particle_new (type, texnum, porg, scale, pvel, live, color, alpha, + ramp); +} + +/* +inline static void +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; + + porg[0] = qfrandom (org_fuzz * 2) - org_fuzz + org[0]; + porg[1] = qfrandom (org_fuzz * 2) - org_fuzz + org[1]; + porg[2] = qfrandom (org_fuzz * 2) - org_fuzz + org[2]; + 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, 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 +CL_ClearParticles (void) +{ + numparticles = 0; +} +*/ + + +static void +pointfile_f (void) +{ + const char *name; + char *mapname; + int c; + QFile *f; + + mapname = strdup (r_worldentity.renderer.model->path); + if (!mapname) + Sys_Error ("Can't duplicate mapname!"); + QFS_StripExtension (mapname, mapname); + + name = va (0, "%s.pts", mapname); + free (mapname); + + f = QFS_FOpenFile (name); + if (!f) { + Sys_Printf ("couldn't open %s\n", name); + return; + } + + 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)); + int r = sscanf (buf, "%f %f %f\n", &org[0], &org[1], &org[2]); + if (r != 3) + break; + c++; + + if (numparticles >= r_maxparticles) { + Sys_MaskPrintf (SYS_dev, "Not enough free particles\n"); + break; + } else { + particle_new (pt_static, part_tex_dot, org, 1.5, zero, + 99999, (-c) & 15, 1.0, 0.0); + } + } + Qclose (f); + Sys_MaskPrintf (SYS_dev, "%i points read\n", c); +} + +static void +CL_ParticleExplosion_QF (vec4f_t org) +{ +// CL_NewExplosion (org); + if (numparticles >= r_maxparticles) + return; + particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8, + 5.0, (mtwist_rand (&mt) & 7) + 8, + 0.5 + qfrandom (0.25), 0.0); +} + +static void +CL_ParticleExplosion2_QF (vec4f_t org, int colorStart, int colorLength) +{ + unsigned int i, j = 512; + + if (numparticles >= r_maxparticles) + return; + else if (numparticles + j >= r_maxparticles) + j = r_maxparticles - numparticles; + + for (i = 0; i < j; i++) { + particle_new_random (pt_blob, part_tex_dot, org, 16, 2, 256, + 0.3, + colorStart + (i % colorLength), 1.0, 0.0); + } +} + +static void +CL_BlobExplosion_QF (vec4f_t org) +{ + unsigned int i; + unsigned int j = 1024; + + if (numparticles >= r_maxparticles) + 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, 2, 256, + 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, + 1.0 + (mtwist_rand (&mt) & 7) * 0.05, + 150 + i % 6, 1.0, 0.0); + } +} + +static inline void +CL_RunSparkEffect_QF (vec4f_t org, int count, int ofuzz) +{ + vec4f_t zero = {}; + particle_new (pt_smokecloud, part_tex_smoke, org, ofuzz * 0.08, + zero, 9, 12 + (mtwist_rand (&mt) & 3), + 0.25 + qfrandom (0.125), 0.0); + + if (count > 0) { + int orgfuzz = ofuzz * 3 / 4; + if (orgfuzz < 1) + orgfuzz = 1; + + while (count--) { + int color = mtwist_rand (&mt) & 7; + + particle_new_random (pt_fallfadespark, part_tex_dot, org, orgfuzz, + 0.7, 96, 5.0, 0, 1.0, color); + } + } +} + +static inline void +CL_BloodPuff_QF (vec4f_t org, int count) +{ + 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 +CL_BloodPuffEffect_QF (vec4f_t org, int count) +{ + CL_BloodPuff_QF (org, count); +} + +static void +CL_GunshotEffect_QF (vec4f_t org, int count) +{ + int scale = 16; + + scale += count / 15; + CL_RunSparkEffect_QF (org, count >> 1, scale); +} + +static void +CL_LightningBloodEffect_QF (vec4f_t org) +{ + CL_BloodPuff_QF (org, 50); + + 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); + + for (int count = 7; count-- > 0; ) { + particle_new_random (pt_fallfade, part_tex_spark, org, 12, 2.0, 128, + 5.0, 244 + (count % 3), 1.0, 0.0); + } +} + +static void +CL_RunParticleEffect_QF (vec4f_t org, vec4f_t dir, int color, int count) +{ + float scale = pow (count, 0.23); + + for (int i = 0; i < count; i++) { + int rnd = mtwist_rand (&mt); + + // Note that ParseParticleEffect handles (dir * 15) + 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 +CL_SpikeEffect_QF (vec4f_t org) +{ + CL_RunSparkEffect_QF (org, 5, 8); +} + +static void +CL_SuperSpikeEffect_QF (vec4f_t org) +{ + CL_RunSparkEffect_QF (org, 10, 8); +} + +static void +CL_KnightSpikeEffect_QF (vec4f_t org) +{ + 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, + 5.0, 234, 1.0, 0.0); + } +} + +static void +CL_WizSpikeEffect_QF (vec4f_t org) +{ + 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, + 5.0, 63, 1.0, 0.0); + } +} + +static void +CL_LavaSplash_QF (vec4f_t org) +{ + 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 +CL_TeleportSplash_QF (vec4f_t org) +{ + 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); + } + } + } +} + +static void +CL_RocketTrail_QF (vec4f_t start, vec4f_t end) +{ + if (numparticles >= r_maxparticles) + return; + + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = cl_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) { + float pscalenext = 1.5 + qfrandom (1.5); + float dist = (pscale + pscalenext) * 3.0; + float percent = len * origlen; + + 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; + pos += step; + pscale = pscalenext; + } +} + +static void +CL_GrenadeTrail_QF (vec4f_t start, vec4f_t end) +{ + if (numparticles >= r_maxparticles) + return; + + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = cl_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) { + float pscalenext = 6.0 + qfrandom (7.0); + float dist = (pscale + pscalenext) * 2.0; + float percent = len * origlen; + + 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; + pos += step; + pscale = pscalenext; + } +} + +static void +CL_BloodTrail_QF (vec4f_t start, vec4f_t end) +{ + if (numparticles >= r_maxparticles) + return; + + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = cl_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) { + 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; + + 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; + pos += step; + pscale = pscalenext; + } +} + +static void +CL_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) +{ + if (numparticles >= r_maxparticles) + return; + + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = cl_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) { + 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; + + 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; + pos += step; + pscale = pscalenext; + } +} + +static void +CL_WizTrail_QF (vec4f_t start, vec4f_t end) +{ + float dist = 3.0; + + if (numparticles >= r_maxparticles) + return; + + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = cl_frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t pos = start; + while (len < maxlen) { + static int tracercount; + float percent = len * origlen; + + 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; + pos += step; + } +} + +static void +CL_FlameTrail_QF (vec4f_t start, vec4f_t end) +{ + float dist = 3.0; + + if (numparticles >= r_maxparticles) + return; + + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = cl_frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t pos = start; + while (len < maxlen) { + static int tracercount; + float percent = len * origlen; + + 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); + len += dist; + pos += step; + } +} + +static void +CL_VoorTrail_QF (vec4f_t start, vec4f_t end) +{ + float dist = 3.0; + + if (numparticles >= r_maxparticles) + return; + + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = cl_frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; + while (len < maxlen) { + float percent = len * origlen; + + 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); + len += dist; + pos += step; + } +} + +static void +CL_GlowTrail_QF (vec4f_t start, vec4f_t end, int glow_color) +{ + float dist = 3.0; + + if (numparticles >= r_maxparticles) + return; + + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = cl_frametime / maxlen; + vec4f_t step = (maxlen - dist) * vec; + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; + while (len < maxlen) { + float percent = len * origlen; + + 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; + pos += step; + } +} + +static void +CL_ParticleExplosion_EE (vec4f_t org) +{ +/* + CL_NewExplosion (org); +*/ + if (numparticles >= r_maxparticles) + return; + particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8, + 5.0, mtwist_rand (&mt) & 255, + 0.5 + qfrandom (0.25), 0.0); +} + +static void +CL_TeleportSplash_EE (vec4f_t org) +{ + 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); + } + } + } +} + +static void +CL_RocketTrail_EE (vec4f_t start, vec4f_t end) +{ + if (numparticles >= r_maxparticles) + return; + + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = cl_frametime / maxlen; + float pscale = 1.5 + qfrandom (1.5); + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; + while (len < maxlen) { + float pscalenext = 1.5 + qfrandom (1.5); + float dist = (pscale + pscalenext) * 3.0; + float percent = len * origlen; + + 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; + pos += len * vec; + pscale = pscalenext; + } +} + +static void +CL_GrenadeTrail_EE (vec4f_t start, vec4f_t end) +{ + vec4f_t vec = end - start; + float maxlen = magnitudef (vec)[0]; + vec = normalf (vec); + + float origlen = cl_frametime / maxlen; + float pscale = 6.0 + qfrandom (7.0); + + float len = 0; + vec4f_t zero = {}; + vec4f_t pos = start; + while (len < maxlen) { + float pscalenext = 6.0 + qfrandom (7.0); + float dist = (pscale + pscalenext) * 2.0; + float percent = len * origlen; + + 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); + len += dist; + pos += len * vec; + pscale = pscalenext; + } +} + +static void +CL_ParticleExplosion_ID (vec4f_t org) +{ + 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 +CL_BlobExplosion_ID (vec4f_t org) +{ + 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? +CL_RunParticleEffect_ID (vec4f_t org, vec4f_t dir, int color, int count) +{ + 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 +CL_BloodPuffEffect_ID (vec4f_t org, int count) +{ + vec4f_t zero = {}; + CL_RunParticleEffect_ID (org, zero, 73, count); +} + +static void +CL_GunshotEffect_ID (vec4f_t org, int count) +{ + vec4f_t zero = {}; + CL_RunParticleEffect_ID (org, zero, 0, count); +} + +static void +CL_LightningBloodEffect_ID (vec4f_t org) +{ + vec4f_t zero = {}; + CL_RunParticleEffect_ID (org, zero, 225, 50); +} + +static void +CL_SpikeEffect_ID (vec4f_t org) +{ + vec4f_t zero = {}; + CL_RunParticleEffect_ID (org, zero, 0, 10); +} + +static void +CL_SuperSpikeEffect_ID (vec4f_t org) +{ + vec4f_t zero = {}; + CL_RunParticleEffect_ID (org, zero, 0, 20); +} + +static void +CL_KnightSpikeEffect_ID (vec4f_t org) +{ + vec4f_t zero = {}; + CL_RunParticleEffect_ID (org, zero, 226, 20); +} + +static void +CL_WizSpikeEffect_ID (vec4f_t org) +{ + vec4f_t zero = {}; + CL_RunParticleEffect_ID (org, zero, 20, 30); +} + +static void +CL_LavaSplash_ID (vec4f_t org) +{ + 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 +CL_TeleportSplash_ID (vec4f_t org) +{ + 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 +CL_DarkFieldParticles_ID (vec4f_t 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 + }; + + add_particle (pt_slowgrav, org + offs, vel * dir, + 0.2 + (rnd & 7) * 0.02, + 150 + mtwist_rand (&mt) % 6, 0); + } + } + } +} + +#define num_normals (int)(sizeof (normals) / sizeof (normals[0])) +static vec4f_t normals[] = { +#include "anorms.h" +}; +static vec4f_t velocities[num_normals]; + +static void +CL_EntityParticles_ID (vec4f_t org) +{ + float angle, sp, sy, cp, cy; // cr, sr + float beamlength = 16.0, dist = 64.0; + + for (int i = 0; i < num_normals; i++) { + int k; + for (k = 0; k < 3; k++) { + velocities[i][k] = (mtwist_rand (&mt) & 255) * 0.01; + } + } + + vec4f_t zero = {}; + for (int i = 0; i < num_normals; i++) { + angle = cl_realtime * velocities[i][0]; + cy = cos (angle); + sy = sin (angle); + angle = cl_realtime * velocities[i][1]; + cp = cos (angle); + sp = sin (angle); +// Next 3 lines results aren't currently used, may be in future. --Despair +// angle = cl_realtime * avelocities[i][2]; +// sr = sin (angle); +// cr = cos (angle); + + 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 +CL_RocketTrail_ID (vec4f_t start, vec4f_t end) +{ + 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; + add_particle (pt_fire, pos + roffs (6), zero, 2, + 0, (mtwist_rand (&mt) & 3)); + pos += vec; + } +} + +static void +CL_GrenadeTrail_ID (vec4f_t start, vec4f_t end) +{ + 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; + add_particle (pt_fire, pos + roffs (6), zero, 2, + 0, (mtwist_rand (&mt) & 3) + 2); + pos += vec; + } +} + +static void +CL_BloodTrail_ID (vec4f_t start, vec4f_t end) +{ + 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; + add_particle (pt_slowgrav, pos + roffs (6), zero, 2, + 67 + (mtwist_rand (&mt) & 3), 0); + pos += vec; + } +} + +static void +CL_SlightBloodTrail_ID (vec4f_t start, vec4f_t end) +{ + 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; + add_particle (pt_slowgrav, pos + roffs (6), zero, 2, + 67 + (mtwist_rand (&mt) & 3), 0); + pos += vec; + } +} + +static void +CL_WizTrail_ID (vec4f_t start, vec4f_t end) +{ + 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; + add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, + 52 + ((tracercount & 4) << 1), 0); + tracercount++; + pos += vec; + } +} + +static void +CL_FlameTrail_ID (vec4f_t start, vec4f_t end) +{ + 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; + add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, + 230 + ((tracercount & 4) << 1), 0); + tracercount++; + pos += vec; + } +} + +static void +CL_VoorTrail_ID (vec4f_t start, vec4f_t end) +{ + 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; + add_particle (pt_static, pos + roffs (16), zero, 0.3, + 9 * 16 + 8 + (mtwist_rand (&mt) & 3), 0); + pos += vec; + } +} + +static void +CL_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, live, color, alpha, ramp); +} + +static void +CL_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, live, + color, alpha, ramp); +} + +static cl_particle_funcs_t particles_QF = { + CL_RocketTrail_QF, + CL_GrenadeTrail_QF, + CL_BloodTrail_QF, + CL_SlightBloodTrail_QF, + CL_WizTrail_QF, + CL_FlameTrail_QF, + CL_VoorTrail_QF, + CL_GlowTrail_QF, + CL_RunParticleEffect_QF, + CL_BloodPuffEffect_QF, + CL_GunshotEffect_QF, + CL_LightningBloodEffect_QF, + CL_SpikeEffect_QF, + CL_KnightSpikeEffect_QF, + CL_SuperSpikeEffect_QF, + CL_WizSpikeEffect_QF, + CL_BlobExplosion_QF, + CL_ParticleExplosion_QF, + CL_ParticleExplosion2_QF, + CL_LavaSplash_QF, + CL_TeleportSplash_QF, + CL_DarkFieldParticles_ID, + CL_EntityParticles_ID, + CL_Particle_New, + CL_Particle_NewRandom, +}; + +static cl_particle_funcs_t particles_ID = { + CL_RocketTrail_ID, + CL_GrenadeTrail_ID, + CL_BloodTrail_ID, + CL_SlightBloodTrail_ID, + CL_WizTrail_ID, + CL_FlameTrail_ID, + CL_VoorTrail_ID, + CL_GlowTrail_QF, + CL_RunParticleEffect_ID, + CL_BloodPuffEffect_ID, + CL_GunshotEffect_ID, + CL_LightningBloodEffect_ID, + CL_SpikeEffect_ID, + CL_KnightSpikeEffect_ID, + CL_SuperSpikeEffect_ID, + CL_WizSpikeEffect_ID, + CL_BlobExplosion_ID, + CL_ParticleExplosion_ID, + CL_ParticleExplosion2_QF, + CL_LavaSplash_ID, + CL_TeleportSplash_ID, + CL_DarkFieldParticles_ID, + CL_EntityParticles_ID, + CL_Particle_New, + CL_Particle_NewRandom, +}; + +static cl_particle_funcs_t particles_QF_egg = { + CL_RocketTrail_EE, + CL_GrenadeTrail_EE, + CL_BloodTrail_QF, + CL_SlightBloodTrail_QF, + CL_WizTrail_QF, + CL_FlameTrail_QF, + CL_VoorTrail_QF, + CL_GlowTrail_QF, + CL_RunParticleEffect_QF, + CL_BloodPuffEffect_QF, + CL_GunshotEffect_QF, + CL_LightningBloodEffect_QF, + CL_SpikeEffect_QF, + CL_KnightSpikeEffect_QF, + CL_SuperSpikeEffect_QF, + CL_WizSpikeEffect_QF, + CL_BlobExplosion_QF, + CL_ParticleExplosion_EE, + CL_ParticleExplosion2_QF, + CL_LavaSplash_QF, + CL_TeleportSplash_EE, + CL_DarkFieldParticles_ID, + CL_EntityParticles_ID, + CL_Particle_New, + CL_Particle_NewRandom, +}; + +static cl_particle_funcs_t particles_ID_egg = { + CL_RocketTrail_EE, + CL_GrenadeTrail_EE, + CL_BloodTrail_ID, + CL_SlightBloodTrail_ID, + CL_WizTrail_ID, + CL_FlameTrail_ID, + CL_VoorTrail_ID, + CL_GlowTrail_QF, + CL_RunParticleEffect_ID, + CL_BloodPuffEffect_ID, + CL_GunshotEffect_ID, + CL_LightningBloodEffect_ID, + CL_SpikeEffect_ID, + CL_KnightSpikeEffect_ID, + CL_SuperSpikeEffect_ID, + CL_WizSpikeEffect_ID, + CL_BlobExplosion_ID, + CL_ParticleExplosion_EE, + CL_ParticleExplosion2_QF, + CL_LavaSplash_ID, + CL_TeleportSplash_EE, + CL_DarkFieldParticles_ID, + CL_EntityParticles_ID, + CL_Particle_New, + CL_Particle_NewRandom, +}; + +static void +easter_eggs_f (cvar_t *var) +{ + if (easter_eggs) { + if (easter_eggs->int_val) { + if (particles_style->int_val) { + clp_funcs = &particles_QF_egg; + } else { + clp_funcs = &particles_ID_egg; + } + } else if (particles_style) { + if (particles_style->int_val) { + clp_funcs = &particles_QF; + } else { + clp_funcs = &particles_ID; + } + } + } +} + +static void +particles_style_f (cvar_t *var) +{ + easter_eggs_f (easter_eggs); +} + +static void +CL_ParticleFunctionInit (void) +{ + particles_style_f (particles_style); + easter_eggs_f (easter_eggs); +} + +/* + */ +void +CL_Particles_Init (void) +{ + mtwist_seed (&mt, 0xdeadbeef); + Cmd_AddCommand ("pointfile", pointfile_f, + "Load a pointfile to determine map leaks."); + easter_eggs = Cvar_Get ("easter_eggs", "0", CVAR_NONE, easter_eggs_f, + "Enables easter eggs."); + particles_style = Cvar_Get ("particles_style", "1", CVAR_ARCHIVE, + particles_style_f, + "Sets particle style. 0 for Id, 1 for QF."); + CL_ParticleFunctionInit (); +} diff --git a/libs/client/cl_temp_entities.c b/libs/client/cl_temp_entities.c index 412946f65..9ce856d70 100644 --- a/libs/client/cl_temp_entities.c +++ b/libs/client/cl_temp_entities.c @@ -47,7 +47,9 @@ #include "QF/plugin/vid_render.h" //FIXME #include "QF/scene/entity.h" +#include "client/effects.h" #include "client/entities.h" +#include "client/particles.h" #include "client/temp_entities.h" typedef struct tent_s { @@ -337,13 +339,13 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, case TE_Blood: count = MSG_ReadByte (net_message) * 20; MSG_ReadCoordV (net_message, &position[0]); - r_funcs->particles->R_BloodPuffEffect (position, count); + clp_funcs->BloodPuffEffect (position, count); break; case TE_Explosion: MSG_ReadCoordV (net_message, &position[0]); // particles - r_funcs->particles->R_ParticleExplosion (position); + clp_funcs->ParticleExplosion (position); // light dl = r_funcs->R_AllocDlight (0); @@ -380,8 +382,7 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, colorStart = MSG_ReadByte (net_message); colorLength = MSG_ReadByte (net_message); S_StartSound (-1, 0, cl_sfx_r_exp3, &position[0], 1, 1); - r_funcs->particles->R_ParticleExplosion2 (position, colorStart, - colorLength); + clp_funcs->ParticleExplosion2 (position, colorStart, colorLength); dl = r_funcs->R_AllocDlight (0); if (!dl) break; @@ -398,7 +399,7 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, MSG_ReadCoordV (net_message, &position[0]); MSG_ReadCoordV (net_message, color); // OUCH! color[3] = 0.7; - r_funcs->particles->R_ParticleExplosion (position); + clp_funcs->ParticleExplosion (position); S_StartSound (-1, 0, cl_sfx_r_exp3, &position[0], 1, 1); dl = r_funcs->R_AllocDlight (0); if (dl) { @@ -411,21 +412,21 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, break; case TE_Gunshot1: MSG_ReadCoordV (net_message, &position[0]); - r_funcs->particles->R_GunshotEffect (position, 20); + clp_funcs->GunshotEffect (position, 20); break; case TE_Gunshot2: count = MSG_ReadByte (net_message) * 20; MSG_ReadCoordV (net_message, &position[0]); - r_funcs->particles->R_GunshotEffect (position, count); + clp_funcs->GunshotEffect (position, count); break; case TE_KnightSpike: MSG_ReadCoordV (net_message, &position[0]); - r_funcs->particles->R_KnightSpikeEffect (position); + clp_funcs->KnightSpikeEffect (position); S_StartSound (-1, 0, cl_sfx_knighthit, &position[0], 1, 1); break; case TE_LavaSplash: MSG_ReadCoordV (net_message, &position[0]); - r_funcs->particles->R_LavaSplash (position); + clp_funcs->LavaSplash (position); break; case TE_Lightning1: CL_ParseBeam (net_message, cl_mod_bolt, time, ctx); @@ -453,11 +454,11 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, QuatSet (0.25, 0.40, 0.65, 1, dl->color); } - r_funcs->particles->R_LightningBloodEffect (position); + clp_funcs->LightningBloodEffect (position); break; case TE_Spike: MSG_ReadCoordV (net_message, &position[0]); - r_funcs->particles->R_SpikeEffect (position); + clp_funcs->SpikeEffect (position); { int i; sfx_t *sound; @@ -473,7 +474,7 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, break; case TE_SuperSpike: MSG_ReadCoordV (net_message, &position[0]); - r_funcs->particles->R_SuperSpikeEffect (position); + clp_funcs->SuperSpikeEffect (position); { int i; sfx_t *sound; @@ -489,17 +490,17 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx, break; case TE_TarExplosion: MSG_ReadCoordV (net_message, &position[0]); - r_funcs->particles->R_BlobExplosion (position); + clp_funcs->BlobExplosion (position); S_StartSound (-1, 0, cl_sfx_r_exp3, &position[0], 1, 1); break; case TE_Teleport: MSG_ReadCoordV (net_message, &position[0]); - r_funcs->particles->R_TeleportSplash (position); + clp_funcs->TeleportSplash (position); break; case TE_WizSpike: MSG_ReadCoordV (net_message, &position[0]); - r_funcs->particles->R_WizSpikeEffect (position); + clp_funcs->WizSpikeEffect (position); S_StartSound (-1, 0, cl_sfx_wizhit, &position[0], 1, 1); break; } @@ -659,9 +660,9 @@ CL_ParseParticleEffect (qmsg_t *net_message) color = MSG_ReadByte (net_message); if (count == 255) - r_funcs->particles->R_ParticleExplosion (org); + clp_funcs->ParticleExplosion (org); else - r_funcs->particles->R_RunParticleEffect (org, dir, color, count); + clp_funcs->RunParticleEffect (org, dir, color, count); } void diff --git a/libs/client/locs.c b/libs/client/locs.c index 4998694bf..ce5bd3ef4 100644 --- a/libs/client/locs.c +++ b/libs/client/locs.c @@ -55,7 +55,9 @@ #include "compat.h" #include "d_iface.h" //FIXME part_tex_smoke and part_tex_dot +#include "client/effects.h" #include "client/locs.h" +#include "client/particles.h" #define LOCATION_BLOCK 128 // 128 locations per block. @@ -307,14 +309,12 @@ locs_draw (vec4f_t simorg) dl->color[3] = 0.7; } trueloc = nearloc->loc; - r_funcs->particles->R_Particle_New (pt_smokecloud, part_tex_smoke, - trueloc, 2.0, + clp_funcs->Particle_New (pt_smokecloud, part_tex_smoke, 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, 12, - 0.7, 96, r_data->realtime + 5.0, + clp_funcs->Particle_NewRandom (pt_fallfade, 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 988c91432..5b0db4da3 100644 --- a/libs/video/renderer/gl/gl_dyn_part.c +++ b/libs/video/renderer/gl/gl_dyn_part.c @@ -66,124 +66,11 @@ static int pVAsize; static int *pVAindices; static varray_t2f_c4ub_v3f_t *particleVertexArray; -static mtstate_t mt; // private PRNG state - -inline static void -particle_new (ptype_t type, int texnum, vec4f_t pos, float scale, - vec4f_t vel, float live, int color, float alpha, 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 = 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]; - } -} - -/* - particle_new_random - - note that org_fuzz & vel_fuzz should be ints greater than 0 if you are - going to bother using this function. -*/ -inline static void -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; - 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, live, color, alpha, ramp); -} - -/* -inline static void -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; - - porg[0] = qfrandom (org_fuzz * 2) - org_fuzz + org[0]; - porg[1] = qfrandom (org_fuzz * 2) - org_fuzz + org[1]; - porg[2] = qfrandom (org_fuzz * 2) - org_fuzz + org[2]; - 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, 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) -{ - numparticles = 0; -} - void gl_R_InitParticles (void) { int i; - mtwist_seed (&mt, 0xdeadbeef); - if (r_maxparticles && r_init) { if (vaelements) { partUseVA = 0; @@ -225,1020 +112,6 @@ gl_R_InitParticles (void) } } - -void -gl_R_ReadPointFile_f (void) -{ - const char *name; - char *mapname; - int c; - QFile *f; - - mapname = strdup (r_worldentity.renderer.model->path); - if (!mapname) - Sys_Error ("Can't duplicate mapname!"); - QFS_StripExtension (mapname, mapname); - - name = va (0, "%s.pts", mapname); - free (mapname); - - f = QFS_FOpenFile (name); - if (!f) { - Sys_Printf ("couldn't open %s\n", name); - return; - } - - 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)); - int r = sscanf (buf, "%f %f %f\n", &org[0], &org[1], &org[2]); - if (r != 3) - break; - c++; - - if (numparticles >= r_maxparticles) { - Sys_MaskPrintf (SYS_dev, "Not enough free particles\n"); - break; - } else { - particle_new (pt_static, part_tex_dot, org, 1.5, zero, - 99999, (-c) & 15, 1.0, 0.0); - } - } - Qclose (f); - Sys_MaskPrintf (SYS_dev, "%i points read\n", c); -} - -static void -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, - 5.0, (mtwist_rand (&mt) & 7) + 8, - 0.5 + qfrandom (0.25), 0.0); -} - -static void -R_ParticleExplosion2_QF (vec4f_t org, int colorStart, int colorLength) -{ - unsigned int i, j = 512; - - if (numparticles >= r_maxparticles) - return; - else if (numparticles + j >= r_maxparticles) - j = r_maxparticles - numparticles; - - for (i = 0; i < j; i++) { - particle_new_random (pt_blob, part_tex_dot, org, 16, 2, 256, - 0.3, - colorStart + (i % colorLength), 1.0, 0.0); - } -} - -static void -R_BlobExplosion_QF (vec4f_t org) -{ - unsigned int i; - unsigned int j = 1024; - - if (numparticles >= r_maxparticles) - 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, 2, 256, - 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, - 1.0 + (mtwist_rand (&mt) & 7) * 0.05, - 150 + i % 6, 1.0, 0.0); - } -} - -static inline void -R_RunSparkEffect_QF (vec4f_t org, int count, int ofuzz) -{ - if (!r_particles->int_val) - return; - - vec4f_t zero = {}; - particle_new (pt_smokecloud, part_tex_smoke, org, ofuzz * 0.08, - zero, 9, 12 + (mtwist_rand (&mt) & 3), - 0.25 + qfrandom (0.125), 0.0); - - if (count > 0) { - int orgfuzz = ofuzz * 3 / 4; - if (orgfuzz < 1) - orgfuzz = 1; - - while (count--) { - int color = mtwist_rand (&mt) & 7; - - particle_new_random (pt_fallfadespark, part_tex_dot, org, orgfuzz, - 0.7, 96, 5.0, 0, 1.0, color); - } - } -} - -static inline void -R_BloodPuff_QF (vec4f_t org, int count) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org, int count) -{ - R_BloodPuff_QF (org, count); -} - -static void -R_GunshotEffect_QF (vec4f_t org, int count) -{ - int scale = 16; - - scale += count / 15; - R_RunSparkEffect_QF (org, count >> 1, scale); -} - -static void -R_LightningBloodEffect_QF (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - R_BloodPuff_QF (org, 50); - - 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); - - for (int count = 7; count-- > 0; ) { - particle_new_random (pt_fallfade, part_tex_spark, org, 12, 2.0, 128, - 5.0, 244 + (count % 3), 1.0, 0.0); - } -} - -static void -R_RunParticleEffect_QF (vec4f_t org, vec4f_t dir, int color, - int count) -{ - if (!r_particles->int_val) - return; - - float scale = pow (count, 0.23); - - for (int i = 0; i < count; i++) { - int rnd = mtwist_rand (&mt); - - // Note that ParseParticleEffect handles (dir * 15) - 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 (vec4f_t org) -{ - R_RunSparkEffect_QF (org, 5, 8); -} - -static void -R_SuperSpikeEffect_QF (vec4f_t org) -{ - R_RunSparkEffect_QF (org, 10, 8); -} - -static void -R_KnightSpikeEffect_QF (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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, - 5.0, 234, 1.0, 0.0); - } -} - -static void -R_WizSpikeEffect_QF (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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, - 5.0, 63, 1.0, 0.0); - } -} - -static void -R_LavaSplash_QF (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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); - } - } - } -} - -static void -R_RocketTrail_QF (vec4f_t start, vec4f_t end) -{ - if (numparticles >= r_maxparticles) - return; - - 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) { - float pscalenext = 1.5 + qfrandom (1.5); - float dist = (pscale + pscalenext) * 3.0; - float percent = len * origlen; - - 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; - pos += step; - pscale = pscalenext; - } -} - -static void -R_GrenadeTrail_QF (vec4f_t start, vec4f_t end) -{ - if (numparticles >= r_maxparticles) - return; - - 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) { - float pscalenext = 6.0 + qfrandom (7.0); - float dist = (pscale + pscalenext) * 2.0; - float percent = len * origlen; - - 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; - pos += step; - pscale = pscalenext; - } -} - -static void -R_BloodTrail_QF (vec4f_t start, vec4f_t end) -{ - if (numparticles >= r_maxparticles) - return; - - 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) { - 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; - - 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; - pos += step; - pscale = pscalenext; - } -} - -static void -R_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) -{ - if (numparticles >= r_maxparticles) - return; - - 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) { - 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; - - 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; - pos += step; - pscale = pscalenext; - } -} - -static void -R_WizTrail_QF (vec4f_t start, vec4f_t end) -{ - float dist = 3.0; - - if (numparticles >= r_maxparticles) - return; - - 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) { - static int tracercount; - float percent = len * origlen; - - 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; - pos += step; - } -} - -static void -R_FlameTrail_QF (vec4f_t start, vec4f_t end) -{ - float dist = 3.0; - - if (numparticles >= r_maxparticles) - return; - - 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) { - static int tracercount; - float percent = len * origlen; - - 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); - len += dist; - pos += step; - } -} - -static void -R_VoorTrail_QF (vec4f_t start, vec4f_t end) -{ - float dist = 3.0; - - if (numparticles >= r_maxparticles) - return; - - 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) { - float percent = len * origlen; - - 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); - len += dist; - pos += step; - } -} - -static void -R_GlowTrail_QF (vec4f_t start, vec4f_t end, int glow_color) -{ - float dist = 3.0; - - if (numparticles >= r_maxparticles) - return; - - 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) { - float percent = len * origlen; - - 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; - pos += step; - } -} - -static void -R_ParticleExplosion_EE (vec4f_t org) -{ -/* - R_NewExplosion (org); -*/ - if (numparticles >= r_maxparticles) - return; - particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8, - 5.0, mtwist_rand (&mt) & 255, - 0.5 + qfrandom (0.25), 0.0); -} - -static void -R_TeleportSplash_EE (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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); - } - } - } -} - -static void -R_RocketTrail_EE (vec4f_t start, vec4f_t end) -{ - if (numparticles >= r_maxparticles) - return; - - 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) { - float pscalenext = 1.5 + qfrandom (1.5); - float dist = (pscale + pscalenext) * 3.0; - float percent = len * origlen; - - 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; - pos += len * vec; - pscale = pscalenext; - } -} - -static void -R_GrenadeTrail_EE (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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) { - float pscalenext = 6.0 + qfrandom (7.0); - float dist = (pscale + pscalenext) * 2.0; - float percent = len * origlen; - - 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); - len += dist; - pos += len * vec; - pscale = pscalenext; - } -} - -static void -R_ParticleExplosion_ID (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org, vec4f_t dir, int color, - int count) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org, int count) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 73, count); -} - -static void -R_GunshotEffect_ID (vec4f_t org, int count) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 0, count); -} - -static void -R_LightningBloodEffect_ID (vec4f_t org) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 225, 50); -} - -static void -R_SpikeEffect_ID (vec4f_t org) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 0, 10); -} - -static void -R_SuperSpikeEffect_ID (vec4f_t org) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 0, 20); -} - -static void -R_KnightSpikeEffect_ID (vec4f_t org) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 226, 20); -} - -static void -R_WizSpikeEffect_ID (vec4f_t org) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 20, 30); -} - -static void -R_LavaSplash_ID (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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_TeleportSplash_ID (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_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; - - 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 * velocities[i][1]; - cp = cos (angle); - sp = sin (angle); -// Next 3 lines results aren't currently used, may be in future. --Despair -// angle = vr_data.realtime * avelocities[i][2]; -// sr = sin (angle); -// cr = cos (angle); - - 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 (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_fire, pos + roffs (6), zero, 2, - 0, (mtwist_rand (&mt) & 3)); - pos += vec; - } -} - -static void -R_GrenadeTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_fire, pos + roffs (6), zero, 2, - 0, (mtwist_rand (&mt) & 3) + 2); - pos += vec; - } -} - -static void -R_BloodTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_slowgrav, pos + roffs (6), zero, 2, - 67 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - -static void -R_SlightBloodTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_slowgrav, pos + roffs (6), zero, 2, - 67 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - -static void -R_WizTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, - 52 + ((tracercount & 4) << 1), 0); - tracercount++; - pos += vec; - } -} - -static void -R_FlameTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, - 230 + ((tracercount & 4) << 1), 0); - tracercount++; - pos += vec; - } -} - -static void -R_VoorTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos + roffs (16), zero, 0.3, - 9 * 16 + 8 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - void gl_R_DrawParticles (void) { @@ -1386,172 +259,6 @@ gl_R_DrawParticles (void) qfglDepthMask (GL_TRUE); } -static void -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, live, color, alpha, ramp); -} - -static void -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, live, - color, alpha, ramp); -} - -static vid_particle_funcs_t particles_QF = { - R_RocketTrail_QF, - R_GrenadeTrail_QF, - R_BloodTrail_QF, - R_SlightBloodTrail_QF, - R_WizTrail_QF, - R_FlameTrail_QF, - R_VoorTrail_QF, - R_GlowTrail_QF, - R_RunParticleEffect_QF, - R_BloodPuffEffect_QF, - R_GunshotEffect_QF, - R_LightningBloodEffect_QF, - R_SpikeEffect_QF, - R_KnightSpikeEffect_QF, - R_SuperSpikeEffect_QF, - R_WizSpikeEffect_QF, - R_BlobExplosion_QF, - R_ParticleExplosion_QF, - R_ParticleExplosion2_QF, - R_LavaSplash_QF, - R_TeleportSplash_QF, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -static vid_particle_funcs_t particles_ID = { - R_RocketTrail_ID, - R_GrenadeTrail_ID, - R_BloodTrail_ID, - R_SlightBloodTrail_ID, - R_WizTrail_ID, - R_FlameTrail_ID, - R_VoorTrail_ID, - R_GlowTrail_QF, - R_RunParticleEffect_ID, - R_BloodPuffEffect_ID, - R_GunshotEffect_ID, - R_LightningBloodEffect_ID, - R_SpikeEffect_ID, - R_KnightSpikeEffect_ID, - R_SuperSpikeEffect_ID, - R_WizSpikeEffect_ID, - R_BlobExplosion_ID, - R_ParticleExplosion_ID, - R_ParticleExplosion2_QF, - R_LavaSplash_ID, - R_TeleportSplash_ID, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -static vid_particle_funcs_t particles_QF_egg = { - R_RocketTrail_EE, - R_GrenadeTrail_EE, - R_BloodTrail_QF, - R_SlightBloodTrail_QF, - R_WizTrail_QF, - R_FlameTrail_QF, - R_VoorTrail_QF, - R_GlowTrail_QF, - R_RunParticleEffect_QF, - R_BloodPuffEffect_QF, - R_GunshotEffect_QF, - R_LightningBloodEffect_QF, - R_SpikeEffect_QF, - R_KnightSpikeEffect_QF, - R_SuperSpikeEffect_QF, - R_WizSpikeEffect_QF, - R_BlobExplosion_QF, - R_ParticleExplosion_EE, - R_ParticleExplosion2_QF, - R_LavaSplash_QF, - R_TeleportSplash_EE, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -static vid_particle_funcs_t particles_ID_egg = { - R_RocketTrail_EE, - R_GrenadeTrail_EE, - R_BloodTrail_ID, - R_SlightBloodTrail_ID, - R_WizTrail_ID, - R_FlameTrail_ID, - R_VoorTrail_ID, - R_GlowTrail_QF, - R_RunParticleEffect_ID, - R_BloodPuffEffect_ID, - R_GunshotEffect_ID, - R_LightningBloodEffect_ID, - R_SpikeEffect_ID, - R_KnightSpikeEffect_ID, - R_SuperSpikeEffect_ID, - R_WizSpikeEffect_ID, - R_BlobExplosion_ID, - R_ParticleExplosion_EE, - R_ParticleExplosion2_QF, - R_LavaSplash_ID, - R_TeleportSplash_EE, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -void -gl_r_easter_eggs_f (cvar_t *var) -{ - if (easter_eggs && !gl_feature_mach64) { - if (easter_eggs->int_val) { - if (r_particles_style->int_val) { - gl_vid_render_funcs.particles = &particles_QF_egg; - } else { - gl_vid_render_funcs.particles = &particles_ID_egg; - } - } else if (r_particles_style) { - if (r_particles_style->int_val) { - gl_vid_render_funcs.particles = &particles_QF; - } else { - gl_vid_render_funcs.particles = &particles_ID; - } - } - } -} - -void -gl_r_particles_style_f (cvar_t *var) -{ - gl_r_easter_eggs_f (easter_eggs); -} - -static void -R_ParticleFunctionInit (void) -{ - gl_r_particles_style_f (r_particles_style); - gl_r_easter_eggs_f (easter_eggs); -} - static void r_particles_nearclip_f (cvar_t *var) { @@ -1574,8 +281,6 @@ r_particles_max_f (cvar_t *var) void gl_R_Particles_Init_Cvars (void) { - easter_eggs = Cvar_Get ("easter_eggs", "0", CVAR_NONE, r_easter_eggs_f, - "Enables easter eggs."); r_particles = Cvar_Get ("r_particles", "1", CVAR_ARCHIVE, r_particles_f, "Toggles drawing of particles."); r_particles_max = Cvar_Get ("r_particles_max", "2048", CVAR_ARCHIVE, @@ -1586,8 +291,4 @@ gl_R_Particles_Init_Cvars (void) CVAR_ARCHIVE, r_particles_nearclip_f, "Distance of the particle near clipping " "plane from the player."); - r_particles_style = Cvar_Get ("r_particles_style", "1", CVAR_ARCHIVE, - r_particles_style_f, "Sets particle style. " - "0 for Id, 1 for QF."); - R_ParticleFunctionInit (); } diff --git a/libs/video/renderer/gl/gl_rmain.c b/libs/video/renderer/gl/gl_rmain.c index 429191157..cd5e406a1 100644 --- a/libs/video/renderer/gl/gl_rmain.c +++ b/libs/video/renderer/gl/gl_rmain.c @@ -895,5 +895,5 @@ gl_R_ClearState (void) r_worldentity.renderer.model = 0; R_ClearEfrags (); R_ClearDlights (); - gl_R_ClearParticles (); + R_ClearParticles (); } diff --git a/libs/video/renderer/gl/gl_rmisc.c b/libs/video/renderer/gl/gl_rmisc.c index 8a2005910..f035be9dd 100644 --- a/libs/video/renderer/gl/gl_rmisc.c +++ b/libs/video/renderer/gl/gl_rmisc.c @@ -146,8 +146,6 @@ gl_R_Init (void) Cmd_AddCommand ("timerefresh", gl_R_TimeRefresh_f, "Tests the current refresh rate for the current location"); Cmd_AddCommand ("envmap", R_Envmap_f, "No Description"); - Cmd_AddCommand ("pointfile", gl_R_ReadPointFile_f, - "Load a pointfile to determine map leaks"); Cmd_AddCommand ("loadsky", gl_R_LoadSky_f, "Load a skybox"); gl_Draw_Init (); @@ -203,7 +201,7 @@ gl_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models) r_viewleaf = NULL; R_MarkLeaves (); - gl_R_ClearParticles (); + R_ClearParticles (); GL_BuildLightmaps (models, num_models); diff --git a/libs/video/renderer/gl/namehack.h b/libs/video/renderer/gl/namehack.h index 84f48faa6..2f2b37ae4 100644 --- a/libs/video/renderer/gl/namehack.h +++ b/libs/video/renderer/gl/namehack.h @@ -34,7 +34,6 @@ #define R_AddTexture gl_R_AddTexture #define R_BlendLightmaps gl_R_BlendLightmaps #define R_CalcLightmaps gl_R_CalcLightmaps -#define R_ClearParticles gl_R_ClearParticles #define R_ClearState gl_R_ClearState #define R_ClearTextures gl_R_ClearTextures #define R_DrawAliasModel gl_R_DrawAliasModel @@ -88,7 +87,6 @@ #undef R_AddTexture #undef R_BlendLightmaps #undef R_CalcLightmaps -#undef R_ClearParticles #undef R_ClearState #undef R_ClearTextures #undef R_DrawAliasModel diff --git a/libs/video/renderer/glsl/glsl_main.c b/libs/video/renderer/glsl/glsl_main.c index 46b865913..1295ca7e4 100644 --- a/libs/video/renderer/glsl/glsl_main.c +++ b/libs/video/renderer/glsl/glsl_main.c @@ -229,8 +229,6 @@ glsl_R_RenderView (void) void glsl_R_Init (void) { - Cmd_AddCommand ("pointfile", glsl_R_ReadPointFile_f, - "Load a pointfile to determine map leaks."); Cmd_AddCommand ("timerefresh", glsl_R_TimeRefresh_f, "Test the current refresh rate for the current location."); R_Init_Cvars (); @@ -262,7 +260,7 @@ glsl_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models) R_MarkLeaves (); R_FreeAllEntities (); - glsl_R_ClearParticles (); + R_ClearParticles (); glsl_R_RegisterTextures (models, num_models); glsl_R_BuildLightmaps (models, num_models); glsl_R_BuildDisplayLists (models, num_models); @@ -279,7 +277,7 @@ glsl_R_ClearState (void) r_worldentity.renderer.model = 0; R_ClearEfrags (); R_ClearDlights (); - glsl_R_ClearParticles (); + R_ClearParticles (); } void diff --git a/libs/video/renderer/glsl/glsl_particles.c b/libs/video/renderer/glsl/glsl_particles.c index 9975f73f2..ebda3b447 100644 --- a/libs/video/renderer/glsl/glsl_particles.c +++ b/libs/video/renderer/glsl/glsl_particles.c @@ -133,117 +133,6 @@ static struct { {"fog", 1}, }; -static mtstate_t mt; // private PRNG state - -inline static void -particle_new (ptype_t type, int texnum, vec4f_t pos, float scale, - vec4f_t vel, float live, int color, float alpha, 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 = 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]; - } -} - -/* - particle_new_random - - note that org_fuzz & vel_fuzz should be ints greater than 0 if you are - going to bother using this function. -*/ -inline static void -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; - 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, live, color, alpha, ramp); -} - -/* -inline static void -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; - - porg[0] = qfrandom (org_fuzz * 2) - org_fuzz + org[0]; - porg[1] = qfrandom (org_fuzz * 2) - org_fuzz + org[1]; - porg[2] = qfrandom (org_fuzz * 2) - org_fuzz + org[2]; - 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, 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) -{ - numparticles = 0; -} - void glsl_R_InitParticles (void) { @@ -255,8 +144,6 @@ glsl_R_InitParticles (void) byte data[64][64][2]; tex_t *tex; - mtwist_seed (&mt, 0xdeadbeef); - qfeglEnable (GL_VERTEX_PROGRAM_POINT_SIZE); qfeglGetFloatv (GL_ALIASED_POINT_SIZE_RANGE, v); Sys_MaskPrintf (SYS_glsl, "point size: %g - %g\n", v[0], v[1]); @@ -329,1019 +216,6 @@ glsl_R_InitParticles (void) } } -void -glsl_R_ReadPointFile_f (void) -{ - const char *name; - char *mapname; - int c; - QFile *f; - - mapname = strdup (r_worldentity.renderer.model->path); - if (!mapname) - Sys_Error ("Can't duplicate mapname!"); - QFS_StripExtension (mapname, mapname); - - name = va (0, "%s.pts", mapname); - free (mapname); - - f = QFS_FOpenFile (name); - if (!f) { - Sys_Printf ("couldn't open %s\n", name); - return; - } - - 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)); - int r = sscanf (buf, "%f %f %f\n", &org[0], &org[1], &org[2]); - if (r != 3) - break; - c++; - - if (numparticles >= r_maxparticles) { - Sys_MaskPrintf (SYS_dev, "Not enough free particles\n"); - break; - } else { - particle_new (pt_static, part_tex_dot, org, 1.5, zero, - 99999, (-c) & 15, 1.0, 0.0); - } - } - Qclose (f); - Sys_MaskPrintf (SYS_dev, "%i points read\n", c); -} - -static void -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, - 5.0, (mtwist_rand (&mt) & 7) + 8, - 0.5 + qfrandom (0.25), 0.0); -} - -static void -R_ParticleExplosion2_QF (vec4f_t org, int colorStart, int colorLength) -{ - unsigned int i, j = 512; - - if (numparticles >= r_maxparticles) - return; - else if (numparticles + j >= r_maxparticles) - j = r_maxparticles - numparticles; - - for (i = 0; i < j; i++) { - particle_new_random (pt_blob, part_tex_dot, org, 16, 2, 256, - 0.3, - colorStart + (i % colorLength), 1.0, 0.0); - } -} - -static void -R_BlobExplosion_QF (vec4f_t org) -{ - unsigned int i; - unsigned int j = 1024; - - if (numparticles >= r_maxparticles) - 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, 2, 256, - 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, - 1.0 + (mtwist_rand (&mt) & 7) * 0.05, - 150 + i % 6, 1.0, 0.0); - } -} - -static inline void -R_RunSparkEffect_QF (vec4f_t org, int count, int ofuzz) -{ - if (!r_particles->int_val) - return; - - vec4f_t zero = {}; - particle_new (pt_smokecloud, part_tex_smoke, org, ofuzz * 0.08, - zero, 9, 12 + (mtwist_rand (&mt) & 3), - 0.25 + qfrandom (0.125), 0.0); - - if (count > 0) { - int orgfuzz = ofuzz * 3 / 4; - if (orgfuzz < 1) - orgfuzz = 1; - - while (count--) { - int color = mtwist_rand (&mt) & 7; - - particle_new_random (pt_fallfadespark, part_tex_dot, org, orgfuzz, - 0.7, 96, 5.0, 0, 1.0, color); - } - } -} - -static inline void -R_BloodPuff_QF (vec4f_t org, int count) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org, int count) -{ - R_BloodPuff_QF (org, count); -} - -static void -R_GunshotEffect_QF (vec4f_t org, int count) -{ - int scale = 16; - - scale += count / 15; - R_RunSparkEffect_QF (org, count >> 1, scale); -} - -static void -R_LightningBloodEffect_QF (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - R_BloodPuff_QF (org, 50); - - 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); - - for (int count = 7; count-- > 0; ) { - particle_new_random (pt_fallfade, part_tex_spark, org, 12, 2.0, 128, - 5.0, 244 + (count % 3), 1.0, 0.0); - } -} - -static void -R_RunParticleEffect_QF (vec4f_t org, vec4f_t dir, int color, - int count) -{ - if (!r_particles->int_val) - return; - - float scale = pow (count, 0.23); - - for (int i = 0; i < count; i++) { - int rnd = mtwist_rand (&mt); - - // Note that ParseParticleEffect handles (dir * 15) - 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 (vec4f_t org) -{ - R_RunSparkEffect_QF (org, 5, 8); -} - -static void -R_SuperSpikeEffect_QF (vec4f_t org) -{ - R_RunSparkEffect_QF (org, 10, 8); -} - -static void -R_KnightSpikeEffect_QF (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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, - 5.0, 234, 1.0, 0.0); - } -} - -static void -R_WizSpikeEffect_QF (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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, - 5.0, 63, 1.0, 0.0); - } -} - -static void -R_LavaSplash_QF (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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); - } - } - } -} - -static void -R_RocketTrail_QF (vec4f_t start, vec4f_t end) -{ - if (numparticles >= r_maxparticles) - return; - - 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) { - float pscalenext = 1.5 + qfrandom (1.5); - float dist = (pscale + pscalenext) * 3.0; - float percent = len * origlen; - - 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; - pos += step; - pscale = pscalenext; - } -} - -static void -R_GrenadeTrail_QF (vec4f_t start, vec4f_t end) -{ - if (numparticles >= r_maxparticles) - return; - - 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) { - float pscalenext = 6.0 + qfrandom (7.0); - float dist = (pscale + pscalenext) * 2.0; - float percent = len * origlen; - - 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; - pos += step; - pscale = pscalenext; - } -} - -static void -R_BloodTrail_QF (vec4f_t start, vec4f_t end) -{ - if (numparticles >= r_maxparticles) - return; - - 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) { - 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; - - 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; - pos += step; - pscale = pscalenext; - } -} - -static void -R_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) -{ - if (numparticles >= r_maxparticles) - return; - - 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) { - 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; - - 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; - pos += step; - pscale = pscalenext; - } -} - -static void -R_WizTrail_QF (vec4f_t start, vec4f_t end) -{ - float dist = 3.0; - - if (numparticles >= r_maxparticles) - return; - - 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) { - static int tracercount; - float percent = len * origlen; - - 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; - pos += step; - } -} - -static void -R_FlameTrail_QF (vec4f_t start, vec4f_t end) -{ - float dist = 3.0; - - if (numparticles >= r_maxparticles) - return; - - 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) { - static int tracercount; - float percent = len * origlen; - - 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); - len += dist; - pos += step; - } -} - -static void -R_VoorTrail_QF (vec4f_t start, vec4f_t end) -{ - float dist = 3.0; - - if (numparticles >= r_maxparticles) - return; - - 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) { - float percent = len * origlen; - - 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); - len += dist; - pos += step; - } -} - -static void -R_GlowTrail_QF (vec4f_t start, vec4f_t end, int glow_color) -{ - float dist = 3.0; - - if (numparticles >= r_maxparticles) - return; - - 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) { - float percent = len * origlen; - - 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; - pos += step; - } -} - -static void -R_ParticleExplosion_EE (vec4f_t org) -{ -/* - R_NewExplosion (org); -*/ - if (numparticles >= r_maxparticles) - return; - particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8, - 5.0, mtwist_rand (&mt) & 255, - 0.5 + qfrandom (0.25), 0.0); -} - -static void -R_TeleportSplash_EE (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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); - } - } - } -} - -static void -R_RocketTrail_EE (vec4f_t start, vec4f_t end) -{ - if (numparticles >= r_maxparticles) - return; - - 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) { - float pscalenext = 1.5 + qfrandom (1.5); - float dist = (pscale + pscalenext) * 3.0; - float percent = len * origlen; - - 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; - pos += len * vec; - pscale = pscalenext; - } -} - -static void -R_GrenadeTrail_EE (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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) { - float pscalenext = 6.0 + qfrandom (7.0); - float dist = (pscale + pscalenext) * 2.0; - float percent = len * origlen; - - 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); - len += dist; - pos += len * vec; - pscale = pscalenext; - } -} - -static void -R_ParticleExplosion_ID (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org, vec4f_t dir, int color, - int count) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org, int count) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 73, count); -} - -static void -R_GunshotEffect_ID (vec4f_t org, int count) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 0, count); -} - -static void -R_LightningBloodEffect_ID (vec4f_t org) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 225, 50); -} - -static void -R_SpikeEffect_ID (vec4f_t org) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 0, 10); -} - -static void -R_SuperSpikeEffect_ID (vec4f_t org) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 0, 20); -} - -static void -R_KnightSpikeEffect_ID (vec4f_t org) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 226, 20); -} - -static void -R_WizSpikeEffect_ID (vec4f_t org) -{ - vec4f_t zero = {}; - R_RunParticleEffect_ID (org, zero, 20, 30); -} - -static void -R_LavaSplash_ID (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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_TeleportSplash_ID (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_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; - - 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 * velocities[i][1]; - cp = cos (angle); - sp = sin (angle); -// Next 3 lines results aren't currently used, may be in future. --Despair -// angle = vr_data.realtime * avelocities[i][2]; -// sr = sin (angle); -// cr = cos (angle); - - 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 (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_fire, pos + roffs (6), zero, 2, - 0, (mtwist_rand (&mt) & 3)); - pos += vec; - } -} - -static void -R_GrenadeTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_fire, pos + roffs (6), zero, 2, - 0, (mtwist_rand (&mt) & 3) + 2); - pos += vec; - } -} - -static void -R_BloodTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_slowgrav, pos + roffs (6), zero, 2, - 67 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - -static void -R_SlightBloodTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_slowgrav, pos + roffs (6), zero, 2, - 67 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - -static void -R_WizTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, - 52 + ((tracercount & 4) << 1), 0); - tracercount++; - pos += vec; - } -} - -static void -R_FlameTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, - 230 + ((tracercount & 4) << 1), 0); - tracercount++; - pos += vec; - } -} - -static void -R_VoorTrail_ID (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos + roffs (16), zero, 0.3, - 9 * 16 + 8 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - static void draw_qf_particles (void) { @@ -1595,179 +469,13 @@ glsl_R_DrawParticles (void) { if (!r_particles->int_val || !numparticles) return; - if (r_particles_style->int_val) { + if (0/*FIXME r_particles_style->int_val*/) { draw_qf_particles (); } else { draw_id_particles (); } } -static void -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, live, color, alpha, ramp); -} - -static void -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, live, - color, alpha, ramp); -} - -static vid_particle_funcs_t particles_QF = { - R_RocketTrail_QF, - R_GrenadeTrail_QF, - R_BloodTrail_QF, - R_SlightBloodTrail_QF, - R_WizTrail_QF, - R_FlameTrail_QF, - R_VoorTrail_QF, - R_GlowTrail_QF, - R_RunParticleEffect_QF, - R_BloodPuffEffect_QF, - R_GunshotEffect_QF, - R_LightningBloodEffect_QF, - R_SpikeEffect_QF, - R_KnightSpikeEffect_QF, - R_SuperSpikeEffect_QF, - R_WizSpikeEffect_QF, - R_BlobExplosion_QF, - R_ParticleExplosion_QF, - R_ParticleExplosion2_QF, - R_LavaSplash_QF, - R_TeleportSplash_QF, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -static vid_particle_funcs_t particles_ID = { - R_RocketTrail_ID, - R_GrenadeTrail_ID, - R_BloodTrail_ID, - R_SlightBloodTrail_ID, - R_WizTrail_ID, - R_FlameTrail_ID, - R_VoorTrail_ID, - R_GlowTrail_QF, - R_RunParticleEffect_ID, - R_BloodPuffEffect_ID, - R_GunshotEffect_ID, - R_LightningBloodEffect_ID, - R_SpikeEffect_ID, - R_KnightSpikeEffect_ID, - R_SuperSpikeEffect_ID, - R_WizSpikeEffect_ID, - R_BlobExplosion_ID, - R_ParticleExplosion_ID, - R_ParticleExplosion2_QF, - R_LavaSplash_ID, - R_TeleportSplash_ID, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -static vid_particle_funcs_t particles_QF_egg = { - R_RocketTrail_EE, - R_GrenadeTrail_EE, - R_BloodTrail_QF, - R_SlightBloodTrail_QF, - R_WizTrail_QF, - R_FlameTrail_QF, - R_VoorTrail_QF, - R_GlowTrail_QF, - R_RunParticleEffect_QF, - R_BloodPuffEffect_QF, - R_GunshotEffect_QF, - R_LightningBloodEffect_QF, - R_SpikeEffect_QF, - R_KnightSpikeEffect_QF, - R_SuperSpikeEffect_QF, - R_WizSpikeEffect_QF, - R_BlobExplosion_QF, - R_ParticleExplosion_EE, - R_ParticleExplosion2_QF, - R_LavaSplash_QF, - R_TeleportSplash_EE, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -static vid_particle_funcs_t particles_ID_egg = { - R_RocketTrail_EE, - R_GrenadeTrail_EE, - R_BloodTrail_ID, - R_SlightBloodTrail_ID, - R_WizTrail_ID, - R_FlameTrail_ID, - R_VoorTrail_ID, - R_GlowTrail_QF, - R_RunParticleEffect_ID, - R_BloodPuffEffect_ID, - R_GunshotEffect_ID, - R_LightningBloodEffect_ID, - R_SpikeEffect_ID, - R_KnightSpikeEffect_ID, - R_SuperSpikeEffect_ID, - R_WizSpikeEffect_ID, - R_BlobExplosion_ID, - R_ParticleExplosion_EE, - R_ParticleExplosion2_QF, - R_LavaSplash_ID, - R_TeleportSplash_EE, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -void -glsl_r_easter_eggs_f (cvar_t *var) -{ - if (easter_eggs) { - if (easter_eggs->int_val) { - if (r_particles_style->int_val) { - glsl_vid_render_funcs.particles = &particles_QF_egg; - } else { - glsl_vid_render_funcs.particles = &particles_ID_egg; - } - } else if (r_particles_style) { - if (r_particles_style->int_val) { - glsl_vid_render_funcs.particles = &particles_QF; - } else { - glsl_vid_render_funcs.particles = &particles_ID; - } - } - } -} - -void -glsl_r_particles_style_f (cvar_t *var) -{ - glsl_r_easter_eggs_f (easter_eggs); -} - -static void -R_ParticleFunctionInit (void) -{ - glsl_r_particles_style_f (r_particles_style); - glsl_r_easter_eggs_f (easter_eggs); -} - static void r_particles_nearclip_f (cvar_t *var) { @@ -1790,8 +498,6 @@ r_particles_max_f (cvar_t *var) void glsl_R_Particles_Init_Cvars (void) { - easter_eggs = Cvar_Get ("easter_eggs", "0", CVAR_NONE, r_easter_eggs_f, - "Enables easter eggs."); r_particles = Cvar_Get ("r_particles", "1", CVAR_ARCHIVE, r_particles_f, "Toggles drawing of particles."); r_particles_max = Cvar_Get ("r_particles_max", "2048", CVAR_ARCHIVE, @@ -1802,8 +508,4 @@ glsl_R_Particles_Init_Cvars (void) CVAR_ARCHIVE, r_particles_nearclip_f, "Distance of the particle near clipping " "plane from the player."); - r_particles_style = Cvar_Get ("r_particles_style", "1", CVAR_ARCHIVE, - r_particles_style_f, "Sets particle style. " - "0 for Id, 1 for QF."); - R_ParticleFunctionInit (); } diff --git a/libs/video/renderer/glsl/namehack.h b/libs/video/renderer/glsl/namehack.h index 6a8377a9d..62e75dc87 100644 --- a/libs/video/renderer/glsl/namehack.h +++ b/libs/video/renderer/glsl/namehack.h @@ -35,7 +35,6 @@ #define R_BlendLightmaps glsl_R_BlendLightmaps #define R_BuildLightMap glsl_R_BuildLightMap #define R_CalcLightmaps glsl_R_CalcLightmaps -#define R_ClearParticles glsl_R_ClearParticles #define R_ClearState glsl_R_ClearState #define R_ClearTextures glsl_R_ClearTextures #define R_DrawAliasModel glsl_R_DrawAliasModel @@ -91,7 +90,6 @@ #undef R_BlendLightmaps #undef R_BuildLightMap #undef R_CalcLightmaps -#undef R_ClearParticles #undef R_ClearState #undef R_ClearTextures #undef R_DrawAliasModel diff --git a/libs/video/renderer/r_cvar.c b/libs/video/renderer/r_cvar.c index 72a537223..24a9b6234 100644 --- a/libs/video/renderer/r_cvar.c +++ b/libs/video/renderer/r_cvar.c @@ -41,8 +41,6 @@ #include "compat.h" #include "r_internal.h" -cvar_t *easter_eggs; - cvar_t *cl_crossx; cvar_t *cl_crossy; cvar_t *cl_verstring; @@ -80,7 +78,6 @@ cvar_t *r_novis; cvar_t *r_numedges; cvar_t *r_numsurfs; cvar_t *r_particles; -cvar_t *r_particles_style; cvar_t *r_particles_max; cvar_t *r_particles_nearclip; cvar_t *r_reportedgeout; diff --git a/libs/video/renderer/r_part.c b/libs/video/renderer/r_part.c index 5a610f9f3..b2c83fc02 100644 --- a/libs/video/renderer/r_part.c +++ b/libs/video/renderer/r_part.c @@ -77,60 +77,11 @@ R_MaxParticlesCheck (cvar_t *r_particles, cvar_t *r_particles_max) partparams = (partparm_t *) &particles[r_maxparticles]; partramps = (const int **) &partparams[r_maxparticles]; } - - vr_funcs->R_ClearParticles (); - - if (r_init) - vr_funcs->R_InitParticles (); + R_ClearParticles (); } -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, -}; - -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) +void +R_ClearParticles (void) { - if (type > pt_flame) { - Sys_Error ("R_ParticlePhysics: invalid particle 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]; + numparticles = 0; } diff --git a/libs/video/renderer/sw/sw_rmain.c b/libs/video/renderer/sw/sw_rmain.c index 93cc58493..d99259e4b 100644 --- a/libs/video/renderer/sw/sw_rmain.c +++ b/libs/video/renderer/sw/sw_rmain.c @@ -131,12 +131,9 @@ sw_R_Init (void) #endif R_InitTurb (); - R_InitParticles (); Cmd_AddCommand ("timerefresh", R_TimeRefresh_f, "Tests the current " "refresh rate for the current location"); - Cmd_AddCommand ("pointfile", R_ReadPointFile_f, "Load a pointfile to " - "determine map leaks"); Cmd_AddCommand ("loadsky", R_LoadSky_f, "Load a skybox"); Cvar_SetValue (r_maxedges, (float) NUMSTACKEDGES); diff --git a/libs/video/renderer/sw/sw_rpart.c b/libs/video/renderer/sw/sw_rpart.c index ede081f77..ceeda14a0 100644 --- a/libs/video/renderer/sw/sw_rpart.c +++ b/libs/video/renderer/sw/sw_rpart.c @@ -49,486 +49,6 @@ #include "compat.h" #include "r_internal.h" -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) -{ - mtwist_seed (&mt, 0xdeadbeef); -} - -void -R_ClearParticles (void) -{ - if (r_maxparticles) { - memset (particles, 0, r_maxparticles * sizeof (*particles)); - } -} - -void -R_ReadPointFile_f (void) -{ - QFile *f; - int c, r; - const char *name; - char *mapname; - vec4f_t zero = {}; - - mapname = strdup (r_worldentity.renderer.model->path); - if (!mapname) - Sys_Error ("Can't duplicate mapname!"); - QFS_StripExtension (mapname, mapname); - - name = va (0, "maps/%s.pts", mapname); - free (mapname); - - f = QFS_FOpenFile (name); - if (!f) { - Sys_Printf ("couldn't open %s\n", name); - return; - } - - Sys_Printf ("Reading %s...\n", name); - 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]); - if (r != 3) - break; - c++; - - //if (!free_particles) { - // Sys_Printf ("Not enough free particles\n"); - // break; - //} - add_particle (pt_static, org, zero, INFINITY, (-c) & 15, 0); - } - - Qclose (f); - Sys_Printf ("%i points read\n", c); -} - -static void -R_ParticleExplosion_QF (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org, int colorStart, int colorLength) -{ - int colorMod = 0; - - 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 (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org, vec4f_t dir, int color, int count) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org) -{ - 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 (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_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_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; - - 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 * velocities[i][1]; - cp = cos (angle); - sp = sin (angle); -// Next 3 lines results aren't currently used, may be in future. --Despair -// angle = vr_data.realtime * avelocities[i][2]; -// sr = sin (angle); -// cr = cos (angle); - - 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 (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_fire, pos + roffs (6), zero, 2, - 0, (mtwist_rand (&mt) & 3)); - pos += vec; - } -} - -static void -R_GrenadeTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_fire, pos + roffs (6), zero, 2, - 0, (mtwist_rand (&mt) & 3) + 2); - pos += vec; - } -} - -static void -R_BloodTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_slowgrav, pos + roffs (6), zero, 2, - 67 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - -static void -R_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_slowgrav, pos + roffs (6), zero, 2, - 67 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - -static void -R_WizTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, - 52 + ((tracercount & 4) << 1), 0); - tracercount++; - pos += vec; - } -} - -static void -R_FlameTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, - 230 + ((tracercount & 4) << 1), 0); - tracercount++; - pos += vec; - } -} - -static void -R_VoorTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos + roffs (16), zero, 0.3, - 9 * 16 + 8 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - void R_DrawParticles (void) { @@ -570,80 +90,6 @@ R_DrawParticles (void) numparticles = j; } -void -r_easter_eggs_f (cvar_t *var) -{ -} - -void -r_particles_style_f (cvar_t *var) -{ -} - -static void -R_Particle_New (ptype_t type, int texnum, vec4f_t pos, float scale, - vec4f_t vel, float live, int color, float alpha, float ramp) -{ - add_particle (type, pos, vel, live, color, ramp); -} - -static void -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; - vec4f_t pos, vel; - - rnd = mtwist_rand (&mt); - 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); - 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; - - add_particle (type, pos, vel, live, color, ramp); -} - -static vid_particle_funcs_t particles_QF = { - R_RocketTrail_QF, - R_GrenadeTrail_QF, - R_BloodTrail_QF, - R_SlightBloodTrail_QF, - R_WizTrail_QF, - R_FlameTrail_QF, - R_VoorTrail_QF, - 0,//R_GlowTrail_QF, - R_RunParticleEffect_QF, - R_BloodPuffEffect_QF, - R_GunshotEffect_QF, - R_LightningBloodEffect_QF, - R_SpikeEffect_QF, - R_KnightSpikeEffect_QF, - R_SuperSpikeEffect_QF, - R_WizSpikeEffect_QF, - R_BlobExplosion_QF, - R_ParticleExplosion_QF, - R_ParticleExplosion2_QF, - R_LavaSplash_QF, - R_TeleportSplash_QF, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -static void -R_ParticleFunctionInit (void) -{ - sw_vid_render_funcs.particles = &particles_QF; -} - static void r_particles_nearclip_f (cvar_t *var) { @@ -666,8 +112,6 @@ r_particles_max_f (cvar_t *var) void R_Particles_Init_Cvars (void) { - easter_eggs = Cvar_Get ("easter_eggs", "0", CVAR_NONE, r_easter_eggs_f, - "Enables easter eggs."); r_particles = Cvar_Get ("r_particles", "1", CVAR_ARCHIVE, r_particles_f, "Toggles drawing of particles."); r_particles_max = Cvar_Get ("r_particles_max", "2048", CVAR_ARCHIVE, @@ -678,8 +122,4 @@ R_Particles_Init_Cvars (void) CVAR_ARCHIVE, r_particles_nearclip_f, "Distance of the particle near clipping " "plane from the player."); - r_particles_style = Cvar_Get ("r_particles_style", "1", CVAR_ARCHIVE, - r_particles_style_f, "Sets particle style. " - "0 for Id, 1 for QF."); - R_ParticleFunctionInit (); } diff --git a/libs/video/renderer/sw32/namehack.h b/libs/video/renderer/sw32/namehack.h index 6642d2d54..b1cf44f01 100644 --- a/libs/video/renderer/sw32/namehack.h +++ b/libs/video/renderer/sw32/namehack.h @@ -65,7 +65,6 @@ #define R_Alias_clip_top sw32_R_Alias_clip_top #define R_IQMDrawModel sw32_R_IQMDrawModel #define R_BeginEdgeFrame sw32_R_BeginEdgeFrame -#define R_ClearParticles sw32_R_ClearParticles #define R_ClearState sw32_R_ClearState #define R_ClipEdge sw32_R_ClipEdge #define R_DrawParticles sw32_R_DrawParticles @@ -305,7 +304,6 @@ extern struct surf_s *sw32_surfaces; #undef R_Alias_clip_top #undef R_IQMDrawModel #undef R_BeginEdgeFrame -#undef R_ClearParticles #undef R_ClearState #undef R_ClipEdge #undef R_DrawParticles diff --git a/libs/video/renderer/sw32/sw32_rmain.c b/libs/video/renderer/sw32/sw32_rmain.c index 01a99be25..2dc129df9 100644 --- a/libs/video/renderer/sw32/sw32_rmain.c +++ b/libs/video/renderer/sw32/sw32_rmain.c @@ -151,12 +151,9 @@ sw32_R_Init (void) sw32_Draw_Init (); SCR_Init (); sw32_R_InitTurb (); - sw32_R_InitParticles (); Cmd_AddCommand ("timerefresh", sw32_R_TimeRefresh_f, "Tests the current " "refresh rate for the current location"); - Cmd_AddCommand ("pointfile", sw32_R_ReadPointFile_f, "Load a pointfile to " - "determine map leaks"); Cmd_AddCommand ("loadsky", sw32_R_LoadSky_f, "Load a skybox"); Cvar_SetValue (r_maxedges, (float) NUMSTACKEDGES); @@ -198,7 +195,7 @@ sw32_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models) r_viewleaf = NULL; R_MarkLeaves (); - sw32_R_ClearParticles (); + R_ClearParticles (); r_cnumsurfs = r_maxsurfs->int_val; @@ -875,5 +872,5 @@ sw32_R_ClearState (void) r_worldentity.renderer.model = 0; R_ClearEfrags (); R_ClearDlights (); - sw32_R_ClearParticles (); + R_ClearParticles (); } diff --git a/libs/video/renderer/sw32/sw32_rpart.c b/libs/video/renderer/sw32/sw32_rpart.c index 26a9255ed..4bef2bc2b 100644 --- a/libs/video/renderer/sw32/sw32_rpart.c +++ b/libs/video/renderer/sw32/sw32_rpart.c @@ -52,486 +52,6 @@ #include "compat.h" #include "r_internal.h" -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) -{ - mtwist_seed (&mt, 0xdeadbeef); -} - -void -sw32_R_ClearParticles (void) -{ - if (r_maxparticles) { - memset (particles, 0, r_maxparticles * sizeof (*particles)); - } -} - -void -sw32_R_ReadPointFile_f (void) -{ - QFile *f; - int c, r; - const char *name; - char *mapname; - vec4f_t zero = {}; - - mapname = strdup (r_worldentity.renderer.model->path); - if (!mapname) - Sys_Error ("Can't duplicate mapname!"); - QFS_StripExtension (mapname, mapname); - - name = va (0, "maps/%s.pts", mapname); - free (mapname); - - f = QFS_FOpenFile (name); - if (!f) { - Sys_Printf ("couldn't open %s\n", name); - return; - } - - Sys_Printf ("Reading %s...\n", name); - 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]); - if (r != 3) - break; - c++; - - //if (!free_particles) { - // Sys_Printf ("Not enough free particles\n"); - // break; - //} - add_particle (pt_static, org, zero, INFINITY, (-c) & 15, 0); - } - - Qclose (f); - Sys_Printf ("%i points read\n", c); -} - -static void -R_ParticleExplosion_QF (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org, int colorStart, int colorLength) -{ - int colorMod = 0; - - 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 (vec4f_t org) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org, vec4f_t dir, int color, int count) -{ - if (!r_particles->int_val) - return; - - 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 (vec4f_t org) -{ - 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 (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_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_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; - - 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 * velocities[i][1]; - cp = cos (angle); - sp = sin (angle); -// Next 3 lines results aren't currently used, may be in future. --Despair -// angle = vr_data.realtime * avelocities[i][2]; -// sr = sin (angle); -// cr = cos (angle); - - 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 (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_fire, pos + roffs (6), zero, 2, - 0, (mtwist_rand (&mt) & 3)); - pos += vec; - } -} - -static void -R_GrenadeTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_fire, pos + roffs (6), zero, 2, - 0, (mtwist_rand (&mt) & 3) + 2); - pos += vec; - } -} - -static void -R_BloodTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_slowgrav, pos + roffs (6), zero, 2, - 67 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - -static void -R_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_slowgrav, pos + roffs (6), zero, 2, - 67 + (mtwist_rand (&mt) & 3), 0); - pos += vec; - } -} - -static void -R_WizTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, - 52 + ((tracercount & 4) << 1), 0); - tracercount++; - pos += vec; - } -} - -static void -R_FlameTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - add_particle (pt_static, pos, 30 * tracer_vel (tracercount, vec), 0.5, - 230 + ((tracercount & 4) << 1), 0); - tracercount++; - pos += vec; - } -} - -static void -R_VoorTrail_QF (vec4f_t start, vec4f_t end) -{ - if (!r_particles->int_val) - return; - - 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; - 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) { @@ -573,81 +93,6 @@ sw32_R_DrawParticles (void) numparticles = j; } -void -sw32_r_easter_eggs_f (cvar_t *var) -{ -} - -void -sw32_r_particles_style_f (cvar_t *var) -{ -} - -static void -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) -{ - add_particle (type, pos, vel, live, color, ramp); -} - -static void -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; - vec4f_t pos, vel; - - rnd = mtwist_rand (&mt); - 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); - 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; - - add_particle (type, pos, vel, live, color, ramp); -} - -static vid_particle_funcs_t particles_QF = { - R_RocketTrail_QF, - R_GrenadeTrail_QF, - R_BloodTrail_QF, - R_SlightBloodTrail_QF, - R_WizTrail_QF, - R_FlameTrail_QF, - R_VoorTrail_QF, - 0,//R_GlowTrail_QF, - R_RunParticleEffect_QF, - R_BloodPuffEffect_QF, - R_GunshotEffect_QF, - R_LightningBloodEffect_QF, - R_SpikeEffect_QF, - R_KnightSpikeEffect_QF, - R_SuperSpikeEffect_QF, - R_WizSpikeEffect_QF, - R_BlobExplosion_QF, - R_ParticleExplosion_QF, - R_ParticleExplosion2_QF, - R_LavaSplash_QF, - R_TeleportSplash_QF, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -static void -R_ParticleFunctionInit (void) -{ - sw32_vid_render_funcs.particles = &particles_QF; -} - static void r_particles_nearclip_f (cvar_t *var) { @@ -670,8 +115,6 @@ r_particles_max_f (cvar_t *var) void sw32_R_Particles_Init_Cvars (void) { - easter_eggs = Cvar_Get ("easter_eggs", "0", CVAR_NONE, r_easter_eggs_f, - "Enables easter eggs."); r_particles = Cvar_Get ("r_particles", "1", CVAR_ARCHIVE, r_particles_f, "Toggles drawing of particles."); r_particles_max = Cvar_Get ("r_particles_max", "2048", CVAR_ARCHIVE, @@ -682,8 +125,4 @@ sw32_R_Particles_Init_Cvars (void) CVAR_ARCHIVE, r_particles_nearclip_f, "Distance of the particle near clipping " "plane from the player."); - r_particles_style = Cvar_Get ("r_particles_style", "1", CVAR_ARCHIVE, - r_particles_style_f, "Sets particle style. " - "0 for Id, 1 for QF."); - R_ParticleFunctionInit (); } diff --git a/libs/video/renderer/vid_render_gl.c b/libs/video/renderer/vid_render_gl.c index 850d13beb..e3b1d6597 100644 --- a/libs/video/renderer/vid_render_gl.c +++ b/libs/video/renderer/vid_render_gl.c @@ -155,12 +155,7 @@ vid_render_funcs_t gl_vid_render_funcs = { R_MaxDlightsCheck, R_DecayLights, gl_R_ViewChanged, - gl_R_ClearParticles, - gl_R_InitParticles, gl_SCR_ScreenShot_f, - gl_r_easter_eggs_f, - gl_r_particles_style_f, - 0, &model_funcs }; diff --git a/libs/video/renderer/vid_render_glsl.c b/libs/video/renderer/vid_render_glsl.c index a4ad536f4..836f2f6ed 100644 --- a/libs/video/renderer/vid_render_glsl.c +++ b/libs/video/renderer/vid_render_glsl.c @@ -154,12 +154,7 @@ vid_render_funcs_t glsl_vid_render_funcs = { R_MaxDlightsCheck, R_DecayLights, glsl_R_ViewChanged, - glsl_R_ClearParticles, - glsl_R_InitParticles, glsl_SCR_ScreenShot_f, - glsl_r_easter_eggs_f, - glsl_r_particles_style_f, - 0, &model_funcs }; diff --git a/libs/video/renderer/vid_render_sw.c b/libs/video/renderer/vid_render_sw.c index cc0186750..f888a979d 100644 --- a/libs/video/renderer/vid_render_sw.c +++ b/libs/video/renderer/vid_render_sw.c @@ -151,12 +151,7 @@ vid_render_funcs_t sw_vid_render_funcs = { R_MaxDlightsCheck, R_DecayLights, R_ViewChanged, - R_ClearParticles, - R_InitParticles, SCR_ScreenShot_f, - r_easter_eggs_f, - r_particles_style_f, - 0, &model_funcs }; diff --git a/libs/video/renderer/vid_render_sw32.c b/libs/video/renderer/vid_render_sw32.c index 3a3638c1a..b9a0acac7 100644 --- a/libs/video/renderer/vid_render_sw32.c +++ b/libs/video/renderer/vid_render_sw32.c @@ -156,12 +156,7 @@ vid_render_funcs_t sw32_vid_render_funcs = { R_MaxDlightsCheck, R_DecayLights, sw32_R_ViewChanged, - sw32_R_ClearParticles, - sw32_R_InitParticles, sw32_SCR_ScreenShot_f, - sw32_r_easter_eggs_f, - sw32_r_particles_style_f, - 0, &model_funcs }; diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index 912a2c58c..cc7904d39 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -246,7 +246,7 @@ vulkan_R_ClearState (void) r_worldentity.renderer.model = 0; R_ClearEfrags (); R_ClearDlights (); - Vulkan_ClearParticles (vulkan_ctx); + R_ClearParticles (); } static void @@ -392,18 +392,6 @@ vulkan_R_ViewChanged (void) Vulkan_CalcProjectionMatrices (vulkan_ctx); } -static void -vulkan_R_ClearParticles (void) -{ - Vulkan_ClearParticles (vulkan_ctx); -} - -static void -vulkan_R_InitParticles (void) -{ - Vulkan_InitParticles (vulkan_ctx); -} - static int is_bgr (VkFormat format) { @@ -455,18 +443,6 @@ vulkan_SCR_ScreenShot_f (void) vulkan_ctx->capture_callback = capture_screenshot; } -static void -vulkan_r_easter_eggs_f (struct cvar_s *var) -{ - Vulkan_r_easter_eggs_f (var, vulkan_ctx); -} - -static void -vulkan_r_particles_style_f (struct cvar_s *var) -{ - Vulkan_r_particles_style_f (var, vulkan_ctx); -} - static void vulkan_Mod_LoadLighting (model_t *mod, bsp_t *bsp) { @@ -700,12 +676,7 @@ vid_render_funcs_t vulkan_vid_render_funcs = { R_MaxDlightsCheck, R_DecayLights, vulkan_R_ViewChanged, - vulkan_R_ClearParticles, - vulkan_R_InitParticles, vulkan_SCR_ScreenShot_f, - vulkan_r_easter_eggs_f, - vulkan_r_particles_style_f, - 0, &model_funcs }; diff --git a/libs/video/renderer/vulkan/vulkan_main.c b/libs/video/renderer/vulkan/vulkan_main.c index 62775419e..06a99a046 100644 --- a/libs/video/renderer/vulkan/vulkan_main.c +++ b/libs/video/renderer/vulkan/vulkan_main.c @@ -198,7 +198,7 @@ Vulkan_NewMap (model_t *worldmodel, struct model_s **models, int num_models, R_MarkLeaves (); R_FreeAllEntities (); - Vulkan_ClearParticles (ctx); + R_ClearParticles (); Vulkan_RegisterTextures (models, num_models, ctx); //Vulkan_BuildLightmaps (models, num_models, ctx); Vulkan_BuildDisplayLists (models, num_models, ctx); diff --git a/libs/video/renderer/vulkan/vulkan_particles.c b/libs/video/renderer/vulkan/vulkan_particles.c index 8c6679ba2..6eb8e74ba 100644 --- a/libs/video/renderer/vulkan/vulkan_particles.c +++ b/libs/video/renderer/vulkan/vulkan_particles.c @@ -56,203 +56,6 @@ static const char * __attribute__((used)) particle_pass_names[] = { "draw", }; -void -Vulkan_ClearParticles (vulkan_ctx_t *ctx) -{ -} - -void -Vulkan_InitParticles (vulkan_ctx_t *ctx) -{ -} - -static void -R_RocketTrail_QF (vec4f_t start, vec4f_t end) -{ -} - -static void -R_GrenadeTrail_QF (vec4f_t start, vec4f_t end) -{ -} - -static void -R_BloodTrail_QF (vec4f_t start, vec4f_t end) -{ -} - -static void -R_SlightBloodTrail_QF (vec4f_t start, vec4f_t end) -{ -} - -static void -R_WizTrail_QF (vec4f_t start, vec4f_t end) -{ -} - -static void -R_FlameTrail_QF (vec4f_t start, vec4f_t end) -{ -} - -static void -R_VoorTrail_QF (vec4f_t start, vec4f_t end) -{ -} - -static void -R_GlowTrail_QF (vec4f_t start, vec4f_t end, int glow_color) -{ -} - -static void -R_RunParticleEffect_QF (vec4f_t org, vec4f_t dir, int color, - int count) -{ -} - -static void -R_BloodPuffEffect_QF (vec4f_t org, int count) -{ -} - -static void -R_GunshotEffect_QF (vec4f_t org, int count) -{ -} - -static void -R_LightningBloodEffect_QF (vec4f_t org) -{ -} - -static void -R_SpikeEffect_QF (vec4f_t org) -{ -} - -static void -R_KnightSpikeEffect_QF (vec4f_t org) -{ -} - -static void -R_SuperSpikeEffect_QF (vec4f_t org) -{ -} - -static void -R_WizSpikeEffect_QF (vec4f_t org) -{ -} - -static void -R_BlobExplosion_QF (vec4f_t org) -{ -} - -static void -R_ParticleExplosion_QF (vec4f_t org) -{ -} - -static void -R_ParticleExplosion2_QF (vec4f_t org, int colorStart, int colorLength) -{ -} - -static void -R_LavaSplash_QF (vec4f_t org) -{ -} - -static void -R_TeleportSplash_QF (vec4f_t org) -{ -} - -static void -R_DarkFieldParticles_ID (vec4f_t org) -{ -} - -static void -R_EntityParticles_ID (vec4f_t org) -{ -} - -static 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) -{ -} - -static 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) -{ -} - -static vid_particle_funcs_t vulkan_particles_QF = { - R_RocketTrail_QF, - R_GrenadeTrail_QF, - R_BloodTrail_QF, - R_SlightBloodTrail_QF, - R_WizTrail_QF, - R_FlameTrail_QF, - R_VoorTrail_QF, - R_GlowTrail_QF, - R_RunParticleEffect_QF, - R_BloodPuffEffect_QF, - R_GunshotEffect_QF, - R_LightningBloodEffect_QF, - R_SpikeEffect_QF, - R_KnightSpikeEffect_QF, - R_SuperSpikeEffect_QF, - R_WizSpikeEffect_QF, - R_BlobExplosion_QF, - R_ParticleExplosion_QF, - R_ParticleExplosion2_QF, - R_LavaSplash_QF, - R_TeleportSplash_QF, - R_DarkFieldParticles_ID, - R_EntityParticles_ID, - R_Particle_New, - R_Particle_NewRandom, -}; - -void -Vulkan_r_easter_eggs_f (cvar_t *var, vulkan_ctx_t *ctx) -{ - if (!easter_eggs || !r_particles_style) { - return; - } - if (easter_eggs->int_val) { - if (r_particles_style->int_val) { - //vulkan_vid_render_funcs.particles = &vulkan_particles_QF_egg; - } else { - //vulkan_vid_render_funcs.particles = &vulkan_particles_ID_egg; - } - } else { - if (r_particles_style->int_val) { - //vulkan_vid_render_funcs.particles = &vulkan_particles_QF; - } else { - //vulkan_vid_render_funcs.particles = &vulkan_particles_ID; - } - } - vulkan_vid_render_funcs.particles = &vulkan_particles_QF; -} - -void -Vulkan_r_particles_style_f (cvar_t *var, vulkan_ctx_t *ctx) -{ - Vulkan_r_easter_eggs_f (var, ctx); -} - void Vulkan_DrawParticles (vulkan_ctx_t *ctx) { @@ -261,8 +64,6 @@ Vulkan_DrawParticles (vulkan_ctx_t *ctx) void Vulkan_Particles_Init (vulkan_ctx_t *ctx) { - vulkan_vid_render_funcs.particles = &vulkan_particles_QF; - qfv_device_t *device = ctx->device; qfvPushDebug (ctx, "particles init"); diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index 2548a2518..d7b474171 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -52,6 +52,7 @@ #include "compat.h" #include "sbar.h" +#include "client/particles.h" #include "client/temp_entities.h" #include "nq/include/chase.h" @@ -597,6 +598,7 @@ CL_Init (cbuf_t *cbuf) Sbar_Init (); CL_Input_Init (cbuf); + CL_Particles_Init (); CL_TEnts_Init (); CL_ClearState (); diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index 26c7f87d5..a5b462735 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -95,6 +95,7 @@ #include "compat.h" #include "sbar.h" +#include "client/particles.h" #include "client/temp_entities.h" #include "client/view.h" @@ -1206,6 +1207,7 @@ CL_Init (void) CL_Input_Init (); CL_Ents_Init (); + CL_Particles_Init (); CL_TEnts_Init (); CL_ClearState (); Pmove_Init ();