Convert particle physics to a scripted system.

The script format is the same as the console command-line, so no new
format :). The scripts are compiled to byte code and cached. They are
referenced by name (eg, "pt_fire"), though the names are likely to change.
It seems to work quite well and should prove to be a good basis for
scripting particle effects in general.
This commit is contained in:
Bill Currie 2014-01-31 10:40:44 +09:00
parent 0057970e3c
commit bcb1049f88
18 changed files with 649 additions and 341 deletions

View file

@ -36,6 +36,7 @@
struct plitem_s;
struct cvar_s;
struct skin_s;
struct particle_s;
/*
All video plugins must export these functions
@ -70,13 +71,13 @@ typedef struct vid_particle_funcs_s {
void (*R_DarkFieldParticles) (struct entity_s *ent);
void (*R_EntityParticles) (struct entity_s *ent);
void (*R_Particle_New) (ptype_t type, int texnum, const vec3_t org,
void (*R_Particle_New) (const char *type, int texnum, const vec3_t org,
float scale, const vec3_t vel, float die,
int color, float alpha, float ramp);
void (*R_Particle_NewRandom) (ptype_t type, int texnum, const vec3_t org,
int org_fuzz, float scale, int vel_fuzz,
float die, int color, float alpha,
float ramp);
void (*R_Particle_NewRandom) (const char *type, int texnum,
const vec3_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 {
@ -160,6 +161,10 @@ typedef struct vid_render_funcs_s {
void (*R_DecayLights) (double frametime);
void (*R_ViewChanged) (float aspect);
qboolean (*R_CompileParticlePhysics) (const char *name, const char *code);
qboolean (*R_AddParticlePhysicsFunction)
(const char *name, qboolean (*func) (struct particle_s *, void *),
void *data);
void (*R_ClearParticles) (void);
void (*R_InitParticles) (void);
void (*SCR_ScreenShot_f) (void);

View file

@ -33,25 +33,6 @@
#include "QF/qdefs.h" // FIXME
#include "QF/vid.h"
typedef enum {
pt_static,
pt_grav,
pt_slowgrav,
pt_fire,
pt_explode,
pt_explode2,
pt_blob,
pt_blob2,
pt_smoke,
pt_smokecloud,
pt_bloodcloud,
pt_fadespark,
pt_fadespark2,
pt_fallfade,
pt_fallfadespark,
pt_flame
} ptype_t;
extern struct vid_render_funcs_s *r_funcs;
extern struct vid_render_data_s *r_data;

View file

@ -63,9 +63,16 @@ typedef enum {
} ptextype_t;
typedef struct particle_s particle_t;
typedef void (*pt_phys_func)(particle_t *);
pt_phys_func R_ParticlePhysics (ptype_t type);
void R_LoadParticles (void);
qboolean R_CompileParticlePhysics (const char *name, const char *code);
void R_RunParticlePhysics (particle_t *part);
const union pt_phys_op_s *R_ParticlePhysics (const char *type);
qboolean R_AddParticlePhysicsFunction (const char *name,
qboolean (*func) (struct particle_s *,
void *),
void *data);
extern const char particle_types[];
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
struct particle_s
@ -78,10 +85,9 @@ struct particle_s
float scale;
// drivers never touch the following fields
vec3_t vel;
ptype_t type;
float die;
float ramp;
pt_phys_func phys;
const union pt_phys_op_s *physics;
particle_t *next;
};

View file

@ -49,10 +49,10 @@ void R_PushDlights (const vec3_t entorigin);
struct cvar_s;
void R_MaxDlightsCheck (struct cvar_s *var);
void R_Particles_Init_Cvars (void);
void R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale,
const vec3_t vel, float die, int color, float alpha,
float ramp);
void R_Particle_NewRandom (ptype_t type, int texnum, const vec3_t org,
void R_Particle_New (const char *type, int texnum, const vec3_t org,
float scale, const vec3_t vel, float die, int color,
float alpha, float ramp);
void R_Particle_NewRandom (const char *type, int texnum, const vec3_t org,
int org_fuzz, float scale, int vel_fuzz, float die,
int color, float alpha, float ramp);
void R_InitBubble (void);

View file

@ -10,9 +10,17 @@ plugin_ldflags= @plugin_ldflags@ -avoid-version -module -rpath $(plugindir)
plugin_libadd= @plugin_libadd@
EXEEXT=
particles_src= particles.part
particles_gen= particles.pc
SUFFICES=.part .pc
.part.pc:
sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' $< > $@
#lib_LTLIBRARIES= @VID_REND_TARGETS@
plugin_LTLIBRARIES= @vid_render_plugins@
noinst_LTLIBRARIES= libQFrenderer.la @vid_render_static_plugins@
BUILT_SOURCES= $(particles_gen)
EXTRA_LTLIBRARIES= \
vid_render_sw.la vid_render_sw32.la \
@ -63,3 +71,6 @@ vid_render_sw32_la_LDFLAGS= $(plugin_ldflags)
vid_render_sw32_la_LIBADD= $(sw32_libs)
vid_render_sw32_la_DEPENDENCIES=$(sw32_libs)
vid_render_sw32_la_SOURCES= $(common_sources) vid_render_sw32.c
EXTRA_DIST = $(particles_src)
CLEANFILES= *.pc

View file

@ -70,7 +70,7 @@ static varray_t2f_c4ub_v3f_t *particleVertexArray;
static mtstate_t mt; // private PRNG state
inline static void
particle_new (ptype_t type, int texnum, const vec3_t org, float scale,
particle_new (const char *type, int texnum, const vec3_t org, float scale,
const vec3_t vel, float die, int color, float alpha, float ramp)
{
particle_t *part;
@ -91,10 +91,9 @@ particle_new (ptype_t type, int texnum, const vec3_t org, float scale,
part->scale = scale;
part->alpha = alpha;
VectorCopy (vel, part->vel);
part->type = type;
part->die = die;
part->ramp = ramp;
part->phys = R_ParticlePhysics (type);
part->physics = R_ParticlePhysics (type);
}
/*
@ -104,7 +103,8 @@ particle_new (ptype_t type, int texnum, const vec3_t org, float scale,
going to bother using this function.
*/
inline static void
particle_new_random (ptype_t type, int texnum, const vec3_t org, int org_fuzz,
particle_new_random (const char *type, int texnum,
const vec3_t org, int org_fuzz,
float scale, int vel_fuzz, float die, int color,
float alpha, float ramp)
{
@ -153,6 +153,8 @@ gl_R_InitParticles (void)
{
int i;
R_LoadParticles ();
mtwist_seed (&mt, 0xdeadbeef);
if (r_maxparticles && r_init) {
@ -234,7 +236,7 @@ gl_R_ReadPointFile_f (void)
Sys_MaskPrintf (SYS_DEV, "Not enough free particles\n");
break;
} else {
particle_new (pt_static, part_tex_dot, org, 1.5, vec3_origin,
particle_new ("pt_static", part_tex_dot, org, 1.5, vec3_origin,
99999, (-c) & 15, 1.0, 0.0);
}
}
@ -248,7 +250,7 @@ R_ParticleExplosion_QF (const vec3_t org)
// R_NewExplosion (org);
if (numparticles >= r_maxparticles)
return;
particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8,
particle_new_random ("pt_smokecloud", part_tex_smoke, org, 4, 30, 8,
vr_data.realtime + 5.0, (mtwist_rand (&mt) & 7) + 8,
0.5 + qfrandom (0.25), 0.0);
}
@ -264,7 +266,7 @@ R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength)
j = r_maxparticles - numparticles;
for (i = 0; i < j; i++) {
particle_new_random (pt_blob, part_tex_dot, org, 16, 2, 256,
particle_new_random ("pt_blob", part_tex_dot, org, 16, 2, 256,
vr_data.realtime + 0.3,
colorStart + (i % colorLength), 1.0, 0.0);
}
@ -282,12 +284,12 @@ R_BlobExplosion_QF (const vec3_t org)
j = r_maxparticles - numparticles;
for (i = 0; i < j >> 1; i++) {
particle_new_random (pt_blob, part_tex_dot, org, 12, 2, 256,
particle_new_random ("pt_blob", part_tex_dot, org, 12, 2, 256,
vr_data.realtime + 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,
particle_new_random ("pt_blob2", part_tex_dot, org, 12, 2, 256,
vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 7) * 0.05,
150 + i % 6, 1.0, 0.0);
}
@ -298,7 +300,7 @@ R_RunSparkEffect_QF (const vec3_t org, int count, int ofuzz)
{
if (numparticles >= r_maxparticles)
return;
particle_new (pt_smokecloud, part_tex_smoke, org, ofuzz * 0.08,
particle_new ("pt_smokecloud", part_tex_smoke, org, ofuzz * 0.08,
vec3_origin, vr_data.realtime + 9, 12 + (mtwist_rand (&mt) & 3),
0.25 + qfrandom (0.125), 0.0);
@ -312,7 +314,7 @@ R_RunSparkEffect_QF (const vec3_t org, int count, int ofuzz)
while (count--) {
int color = mtwist_rand (&mt) & 7;
particle_new_random (pt_fallfadespark, part_tex_dot, org, orgfuzz,
particle_new_random ("pt_fallfadespark", part_tex_dot, org, orgfuzz,
0.7, 96, vr_data.realtime + 5.0, ramp1[color],
1.0, color);
}
@ -325,7 +327,7 @@ R_BloodPuff_QF (const vec3_t org, int count)
if (numparticles >= r_maxparticles)
return;
particle_new (pt_bloodcloud, part_tex_smoke, org, count / 5, vec3_origin,
particle_new ("pt_bloodcloud", part_tex_smoke, org, count / 5, vec3_origin,
vr_data.realtime + 99.0, 70 + (mtwist_rand (&mt) & 3), 0.5, 0.0);
}
@ -353,14 +355,14 @@ R_LightningBloodEffect_QF (const vec3_t org)
if (numparticles >= r_maxparticles)
return;
particle_new (pt_smokecloud, part_tex_smoke, org, 3.0, vec3_origin,
particle_new ("pt_smokecloud", part_tex_smoke, org, 3.0, vec3_origin,
vr_data.realtime + 9.0, 12 + (mtwist_rand (&mt) & 3),
0.25 + qfrandom (0.125), 0.0);
if (numparticles + count >= r_maxparticles)
count = r_maxparticles - numparticles;
while (count--)
particle_new_random (pt_fallfade, part_tex_spark, org, 12, 2.0, 128,
particle_new_random ("pt_fallfade", part_tex_spark, org, 12, 2.0, 128,
vr_data.realtime + 5.0, 244 + (count % 3), 1.0,
0.0);
}
@ -388,7 +390,7 @@ R_RunParticleEffect_QF (const vec3_t org, const vec3_t dir, int color,
porg[1] = org[1] + scale * (((rnd >> 7) & 15) - 7.5);
porg[2] = org[2] + scale * (((rnd >> 11) & 15) - 7.5);
// Note that ParseParticleEffect handles (dir * 15)
particle_new (pt_grav, part_tex_dot, porg, 1.5, dir,
particle_new ("pt_grav", part_tex_dot, porg, 1.5, dir,
vr_data.realtime + 0.1 * (i % 5),
(color & ~7) + (rnd & 7), 1.0, 0.0);
}
@ -413,13 +415,13 @@ R_KnightSpikeEffect_QF (const vec3_t org)
if (numparticles >= r_maxparticles)
return;
particle_new (pt_smokecloud, part_tex_smoke, org, 1.0, vec3_origin,
particle_new ("pt_smokecloud", part_tex_smoke, org, 1.0, vec3_origin,
vr_data.realtime + 9.0, 234, 0.25 + qfrandom (0.125), 0.0);
if (numparticles + count >= r_maxparticles)
count = r_maxparticles - numparticles;
while (count--)
particle_new_random (pt_fallfade, part_tex_dot, org, 6, 0.7, 96,
particle_new_random ("pt_fallfade", part_tex_dot, org, 6, 0.7, 96,
vr_data.realtime + 5.0, 234, 1.0, 0.0);
}
@ -430,13 +432,13 @@ R_WizSpikeEffect_QF (const vec3_t org)
if (numparticles >= r_maxparticles)
return;
particle_new (pt_smokecloud, part_tex_smoke, org, 2.0, vec3_origin,
particle_new ("pt_smokecloud", part_tex_smoke, org, 2.0, vec3_origin,
vr_data.realtime + 9.0, 63, 0.25 + qfrandom (0.125), 0.0);
if (numparticles + count >= r_maxparticles)
count = r_maxparticles - numparticles;
while (count--)
particle_new_random (pt_fallfade, part_tex_dot, org, 12, 0.7, 96,
particle_new_random ("pt_fallfade", part_tex_dot, org, 12, 0.7, 96,
vr_data.realtime + 5.0, 63, 1.0, 0.0);
}
@ -469,7 +471,7 @@ R_LavaSplash_QF (const vec3_t org)
rnd = mtwist_rand (&mt);
vel = 50.0 + 0.5 * (float) (rnd & 127);
VectorScale (dir, vel, pvel);
particle_new (pt_grav, part_tex_dot, porg, 3, pvel,
particle_new ("pt_grav", part_tex_dot, porg, 3, pvel,
vr_data.realtime + 2.0 + ((rnd >> 7) & 31) * 0.02,
224 + ((rnd >> 12) & 7), 0.75, 0.0);
}
@ -507,7 +509,7 @@ R_TeleportSplash_QF (const vec3_t org)
vel = 50 + ((rnd >> 6) & 63);
VectorScale (pdir, vel, pvel);
particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel,
particle_new ("pt_grav", part_tex_spark, porg, 0.6, pvel,
(vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 15) * 0.01),
(7 + ((rnd >> 12) & 7)), 1.0, 0.0);
}
@ -536,7 +538,7 @@ R_RocketTrail_QF (entity_t *ent)
dist = (pscale + pscalenext) * 3.0;
percent = len * origlen;
particle_new (pt_smoke, part_tex_smoke, old_origin,
particle_new ("pt_smoke", part_tex_smoke, old_origin,
pscale + percent * 4.0, vec3_origin,
vr_data.realtime + 2.0 - percent * 2.0,
12 + (mtwist_rand (&mt) & 3),
@ -570,7 +572,7 @@ R_GrenadeTrail_QF (entity_t *ent)
dist = (pscale + pscalenext) * 2.0;
percent = len * origlen;
particle_new (pt_smoke, part_tex_smoke, old_origin,
particle_new ("pt_smoke", part_tex_smoke, old_origin,
pscale + percent * 4.0, vec3_origin,
vr_data.realtime + 2.0 - percent * 2.0,
1 + (mtwist_rand (&mt) & 3),
@ -612,7 +614,7 @@ R_BloodTrail_QF (entity_t *ent)
percent = len * origlen;
pvel[2] -= percent * 40.0;
particle_new (pt_grav, part_tex_smoke, porg, pscale, pvel,
particle_new ("pt_grav", part_tex_smoke, porg, pscale, pvel,
vr_data.realtime + 2.0 - percent * 2.0,
68 + (mtwist_rand (&mt) & 3), 1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -652,7 +654,7 @@ R_SlightBloodTrail_QF (entity_t *ent)
percent = len * origlen;
pvel[2] -= percent * 40;
particle_new (pt_grav, part_tex_smoke, porg, pscale, pvel,
particle_new ("pt_grav", part_tex_smoke, porg, pscale, pvel,
vr_data.realtime + 1.5 - percent * 1.5,
68 + (mtwist_rand (&mt) & 3), 0.75, 0.0);
if (numparticles >= r_maxparticles)
@ -693,7 +695,7 @@ R_WizTrail_QF (entity_t *ent)
}
pvel[2] = 0.0;
particle_new (pt_flame, part_tex_smoke, old_origin,
particle_new ("pt_flame", part_tex_smoke, old_origin,
2.0 + qfrandom (1.0) - percent * 2.0, pvel,
vr_data.realtime + 0.5 - percent * 0.5,
52 + (mtwist_rand (&mt) & 4), 1.0 - percent * 0.125, 0.0);
@ -734,7 +736,7 @@ R_FlameTrail_QF (entity_t *ent)
}
pvel[2] = 0.0;
particle_new (pt_flame, part_tex_smoke, old_origin,
particle_new ("pt_flame", part_tex_smoke, old_origin,
2.0 + qfrandom (1.0) - percent * 2.0, pvel,
vr_data.realtime + 0.5 - percent * 0.5, 234,
1.0 - percent * 0.125, 0.0);
@ -768,7 +770,7 @@ R_VoorTrail_QF (entity_t *ent)
for (j = 0; j < 3; j++)
porg[j] = old_origin[j] + qfrandom (16.0) - 8.0;
particle_new (pt_static, part_tex_dot, porg, 1.0 + qfrandom (1.0),
particle_new ("pt_static", part_tex_dot, porg, 1.0 + qfrandom (1.0),
vec3_origin, vr_data.realtime + 0.3 - percent * 0.3,
9 * 16 + 8 + (mtwist_rand (&mt) & 3), 1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -803,7 +805,7 @@ R_GlowTrail_QF (entity_t *ent, int glow_color)
org[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5;
org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5;
particle_new (pt_smoke, part_tex_dot, org, 1.0, vec3_origin,
particle_new ("pt_smoke", part_tex_dot, org, 1.0, vec3_origin,
vr_data.realtime + 2.0 - percent * 0.2,
glow_color, 1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -821,7 +823,7 @@ R_ParticleExplosion_EE (const vec3_t org)
*/
if (numparticles >= r_maxparticles)
return;
particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8,
particle_new_random ("pt_smokecloud", part_tex_smoke, org, 4, 30, 8,
vr_data.realtime + 5.0, mtwist_rand (&mt) & 255,
0.5 + qfrandom (0.25), 0.0);
}
@ -855,7 +857,7 @@ R_TeleportSplash_EE (const vec3_t org)
VectorNormalize (dir);
vel = 50 + ((rnd >> 6) & 63);
VectorScale (dir, vel, pvel);
particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel,
particle_new ("pt_grav", part_tex_spark, porg, 0.6, pvel,
(vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 15) * 0.01),
qfrandom (1.0), 1.0, 0.0);
}
@ -884,7 +886,7 @@ R_RocketTrail_EE (entity_t *ent)
dist = (pscale + pscalenext) * 3.0;
percent = len * origlen;
particle_new (pt_smoke, part_tex_smoke, old_origin,
particle_new ("pt_smoke", part_tex_smoke, old_origin,
pscale + percent * 4.0, vec3_origin,
vr_data.realtime + 2.0 - percent * 2.0,
mtwist_rand (&mt) & 255,
@ -919,7 +921,7 @@ R_GrenadeTrail_EE (entity_t *ent)
dist = (pscale + pscalenext) * 2.0;
percent = len * origlen;
particle_new (pt_smoke, part_tex_smoke, old_origin,
particle_new ("pt_smoke", part_tex_smoke, old_origin,
pscale + percent * 4.0, vec3_origin,
vr_data.realtime + 2.0 - percent * 2.0,
mtwist_rand (&mt) & 255,
@ -945,11 +947,11 @@ R_ParticleExplosion_ID (const vec3_t org)
j = r_maxparticles - numparticles;
for (i = 0; i < j >> 1; i++) {
particle_new_random (pt_explode, part_tex_dot, org, 16, 1.0, 256,
particle_new_random ("pt_explode", part_tex_dot, org, 16, 1.0, 256,
vr_data.realtime + 5.0, ramp1[0], 1.0, i & 3);
}
for (i = 0; i < j / 2; i++) {
particle_new_random (pt_explode2, part_tex_dot, org, 16, 1.0, 256,
particle_new_random ("pt_explode2", part_tex_dot, org, 16, 1.0, 256,
vr_data.realtime + 5.0, ramp1[0], 1.0, i & 3);
}
}
@ -966,12 +968,12 @@ R_BlobExplosion_ID (const vec3_t org)
j = r_maxparticles - numparticles;
for (i = 0; i < j >> 1; i++) {
particle_new_random (pt_blob, part_tex_dot, org, 12, 1.0, 256,
particle_new_random ("pt_blob", part_tex_dot, org, 12, 1.0, 256,
vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 8) * 0.05,
66 + i % 6, 1.0, 0.0);
}
for (i = 0; i < j / 2; i++) {
particle_new_random (pt_blob2, part_tex_dot, org, 12, 1.0, 256,
particle_new_random ("pt_blob2", part_tex_dot, org, 12, 1.0, 256,
vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 8) * 0.05,
150 + i % 6, 1.0, 0.0);
}
@ -1006,7 +1008,7 @@ R_RunParticleEffect_ID (const vec3_t org, const vec3_t dir, int color,
porg[2] = org[2] + scale * (((rnd >> 11) & 15) - 8);
// Note that ParseParticleEffect handles (dir * 15)
particle_new (pt_grav, part_tex_dot, porg, 1.0, dir,
particle_new ("pt_grav", part_tex_dot, porg, 1.0, dir,
vr_data.realtime + 0.1 * (i % 5),
(color & ~7) + (rnd & 7), 1.0, 0.0);
}
@ -1083,7 +1085,7 @@ R_LavaSplash_ID (const vec3_t org)
rnd = mtwist_rand (&mt);
vel = 50 + (rnd & 63);
VectorScale (dir, vel, pvel);
particle_new (pt_grav, part_tex_dot, porg, 1.0, pvel,
particle_new ("pt_grav", part_tex_dot, porg, 1.0, pvel,
vr_data.realtime + 2 + ((rnd >> 7) & 31) * 0.02,
224 + ((rnd >> 12) & 7), 1.0, 0.0);
}
@ -1121,7 +1123,7 @@ R_TeleportSplash_ID (const vec3_t org)
vel = 50 + ((rnd >> 6) & 63);
VectorScale (pdir, vel, pvel);
particle_new (pt_grav, part_tex_dot, porg, 1.0, pvel,
particle_new ("pt_grav", part_tex_dot, porg, 1.0, pvel,
(vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 7) * 0.02),
(7 + ((rnd >> 12) & 7)), 1.0, 0.0);
}
@ -1160,7 +1162,7 @@ R_DarkFieldParticles_ID (entity_t *ent)
VectorNormalize (dir);
vel = 50 + ((rnd >> 9) & 63);
VectorScale (dir, vel, pvel);
particle_new (pt_slowgrav, part_tex_dot, porg, 1.5, pvel,
particle_new ("pt_slowgrav", part_tex_dot, porg, 1.5, pvel,
(vr_data.realtime + 0.2 + (rnd & 7) * 0.02),
(150 + mtwist_rand (&mt) % 6), 1.0, 0.0);
}
@ -1215,7 +1217,7 @@ R_EntityParticles_ID (entity_t *ent)
forward[1] * beamlength;
porg[2] = ent->origin[2] + r_avertexnormals[i][2] * dist +
forward[2] * beamlength;
particle_new (pt_explode, part_tex_dot, porg, 1.0, vec3_origin,
particle_new ("pt_explode", part_tex_dot, porg, 1.0, vec3_origin,
vr_data.realtime + 0.01, 0x6f, 1.0, 0);
}
}
@ -1243,7 +1245,7 @@ R_RocketTrail_ID (entity_t *ent)
org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5;
ramp = rnd & 3;
particle_new (pt_fire, part_tex_dot, org, 1.0, vec3_origin,
particle_new ("pt_fire", part_tex_dot, org, 1.0, vec3_origin,
vr_data.realtime + 2.0, ramp3[ramp], 1.0, ramp);
if (numparticles >= r_maxparticles)
break;
@ -1275,7 +1277,7 @@ R_GrenadeTrail_ID (entity_t *ent)
org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5;
ramp = (rnd & 3) + 2;
particle_new (pt_fire, part_tex_dot, org, 1.0, vec3_origin,
particle_new ("pt_fire", part_tex_dot, org, 1.0, vec3_origin,
vr_data.realtime + 2.0, ramp3[ramp], 1.0, ramp);
if (numparticles >= r_maxparticles)
break;
@ -1306,7 +1308,7 @@ R_BloodTrail_ID (entity_t *ent)
porg[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5;
porg[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5;
particle_new (pt_grav, part_tex_dot, porg, 1.0, vec3_origin,
particle_new ("pt_grav", part_tex_dot, porg, 1.0, vec3_origin,
vr_data.realtime + 2.0, 67 + (rnd & 3), 1.0, 0.0);
if (numparticles >= r_maxparticles)
break;
@ -1337,7 +1339,7 @@ R_SlightBloodTrail_ID (entity_t *ent)
porg[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5;
porg[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5;
particle_new (pt_grav, part_tex_dot, porg, 1.0, vec3_origin,
particle_new ("pt_grav", part_tex_dot, porg, 1.0, vec3_origin,
vr_data.realtime + 1.5, 67 + (rnd & 3), 1.0, 0.0);
if (numparticles >= r_maxparticles)
break;
@ -1373,7 +1375,7 @@ R_WizTrail_ID (entity_t *ent)
}
pvel[2] = 0.0;
particle_new (pt_static, part_tex_dot, old_origin, 1.0, pvel,
particle_new ("pt_static", part_tex_dot, old_origin, 1.0, pvel,
vr_data.realtime + 0.5, 52 + ((tracercount & 4) << 1),
1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -1410,7 +1412,7 @@ R_FlameTrail_ID (entity_t *ent)
}
pvel[2] = 0.0;
particle_new (pt_static, part_tex_dot, old_origin, 1.0, pvel,
particle_new ("pt_static", part_tex_dot, old_origin, 1.0, pvel,
vr_data.realtime + 0.5, 230 + ((tracercount & 4) << 1),
1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -1442,7 +1444,7 @@ R_VoorTrail_ID (entity_t *ent)
porg[1] = old_origin[1] + ((rnd >> 7) & 15) - 7.5;
porg[2] = old_origin[2] + ((rnd >> 11) & 15) - 7.5;
particle_new (pt_static, part_tex_dot, porg, 1.0, vec3_origin,
particle_new ("pt_static", part_tex_dot, porg, 1.0, vec3_origin,
vr_data.realtime + 0.3, 9 * 16 + 8 + (rnd & 3),
1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -1550,7 +1552,7 @@ gl_R_DrawParticles (void)
}
}
part->phys (part);
R_RunParticlePhysics (part);
// LordHavoc: immediate removal of unnecessary particles (must be done
// to ensure compactor below operates properly in all cases)
@ -1777,7 +1779,7 @@ gl_R_Particles_Init_Cvars (void)
}
void
gl_R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale,
gl_R_Particle_New (const char *type, int texnum, const vec3_t org, float scale,
const vec3_t vel, float die, int color, float alpha,
float ramp)
{
@ -1787,7 +1789,7 @@ gl_R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale,
}
void
gl_R_Particle_NewRandom (ptype_t type, int texnum, const vec3_t org,
gl_R_Particle_NewRandom (const char *type, int texnum, const vec3_t org,
int org_fuzz, float scale, int vel_fuzz, float die,
int color, float alpha, float ramp)
{

View file

@ -228,7 +228,7 @@ free_point (particle_t *point)
}
inline static void
particle_new (ptype_t type, int texnum, const vec3_t org, float scale,
particle_new (const char *type, int texnum, const vec3_t org, float scale,
const vec3_t vel, float die, int color, float alpha, float ramp)
{
particle_t *part;
@ -249,10 +249,9 @@ particle_new (ptype_t type, int texnum, const vec3_t org, float scale,
part->scale = scale;
part->alpha = alpha;
VectorCopy (vel, part->vel);
part->type = type;
part->die = die;
part->ramp = ramp;
part->phys = R_ParticlePhysics (type);
part->physics = R_ParticlePhysics (type);
}
/*
@ -262,9 +261,9 @@ particle_new (ptype_t type, int texnum, const vec3_t org, float scale,
going to bother using this function.
*/
inline static void
particle_new_random (ptype_t type, int texnum, const vec3_t org, int org_fuzz,
float scale, int vel_fuzz, float die, int color,
float alpha, float ramp)
particle_new_random (const char *type, int texnum, const vec3_t org,
int org_fuzz, float scale, int vel_fuzz, float die,
int color, float alpha, float ramp)
{
float o_fuzz = org_fuzz, v_fuzz = vel_fuzz;
int rnd;
@ -317,6 +316,8 @@ glsl_R_InitParticles (void)
byte data[64][64][2];
tex_t *tex;
R_LoadParticles ();
mtwist_seed (&mt, 0xdeadbeef);
qfeglEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
@ -447,7 +448,7 @@ glsl_R_ReadPointFile_f (void)
Sys_MaskPrintf (SYS_DEV, "Not enough free particles\n");
break;
} else {
particle_new (pt_static, part_tex_dot, org, 1.5, vec3_origin,
particle_new ("pt_static", part_tex_dot, org, 1.5, vec3_origin,
99999, (-c) & 15, 1.0, 0.0);
}
}
@ -461,7 +462,7 @@ R_ParticleExplosion_QF (const vec3_t org)
// R_NewExplosion (org);
if (numparticles >= r_maxparticles)
return;
particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8,
particle_new_random ("pt_smokecloud", part_tex_smoke, org, 4, 30, 8,
vr_data.realtime + 5.0, (mtwist_rand (&mt) & 7) + 8,
0.5 + qfrandom (0.25), 0.0);
}
@ -477,7 +478,7 @@ R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength)
j = r_maxparticles - numparticles;
for (i = 0; i < j; i++) {
particle_new_random (pt_blob, part_tex_dot, org, 16, 2, 256,
particle_new_random ("pt_blob", part_tex_dot, org, 16, 2, 256,
vr_data.realtime + 0.3,
colorStart + (i % colorLength), 1.0, 0.0);
}
@ -495,12 +496,12 @@ R_BlobExplosion_QF (const vec3_t org)
j = r_maxparticles - numparticles;
for (i = 0; i < j >> 1; i++) {
particle_new_random (pt_blob, part_tex_dot, org, 12, 2, 256,
particle_new_random ("pt_blob", part_tex_dot, org, 12, 2, 256,
vr_data.realtime + 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,
particle_new_random ("pt_blob2", part_tex_dot, org, 12, 2, 256,
vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 7) * 0.05,
150 + i % 6, 1.0, 0.0);
}
@ -511,7 +512,7 @@ R_RunSparkEffect_QF (const vec3_t org, int count, int ofuzz)
{
if (numparticles >= r_maxparticles)
return;
particle_new (pt_smokecloud, part_tex_smoke, org, ofuzz * 0.08,
particle_new ("pt_smokecloud", part_tex_smoke, org, ofuzz * 0.08,
vec3_origin, vr_data.realtime + 9, 12 + (mtwist_rand (&mt) & 3),
0.25 + qfrandom (0.125), 0.0);
@ -525,7 +526,7 @@ R_RunSparkEffect_QF (const vec3_t org, int count, int ofuzz)
while (count--) {
int color = mtwist_rand (&mt) & 7;
particle_new_random (pt_fallfadespark, part_tex_dot, org, orgfuzz,
particle_new_random ("pt_fallfadespark", part_tex_dot, org, orgfuzz,
0.7, 96, vr_data.realtime + 5.0, ramp1[color],
1.0, color);
}
@ -538,7 +539,7 @@ R_BloodPuff_QF (const vec3_t org, int count)
if (numparticles >= r_maxparticles)
return;
particle_new (pt_bloodcloud, part_tex_smoke, org, count / 5, vec3_origin,
particle_new ("pt_bloodcloud", part_tex_smoke, org, count / 5, vec3_origin,
vr_data.realtime + 99.0, 70 + (mtwist_rand (&mt) & 3), 0.5, 0.0);
}
@ -566,14 +567,14 @@ R_LightningBloodEffect_QF (const vec3_t org)
if (numparticles >= r_maxparticles)
return;
particle_new (pt_smokecloud, part_tex_smoke, org, 3.0, vec3_origin,
particle_new ("pt_smokecloud", part_tex_smoke, org, 3.0, vec3_origin,
vr_data.realtime + 9.0, 12 + (mtwist_rand (&mt) & 3),
0.25 + qfrandom (0.125), 0.0);
if (numparticles + count >= r_maxparticles)
count = r_maxparticles - numparticles;
while (count--)
particle_new_random (pt_fallfade, part_tex_spark, org, 12, 2.0, 128,
particle_new_random ("pt_fallfade", part_tex_spark, org, 12, 2.0, 128,
vr_data.realtime + 5.0, 244 + (count % 3),
1.0, 0.0);
}
@ -601,7 +602,7 @@ R_RunParticleEffect_QF (const vec3_t org, const vec3_t dir, int color,
porg[1] = org[1] + scale * (((rnd >> 7) & 15) - 7.5);
porg[2] = org[2] + scale * (((rnd >> 11) & 15) - 7.5);
// Note that ParseParticleEffect handles (dir * 15)
particle_new (pt_grav, part_tex_dot, porg, 1.5, dir,
particle_new ("pt_grav", part_tex_dot, porg, 1.5, dir,
vr_data.realtime + 0.1 * (i % 5),
(color & ~7) + (rnd & 7), 1.0, 0.0);
}
@ -626,13 +627,13 @@ R_KnightSpikeEffect_QF (const vec3_t org)
if (numparticles >= r_maxparticles)
return;
particle_new (pt_smokecloud, part_tex_smoke, org, 1.0, vec3_origin,
particle_new ("pt_smokecloud", part_tex_smoke, org, 1.0, vec3_origin,
vr_data.realtime + 9.0, 234, 0.25 + qfrandom (0.125), 0.0);
if (numparticles + count >= r_maxparticles)
count = r_maxparticles - numparticles;
while (count--)
particle_new_random (pt_fallfade, part_tex_dot, org, 6, 0.7, 96,
particle_new_random ("pt_fallfade", part_tex_dot, org, 6, 0.7, 96,
vr_data.realtime + 5.0, 234, 1.0, 0.0);
}
@ -643,13 +644,13 @@ R_WizSpikeEffect_QF (const vec3_t org)
if (numparticles >= r_maxparticles)
return;
particle_new (pt_smokecloud, part_tex_smoke, org, 2.0, vec3_origin,
particle_new ("pt_smokecloud", part_tex_smoke, org, 2.0, vec3_origin,
vr_data.realtime + 9.0, 63, 0.25 + qfrandom (0.125), 0.0);
if (numparticles + count >= r_maxparticles)
count = r_maxparticles - numparticles;
while (count--)
particle_new_random (pt_fallfade, part_tex_dot, org, 12, 0.7, 96,
particle_new_random ("pt_fallfade", part_tex_dot, org, 12, 0.7, 96,
vr_data.realtime + 5.0, 63, 1.0, 0.0);
}
@ -682,7 +683,7 @@ R_LavaSplash_QF (const vec3_t org)
rnd = mtwist_rand (&mt);
vel = 50.0 + 0.5 * (float) (rnd & 127);
VectorScale (dir, vel, pvel);
particle_new (pt_grav, part_tex_dot, porg, 3, pvel,
particle_new ("pt_grav", part_tex_dot, porg, 3, pvel,
vr_data.realtime + 2.0 + ((rnd >> 7) & 31) * 0.02,
224 + ((rnd >> 12) & 7), 0.75, 0.0);
}
@ -720,7 +721,7 @@ R_TeleportSplash_QF (const vec3_t org)
vel = 50 + ((rnd >> 6) & 63);
VectorScale (pdir, vel, pvel);
particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel,
particle_new ("pt_grav", part_tex_spark, porg, 0.6, pvel,
(vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 15) * 0.01),
(7 + ((rnd >> 12) & 7)), 1.0, 0.0);
}
@ -764,10 +765,9 @@ R_RocketTrail_trail (entity_t *ent)
point->scale = pscale + percent * 4.0;
point->alpha = 0.5 + qfrandom (0.125) - percent * 0.40;
VectorCopy (vec3_origin, point->vel);
point->type = pt_smoke;
point->die = vr_data.realtime + 2.0 - percent * 2.0;
point->ramp = 0.0;
point->phys = R_ParticlePhysics (point->type);
point->physics = R_ParticlePhysics ("pt_fire");
*ent->trail->head = point;
ent->trail->head = &point->next;
@ -800,7 +800,7 @@ R_RocketTrail_QF (entity_t *ent)
dist = (pscale + pscalenext) * 3.0;
percent = len * origlen;
particle_new (pt_smoke, part_tex_smoke, old_origin,
particle_new ("pt_smoke", part_tex_smoke, old_origin,
pscale + percent * 4.0, vec3_origin,
vr_data.realtime + 2.0 - percent * 2.0,
12 + (mtwist_rand (&mt) & 3),
@ -834,7 +834,7 @@ R_GrenadeTrail_QF (entity_t *ent)
dist = (pscale + pscalenext) * 2.0;
percent = len * origlen;
particle_new (pt_smoke, part_tex_smoke, old_origin,
particle_new ("pt_smoke", part_tex_smoke, old_origin,
pscale + percent * 4.0, vec3_origin,
vr_data.realtime + 2.0 - percent * 2.0,
1 + (mtwist_rand (&mt) & 3),
@ -876,7 +876,7 @@ R_BloodTrail_QF (entity_t *ent)
percent = len * origlen;
pvel[2] -= percent * 40.0;
particle_new (pt_grav, part_tex_smoke, porg, pscale, pvel,
particle_new ("pt_grav", part_tex_smoke, porg, pscale, pvel,
vr_data.realtime + 2.0 - percent * 2.0,
68 + (mtwist_rand (&mt) & 3), 1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -916,7 +916,7 @@ R_SlightBloodTrail_QF (entity_t *ent)
percent = len * origlen;
pvel[2] -= percent * 40;
particle_new (pt_grav, part_tex_smoke, porg, pscale, pvel,
particle_new ("pt_grav", part_tex_smoke, porg, pscale, pvel,
vr_data.realtime + 1.5 - percent * 1.5,
68 + (mtwist_rand (&mt) & 3), 0.75, 0.0);
if (numparticles >= r_maxparticles)
@ -957,7 +957,7 @@ R_WizTrail_QF (entity_t *ent)
}
pvel[2] = 0.0;
particle_new (pt_flame, part_tex_smoke, old_origin,
particle_new ("pt_flame", part_tex_smoke, old_origin,
2.0 + qfrandom (1.0) - percent * 2.0, pvel,
vr_data.realtime + 0.5 - percent * 0.5,
52 + (mtwist_rand (&mt) & 4), 1.0 - percent * 0.125, 0.0);
@ -998,7 +998,7 @@ R_FlameTrail_QF (entity_t *ent)
}
pvel[2] = 0.0;
particle_new (pt_flame, part_tex_smoke, old_origin,
particle_new ("pt_flame", part_tex_smoke, old_origin,
2.0 + qfrandom (1.0) - percent * 2.0, pvel,
vr_data.realtime + 0.5 - percent * 0.5, 234,
1.0 - percent * 0.125, 0.0);
@ -1032,7 +1032,7 @@ R_VoorTrail_QF (entity_t *ent)
for (j = 0; j < 3; j++)
porg[j] = old_origin[j] + qfrandom (16.0) - 8.0;
particle_new (pt_static, part_tex_dot, porg, 1.0 + qfrandom (1.0),
particle_new ("pt_static", part_tex_dot, porg, 1.0 + qfrandom (1.0),
vec3_origin, vr_data.realtime + 0.3 - percent * 0.3,
9 * 16 + 8 + (mtwist_rand (&mt) & 3), 1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -1067,7 +1067,7 @@ R_GlowTrail_QF (entity_t *ent, int glow_color)
org[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5;
org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5;
particle_new (pt_smoke, part_tex_dot, org, 1.0, vec3_origin,
particle_new ("pt_smoke", part_tex_dot, org, 1.0, vec3_origin,
vr_data.realtime + 2.0 - percent * 0.2, glow_color,
1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -1085,7 +1085,7 @@ R_ParticleExplosion_EE (const vec3_t org)
*/
if (numparticles >= r_maxparticles)
return;
particle_new_random (pt_smokecloud, part_tex_smoke, org, 4, 30, 8,
particle_new_random ("pt_smokecloud", part_tex_smoke, org, 4, 30, 8,
vr_data.realtime + 5.0, mtwist_rand (&mt) & 255,
0.5 + qfrandom (0.25), 0.0);
}
@ -1119,7 +1119,7 @@ R_TeleportSplash_EE (const vec3_t org)
VectorNormalize (dir);
vel = 50 + ((rnd >> 6) & 63);
VectorScale (dir, vel, pvel);
particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel,
particle_new ("pt_grav", part_tex_spark, porg, 0.6, pvel,
(vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 15) * 0.01),
qfrandom (1.0), 1.0, 0.0);
}
@ -1148,7 +1148,7 @@ R_RocketTrail_EE (entity_t *ent)
dist = (pscale + pscalenext) * 3.0;
percent = len * origlen;
particle_new (pt_smoke, part_tex_smoke, old_origin,
particle_new ("pt_smoke", part_tex_smoke, old_origin,
pscale + percent * 4.0, vec3_origin,
vr_data.realtime + 2.0 - percent * 2.0,
mtwist_rand (&mt) & 255,
@ -1183,7 +1183,7 @@ R_GrenadeTrail_EE (entity_t *ent)
dist = (pscale + pscalenext) * 2.0;
percent = len * origlen;
particle_new (pt_smoke, part_tex_smoke, old_origin,
particle_new ("pt_smoke", part_tex_smoke, old_origin,
pscale + percent * 4.0, vec3_origin,
vr_data.realtime + 2.0 - percent * 2.0,
mtwist_rand (&mt) & 255,
@ -1209,11 +1209,11 @@ R_ParticleExplosion_ID (const vec3_t org)
j = r_maxparticles - numparticles;
for (i = 0; i < j >> 1; i++) {
particle_new_random (pt_explode, part_tex_dot, org, 16, 1.0, 256,
particle_new_random ("pt_explode", part_tex_dot, org, 16, 1.0, 256,
vr_data.realtime + 5.0, ramp1[0], 1.0, i & 3);
}
for (i = 0; i < j / 2; i++) {
particle_new_random (pt_explode2, part_tex_dot, org, 16, 1.0, 256,
particle_new_random ("pt_explode2", part_tex_dot, org, 16, 1.0, 256,
vr_data.realtime + 5.0, ramp1[0], 1.0, i & 3);
}
}
@ -1230,12 +1230,12 @@ R_BlobExplosion_ID (const vec3_t org)
j = r_maxparticles - numparticles;
for (i = 0; i < j >> 1; i++) {
particle_new_random (pt_blob, part_tex_dot, org, 12, 1.0, 256,
particle_new_random ("pt_blob", part_tex_dot, org, 12, 1.0, 256,
vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 8) * 0.05,
66 + i % 6, 1.0, 0.0);
}
for (i = 0; i < j / 2; i++) {
particle_new_random (pt_blob2, part_tex_dot, org, 12, 1.0, 256,
particle_new_random ("pt_blob2", part_tex_dot, org, 12, 1.0, 256,
vr_data.realtime + 1.0 + (mtwist_rand (&mt) & 8) * 0.05,
150 + i % 6, 1.0, 0.0);
}
@ -1270,7 +1270,7 @@ R_RunParticleEffect_ID (const vec3_t org, const vec3_t dir, int color,
porg[2] = org[2] + scale * (((rnd >> 11) & 15) - 8);
// Note that ParseParticleEffect handles (dir * 15)
particle_new (pt_grav, part_tex_dot, porg, 1.0, dir,
particle_new ("pt_grav", part_tex_dot, porg, 1.0, dir,
vr_data.realtime + 0.1 * (i % 5),
(color & ~7) + (rnd & 7), 1.0, 0.0);
}
@ -1347,7 +1347,7 @@ R_LavaSplash_ID (const vec3_t org)
rnd = mtwist_rand (&mt);
vel = 50 + (rnd & 63);
VectorScale (dir, vel, pvel);
particle_new (pt_grav, part_tex_dot, porg, 1.0, pvel,
particle_new ("pt_grav", part_tex_dot, porg, 1.0, pvel,
vr_data.realtime + 2 + ((rnd >> 7) & 31) * 0.02,
224 + ((rnd >> 12) & 7), 1.0, 0.0);
}
@ -1385,7 +1385,7 @@ R_TeleportSplash_ID (const vec3_t org)
vel = 50 + ((rnd >> 6) & 63);
VectorScale (pdir, vel, pvel);
particle_new (pt_grav, part_tex_dot, porg, 1.0, pvel,
particle_new ("pt_grav", part_tex_dot, porg, 1.0, pvel,
(vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 7) * 0.02),
(7 + ((rnd >> 12) & 7)), 1.0, 0.0);
}
@ -1424,7 +1424,7 @@ R_DarkFieldParticles_ID (entity_t *ent)
VectorNormalize (dir);
vel = 50 + ((rnd >> 9) & 63);
VectorScale (dir, vel, pvel);
particle_new (pt_slowgrav, part_tex_dot, porg, 1.5, pvel,
particle_new ("pt_slowgrav", part_tex_dot, porg, 1.5, pvel,
(vr_data.realtime + 0.2 + (rnd & 7) * 0.02),
(150 + mtwist_rand (&mt) % 6), 1.0, 0.0);
}
@ -1477,7 +1477,7 @@ R_EntityParticles_ID (entity_t *ent)
forward[1] * beamlength;
porg[2] = ent->origin[2] + vertex_normals[i][2] * dist +
forward[2] * beamlength;
particle_new (pt_explode, part_tex_dot, porg, 1.0, vec3_origin,
particle_new ("pt_explode", part_tex_dot, porg, 1.0, vec3_origin,
vr_data.realtime + 0.01, 0x6f, 1.0, 0);
}
}
@ -1505,7 +1505,7 @@ R_RocketTrail_ID (entity_t *ent)
org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5;
ramp = rnd & 3;
particle_new (pt_fire, part_tex_dot, org, 1.0, vec3_origin,
particle_new ("pt_fire", part_tex_dot, org, 1.0, vec3_origin,
vr_data.realtime + 2.0, ramp3[ramp], 1.0, ramp);
if (numparticles >= r_maxparticles)
break;
@ -1537,7 +1537,7 @@ R_GrenadeTrail_ID (entity_t *ent)
org[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5;
ramp = (rnd & 3) + 2;
particle_new (pt_fire, part_tex_dot, org, 1.0, vec3_origin,
particle_new ("pt_fire", part_tex_dot, org, 1.0, vec3_origin,
vr_data.realtime + 2.0, ramp3[ramp], 1.0, ramp);
if (numparticles >= r_maxparticles)
break;
@ -1568,7 +1568,7 @@ R_BloodTrail_ID (entity_t *ent)
porg[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5;
porg[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5;
particle_new (pt_grav, part_tex_dot, porg, 1.0, vec3_origin,
particle_new ("pt_grav", part_tex_dot, porg, 1.0, vec3_origin,
vr_data.realtime + 2.0, 67 + (rnd & 3), 1.0, 0.0);
if (numparticles >= r_maxparticles)
break;
@ -1599,7 +1599,7 @@ R_SlightBloodTrail_ID (entity_t *ent)
porg[1] = old_origin[1] + ((rnd >> 9) & 7) * (5.0/7.0) - 2.5;
porg[2] = old_origin[2] + ((rnd >> 6) & 7) * (5.0/7.0) - 2.5;
particle_new (pt_grav, part_tex_dot, porg, 1.0, vec3_origin,
particle_new ("pt_grav", part_tex_dot, porg, 1.0, vec3_origin,
vr_data.realtime + 1.5, 67 + (rnd & 3), 1.0, 0.0);
if (numparticles >= r_maxparticles)
break;
@ -1635,7 +1635,7 @@ R_WizTrail_ID (entity_t *ent)
}
pvel[2] = 0.0;
particle_new (pt_static, part_tex_dot, old_origin, 1.0, pvel,
particle_new ("pt_static", part_tex_dot, old_origin, 1.0, pvel,
vr_data.realtime + 0.5, 52 + ((tracercount & 4) << 1),
1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -1672,7 +1672,7 @@ R_FlameTrail_ID (entity_t *ent)
}
pvel[2] = 0.0;
particle_new (pt_static, part_tex_dot, old_origin, 1.0, pvel,
particle_new ("pt_static", part_tex_dot, old_origin, 1.0, pvel,
vr_data.realtime + 0.5, 230 + ((tracercount & 4) << 1),
1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -1704,7 +1704,7 @@ R_VoorTrail_ID (entity_t *ent)
porg[1] = old_origin[1] + ((rnd >> 7) & 15) - 7.5;
porg[2] = old_origin[2] + ((rnd >> 11) & 15) - 7.5;
particle_new (pt_static, part_tex_dot, porg, 1.0, vec3_origin,
particle_new ("pt_static", part_tex_dot, porg, 1.0, vec3_origin,
vr_data.realtime + 0.3, 9 * 16 + 8 + (rnd & 3),
1.0, 0.0);
if (numparticles >= r_maxparticles)
@ -1763,7 +1763,7 @@ build_verts (trailvtx_t *v, GLushort *e)
*e++ = index++;
*e++ = index++;
last_point = point;
point->phys (point);
R_RunParticlePhysics (point);
}
set_vertex (v++, last_point, -1, bary + bind++, index/2 + 1);
set_vertex (v++, last_point, 1, bary + bind++, index/2 + 1);
@ -1964,7 +1964,7 @@ draw_qf_particles (void)
vacount += 6;
}
part->phys (part);
R_RunParticlePhysics (part);
// LordHavoc: immediate removal of unnecessary particles (must be done
// to ensure compactor below operates properly in all cases)
@ -2052,7 +2052,7 @@ draw_id_particles (void)
vacount++;
}
part->phys (part);
R_RunParticlePhysics (part);
// LordHavoc: immediate removal of unnecessary particles (must be done
// to ensure compactor below operates properly in all cases)
@ -2316,9 +2316,9 @@ glsl_R_Particles_Init_Cvars (void)
}
void
glsl_R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale,
const vec3_t vel, float die, int color, float alpha,
float ramp)
glsl_R_Particle_New (const char *type, int texnum, const vec3_t org,
float scale, const vec3_t vel, float die, int color,
float alpha, float ramp)
{
if (numparticles >= r_maxparticles)
return;
@ -2326,7 +2326,7 @@ glsl_R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale,
}
void
glsl_R_Particle_NewRandom (ptype_t type, int texnum, const vec3_t org,
glsl_R_Particle_NewRandom (const char *type, int texnum, const vec3_t org,
int org_fuzz, float scale, int vel_fuzz, float die,
int color, float alpha, float ramp)
{

View file

@ -0,0 +1,83 @@
All of QuakeForge's standard particle physics functions converted to a script
-- pt_static
add_vel
-- pt_grav
add_vel
add_grav
-- pt_slowgrav
add_vel
add_grav
-- pt_fire
add_ramp 5 6
add_vel
color_ramp3
alpha_ramp 6
sub_grav
-- pt_explode
add_ramp 10 8
add_vel
color_ramp1
explode_vel 4
add_grav
-- pt_explode2
add_ramp 15 8
add_vel
color_ramp2
explode_vel 1
add_grav
-- pt_blob
add_vel
explode_vel 4
add_grav
-- pt_blob2
add_vel
damp_vel 4
add_grav
-- pt_smoke
fade_alpha 0.4
add_vel
grow_scale 4
//sub_slowgrav
-- pt_smokecloud
fade_alpha 0.55
add_vel
grow_scale 50
sub_slowgrav
-- pt_bloodcloud
fade_alpha 0.25
add_vel
grow_scale 4
add_grav
-- pt_fadespark
add_vel
-- pt_fadespark2
add_vel
-- pt_fallfade
fade_alpha 1
add_vel
add_fastgrav
-- pt_fallfadespark
add_ramp 15 8
fade_alpha 1
color_ramp1
add_vel
add_fastgrav
-- pt_flame
fade_alpha 0.125
add_vel
shrink_scale 2

View file

@ -28,14 +28,101 @@
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/alloc.h"
#include "QF/cbuf.h"
#include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/qargs.h"
#include "QF/render.h"
#include "QF/script.h"
#include "QF/segtext.h"
#include "QF/sys.h"
#include "compat.h"
#include "r_internal.h"
typedef enum {
pt_phys_done,
pt_phys_add_vel,
pt_phys_sub_slowgrav,
pt_phys_add_grav,
pt_phys_sub_grav,
pt_phys_add_fastgrav,
pt_phys_add_ramp, // die
pt_phys_fade_alpha, // die
pt_phys_color_ramp1,
pt_phys_color_ramp2,
pt_phys_color_ramp3,
pt_phys_alpha_ramp,
pt_phys_explode_vel,
pt_phys_damp_vel,
pt_phys_grow_scale,
pt_phys_shrink_scale, // die
pt_phys_custom, // die
} pt_phys_e;
typedef struct {
const char *name;
pt_phys_e opcode;
int num_params;
} pt_phys_opcode_t;
typedef struct {
char *name;
qboolean (*func) (particle_t *part, void *data);
void *data;
} pt_phys_func_t;
typedef union pt_phys_op_s {
int32_t op;
float parm;
} pt_phys_op_t;
typedef struct pt_phys_script_s {
struct pt_phys_script_s *next;
char *name;
pt_phys_op_t *script;
} pt_phys_script_t;
const char particle_types[] =
#include "particles.pc"
;
static pt_phys_func_t *phys_funcs;
static int num_phys_funcs;
static int max_phys_funcs;
static pt_phys_script_t *phys_script_freelist;
static hashtab_t *phys_scripts;
static pt_phys_opcode_t part_phys_opcodes[] =
{
{"add_vel", pt_phys_add_vel, 0},
{"sub_slowgrav", pt_phys_sub_slowgrav, 0},
{"add_grav", pt_phys_add_grav, 0},
{"sub_grav", pt_phys_sub_grav, 0},
{"add_fastgrav", pt_phys_add_fastgrav, 0},
{"add_ramp", pt_phys_add_ramp, 2},
{"fade_alpha", pt_phys_fade_alpha, 1},
{"color_ramp1", pt_phys_color_ramp1, 0},
{"color_ramp2", pt_phys_color_ramp2, 0},
{"color_ramp3", pt_phys_color_ramp3, 0},
{"alpha_ramp", pt_phys_alpha_ramp, 1},
{"explode_vel", pt_phys_explode_vel, 1},
{"damp_vel", pt_phys_damp_vel, 1},
{"grow_scale", pt_phys_grow_scale, 1},
{"shrink_scale", pt_phys_shrink_scale, 1},
{0, pt_phys_done, 0},
};
unsigned int r_maxparticles, numparticles;
particle_t *active_particles, *free_particles, *particles, **freeparticles;
vec3_t r_pright, r_pup, r_ppn;
@ -160,152 +247,307 @@ fade_alpha (particle_t *part, float time)
return false;
}
static void
part_phys_static (particle_t *part)
static inline qboolean
custom_func (particle_t *part, int op)
{
add_vel (part);
int func;
func = op - pt_phys_custom;
if (func < 0 || func >= num_phys_funcs) {
Sys_Error ("invalid custom particle physics opcode: %d", op);
}
if (phys_funcs[func].func (part, phys_funcs[func].data)) {
part->die = -1;
return true;
}
return false;
}
static void
part_phys_grav (particle_t *part)
void
R_RunParticlePhysics (particle_t *part)
{
add_vel (part);
add_grav (part);
}
const pt_phys_op_t *op;
float parm, max;
static void
part_phys_fire (particle_t *part)
{
if (add_ramp (part, 5.0, 6))
if (!part->physics) {
// safety net for physicsless particles
add_ramp (part, 1, 4);
return;
add_vel (part);
part->color = ramp3[(int) part->ramp];
part->alpha = (6.0 - part->ramp) / 6.0;
sub_grav (part);
}
for (op = part->physics; ; op++) {
if (op->op >= pt_phys_custom) {
if (custom_func (part, op->op))
return;
}
switch ((pt_phys_e) op->op) {
case pt_phys_done:
return;
case pt_phys_add_vel:
add_vel (part);
break;
case pt_phys_sub_slowgrav:
sub_slowgrav (part);
break;
case pt_phys_add_grav:
add_grav (part);
break;
case pt_phys_sub_grav:
sub_grav (part);
break;
case pt_phys_add_fastgrav:
add_fastgrav (part);
break;
case pt_phys_add_ramp:
parm = (++op)->parm;
max = (++op)->parm;
if (add_ramp (part, parm, max))
return;
break;
case pt_phys_fade_alpha:
parm = (++op)->parm;
if (fade_alpha (part, parm))
return;
break;
case pt_phys_color_ramp1:
part->color = ramp1[((int) part->ramp) % sizeof (ramp1)];
break;
case pt_phys_color_ramp2:
part->color = ramp2[((int) part->ramp) % sizeof (ramp2)];
break;
case pt_phys_color_ramp3:
part->color = ramp3[((int) part->ramp) % sizeof (ramp3)];
break;
case pt_phys_alpha_ramp:
parm = (++op)->parm;
part->alpha = (parm - part->ramp) / parm;
break;
case pt_phys_explode_vel:
parm = (++op)->parm;
VectorMultAdd (part->vel, vr_data.frametime * parm, part->vel,
part->vel);
break;
case pt_phys_damp_vel:
parm = (++op)->parm;
part->vel[0] -= part->vel[0] * vr_data.frametime * parm;
part->vel[1] -= part->vel[1] * vr_data.frametime * parm;
break;
case pt_phys_grow_scale:
parm = (++op)->parm;
part->scale += vr_data.frametime * parm;
break;
case pt_phys_shrink_scale:
parm = (++op)->parm;
part->scale -= vr_data.frametime * parm;
if (part->scale <= 0.0) {
part->die = -1;
return;
}
break;
case pt_phys_custom:
// handled above
break;
}
}
}
static pt_phys_opcode_t *
part_find_opcode (const char *name)
{
pt_phys_opcode_t *op;
for (op = part_phys_opcodes; op->name; op++) {
if (strcmp (op->name, name) == 0)
return op;
}
return 0;
}
static pt_phys_func_t *
part_find_function (const char *name)
{
pt_phys_func_t *func;
//FIXME is a hash table worth it?
for (func = phys_funcs; func - phys_funcs < num_phys_funcs; func++) {
if (strcmp (func->name, name) == 0)
return func;
}
return 0;
}
static void
part_phys_explode (particle_t *part)
part_add_op (dstring_t *phys, int op)
{
if (add_ramp (part, 10.0, 8))
return;
add_vel (part);
part->color = ramp1[(int) part->ramp];
VectorMultAdd (part->vel, vr_data.frametime * 4.0, part->vel, part->vel);
add_grav (part);
int offs = phys->size;
phys->size += sizeof (pt_phys_op_t);
dstring_adjust (phys);
((pt_phys_op_t *) (phys->str + offs))->op = op;
}
static void
part_phys_explode2 (particle_t *part)
part_add_parm (dstring_t *phys, float parm)
{
if (add_ramp (part, 15.0, 8))
return;
add_vel (part);
part->color = ramp2[(int) part->ramp];
VectorMultAdd (part->vel, vr_data.frametime, part->vel, part->vel);
add_grav (part);
int offs = phys->size;
phys->size += sizeof (pt_phys_op_t);
dstring_adjust (phys);
((pt_phys_op_t *) (phys->str + offs))->parm = parm;
}
static pt_phys_script_t *
new_phys_script (void)
{
pt_phys_script_t *phys_script;
ALLOC (16, pt_phys_script_t, phys_script, phys_script);
return phys_script;
}
static void
part_phys_blob (particle_t *part)
free_phys_script (pt_phys_script_t *phys_script)
{
add_vel (part);
VectorMultAdd (part->vel, vr_data.frametime * 4.0, part->vel, part->vel);
add_grav (part);
FREE (phys_script, phys_script);
}
static const char *
part_script_get_key (const void *_s, void *unused)
{
const pt_phys_script_t *s = (const pt_phys_script_t *) _s;
return s->name;
}
static void
part_phys_blob2 (particle_t *part)
part_script_free (void *_s, void *unused)
{
add_vel (part);
part->vel[0] -= part->vel[0] * vr_data.frametime * 4.0;
part->vel[1] -= part->vel[1] * vr_data.frametime * 4.0;
add_grav (part);
pt_phys_script_t *s = (pt_phys_script_t *) _s;
free (s->name);
free (s->script);
free_phys_script (s);
}
static void
part_phys_smoke (particle_t *part)
qboolean
R_CompileParticlePhysics (const char *name, const char *code)
{
if (fade_alpha (part, 0.4))
return;
add_vel (part);
part->scale += vr_data.frametime * 4.0;
//sub_slowgrav (part);
cbuf_args_t *args = Cbuf_ArgsNew ();
script_t *script = Script_New ();
pt_phys_opcode_t *opcode;
pt_phys_script_t *phys;
pt_phys_func_t *func;
dstring_t *phys_build = dstring_new ();
int i;
qboolean ret = false;
if (!phys_scripts) {
phys_scripts = Hash_NewTable (61, part_script_get_key,
part_script_free, 0);
}
Script_Start (script, "name", code);
while (Script_GetToken (script, 1)) {
args->argc = 0;
Cbuf_ArgsAdd (args, Script_Token (script));
while (Script_TokenAvailable (script, 0)) {
Script_GetToken (script, 0);
Cbuf_ArgsAdd (args, Script_Token (script));
}
Sys_Printf ("%s:%d: %s\n", name, script->line, args->argv[0]->str);
if ((func = part_find_function (args->argv[0]->str))) {
if (args->argc > 1) {
Sys_Printf ("%s:%d: warning: ignoring extra args\n",
name, script->line);
}
part_add_op (phys_build, pt_phys_custom + (func - phys_funcs));
} else if ((opcode = part_find_opcode (args->argv[0]->str))) {
part_add_op (phys_build, opcode->opcode);
if (args->argc - 1 > opcode->num_params) {
Sys_Printf ("%s:%d: warning: ignoring extra args\n",
name, script->line);
args->argc = opcode->num_params + 1;
}
for (i = 1; i < args->argc; i++) {
char *end;
float parm = strtof (args->argv[i]->str, &end);
if (end == args->argv[i]->str) {
Sys_Printf ("%s:%d: warning: bad float\n",
name, script->line);
} else if (*end) {
Sys_Printf ("%s:%d: warning: ignoring extra chars\n",
name, script->line);
}
part_add_parm (phys_build, parm);
}
if (args->argc - 1 > opcode->num_params) {
Sys_Printf ("%s:%d: warning: setting parms %d+ to zero\n",
name, script->line, args->argc - 1);
for (i--; i < opcode->num_params; i++)
part_add_parm (phys_build, 0);
}
} else {
Sys_Printf ("%s:%d: warning: unknown opcode/function: %s\n",
name, script->line, args->argv[0]->str);
}
}
if (phys_build->size) {
part_add_op (phys_build, pt_phys_done);
phys = new_phys_script ();
phys->name = strdup (name);
phys->script = (pt_phys_op_t *) dstring_freeze (phys_build);
Hash_Add (phys_scripts, phys);
ret = true;
} else {
dstring_delete (phys_build);
}
Script_Delete (script);
Cbuf_ArgsDelete (args);
return ret;
}
static void
part_phys_smokecloud (particle_t *part)
const pt_phys_op_t *
R_ParticlePhysics (const char *type)
{
if (fade_alpha (part, 0.55))
return;
add_vel (part);
part->scale += vr_data.frametime * 50.0;
sub_slowgrav (part);
pt_phys_script_t *phys;
if (!phys_scripts)
return 0;
if ((phys = Hash_Find (phys_scripts, type)))
return phys->script;
return 0;
}
static void
part_phys_bloodcloud (particle_t *part)
qboolean
R_AddParticlePhysicsFunction (const char *name,
qboolean (*func) (particle_t *part, void *data),
void *data)
{
if (fade_alpha (part, 0.25))
return;
add_vel (part);
part->scale += vr_data.frametime * 4.0;
add_grav (part);
int i;
for (i = 0; i < num_phys_funcs; i++) {
if (strcmp (name, phys_funcs[i].name) == 0)
return false;
}
if (num_phys_funcs == max_phys_funcs) {
max_phys_funcs += 16;
phys_funcs = realloc (phys_funcs,
max_phys_funcs * sizeof (pt_phys_func_t));
if (!phys_funcs) {
Sys_Error ("R_AddParticlePhysicsFunction: out of memory");
}
}
phys_funcs[num_phys_funcs].name = strdup (name);
phys_funcs[num_phys_funcs].func = func;
phys_funcs[num_phys_funcs].data = data;
return true;
}
static void
part_phys_fallfade (particle_t *part)
void
R_LoadParticles (void)
{
if (fade_alpha (part, 1.0))
return;
add_vel (part);
add_fastgrav (part);
}
segtext_t *text;
segchunk_t *chunk;
static void
part_phys_fallfadespark (particle_t *part)
{
if (add_ramp (part, 15.0, 8))
return;
if (fade_alpha (part, 1.0))
return;
part->color = ramp1[(int) part->ramp];
add_vel (part);
add_fastgrav (part);
}
static void
part_phys_flame (particle_t *part)
{
if (fade_alpha (part, 0.125))
return;
add_vel (part);
part->scale -= vr_data.frametime * 2.0;
}
static pt_phys_func part_phys[] = {
part_phys_static, // pt_static
part_phys_grav, // pt_grav
part_phys_grav, // pt_slowgrav
part_phys_fire, // pt_fire
part_phys_explode, // pt_explode
part_phys_explode2, // pt_explode2
part_phys_blob, // pt_blob
part_phys_blob2, // pt_blob2
part_phys_smoke, // pt_smoke
part_phys_smokecloud, // pt_smokecloud
part_phys_bloodcloud, // pt_bloodcloud
part_phys_static, // pt_fadespark
part_phys_static, // pt_fadespark2
part_phys_fallfade, // pt_fallfade
part_phys_fallfadespark,// pt_fallfadespark
part_phys_flame, // pt_flame
};
pt_phys_func
R_ParticlePhysics (ptype_t type)
{
if (type > pt_flame)
Sys_Error ("R_ParticlePhysics: invalid particle type");
return part_phys[type];
text = Segtext_new (particle_types);
for (chunk = text->chunk_list; chunk; chunk = chunk->next) {
if (chunk->tag) {
Sys_Printf ("compiling %s\n", chunk->tag);
R_CompileParticlePhysics (chunk->tag, chunk->text);
}
}
}

View file

@ -128,6 +128,7 @@ sw_R_Init (void)
#ifdef USE_INTEL_ASM
R_InitVars ();
#endif
R_InitParticles ();
R_InitTurb ();

View file

@ -56,6 +56,7 @@ static mtstate_t mt; // private PRNG state
void
R_InitParticles (void)
{
R_LoadParticles ();
mtwist_seed (&mt, 0xdeadbeef);
}
@ -119,8 +120,7 @@ R_ReadPointFile_f (void)
p->die = 99999;
p->color = (-c) & 15;
p->type = pt_static;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_static");
VectorZero (p->vel);
VectorCopy (org, p->org);
}
@ -150,10 +150,9 @@ R_ParticleExplosion_QF (const vec3_t org)
p->color = ramp1[0];
p->ramp = mtwist_rand (&mt) & 3;
if (i & 1)
p->type = pt_explode;
p->physics = R_ParticlePhysics ("pt_explode");
else
p->type = pt_explode2;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_explode2");
for (j = 0; j < 3; j++) {
p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16);
p->vel[j] = (mtwist_rand (&mt) % 512) - 256;
@ -180,8 +179,7 @@ R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength)
p->color = colorStart + (colorMod % colorLength);
colorMod++;
p->type = pt_blob;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_blob");
for (j=0 ; j<3 ; j++) {
p->org[j] = org[j] + ((mtwist_rand (&mt)%32)-16);
p->vel[j] = (mtwist_rand (&mt)%512)-256;
@ -209,13 +207,12 @@ R_BlobExplosion_QF (const vec3_t org)
p->die = vr_data.realtime + 1 + (mtwist_rand (&mt) & 8) * 0.05;
if (i & 1) {
p->type = pt_blob;
p->color = 66 + mtwist_rand (&mt) % 6;
p->physics = R_ParticlePhysics ("pt_blob");
} else {
p->type = pt_blob2;
p->color = 150 + mtwist_rand (&mt) % 6;
p->physics = R_ParticlePhysics ("pt_blob2");
}
p->phys = R_ParticlePhysics (p->type);
for (j = 0; j < 3; j++) {
p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16);
p->vel[j] = (mtwist_rand (&mt) % 512) - 256;
@ -243,8 +240,7 @@ R_RunParticleEffect_QF (const vec3_t org, const vec3_t dir, int color,
p->die = vr_data.realtime + 0.1 * (mtwist_rand (&mt) % 5);
p->color = (color & ~7) + (mtwist_rand (&mt) & 7);
p->type = pt_grav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_grav");
for (j = 0; j < 3; j++) {
p->org[j] = org[j] + ((mtwist_rand (&mt) & 15) - 8);
p->vel[j] = dir[j]; // + (mtwist_rand (&mt)%300)-150;
@ -317,8 +313,7 @@ R_LavaSplash_QF (const vec3_t org)
p->die = vr_data.realtime + 2 + (mtwist_rand (&mt) & 31) * 0.02;
p->color = 224 + (mtwist_rand (&mt) & 7);
p->type = pt_grav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_grav");
dir[0] = j * 8 + (mtwist_rand (&mt) & 7);
dir[1] = i * 8 + (mtwist_rand (&mt) & 7);
@ -357,8 +352,7 @@ R_TeleportSplash_QF (const vec3_t org)
p->die = vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 7) * 0.02;
p->color = 7 + (mtwist_rand (&mt) & 7);
p->type = pt_grav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_grav");
dir[0] = j * 8;
dir[1] = i * 8;
@ -403,8 +397,7 @@ R_DarkFieldParticles_ID (entity_t *ent)
p->die = vr_data.realtime + 0.2 + (rnd & 7) * 0.02;
p->color = 150 + mtwist_rand (&mt) % 6;
p->type = pt_slowgrav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_slowgrav");
dir[0] = j * 8;
dir[1] = i * 8;
dir[2] = k * 8;
@ -467,8 +460,7 @@ R_EntityParticles_ID (entity_t *ent)
p->die = vr_data.realtime + 0.01;
p->color = 0x6f;
p->type = pt_explode;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_explode");
p->org[0] = ent->origin[0] + r_avertexnormals[i][0] * dist +
forward[0] * beamlength;
@ -509,8 +501,7 @@ R_RocketTrail_QF (entity_t *ent)
p->die = vr_data.realtime + 2;
p->ramp = (mtwist_rand (&mt) & 3);
p->color = ramp3[(int) p->ramp];
p->type = pt_fire;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_fire");
for (j = 0; j < 3; j++)
p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3);
@ -548,8 +539,7 @@ R_GrenadeTrail_QF (entity_t *ent)
p->die = vr_data.realtime + 2;
p->ramp = (mtwist_rand (&mt) & 3) + 2;
p->color = ramp3[(int) p->ramp];
p->type = pt_fire;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_fire");
for (j = 0; j < 3; j++)
p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3);
@ -585,8 +575,7 @@ R_BloodTrail_QF (entity_t *ent)
VectorZero (p->vel);
p->die = vr_data.realtime + 2;
p->type = pt_slowgrav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_slowgrav");
p->color = 67 + (mtwist_rand (&mt) & 3);
for (j = 0; j < 3; j++)
p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3);
@ -624,8 +613,7 @@ R_SlightBloodTrail_QF (entity_t *ent)
VectorZero (p->vel);
p->die = vr_data.realtime + 2;
p->type = pt_slowgrav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_slowgrav");
p->color = 67 + (mtwist_rand (&mt) & 3);
for (j = 0; j < 3; j++)
p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3);
@ -661,8 +649,7 @@ R_WizTrail_QF (entity_t *ent)
active_particles = p;
p->die = vr_data.realtime + 0.5;
p->type = pt_static;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_static");
p->color = 52 + ((tracercount & 4) << 1);
tracercount++;
@ -708,8 +695,7 @@ R_FlameTrail_QF (entity_t *ent)
active_particles = p;
p->die = vr_data.realtime + 0.5;
p->type = pt_static;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_static");
p->color = 230 + ((tracercount & 4) << 1);
tracercount++;
@ -756,8 +742,7 @@ R_VoorTrail_QF (entity_t *ent)
VectorZero (p->vel);
p->die = vr_data.realtime + 0.3;
p->type = pt_static;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_static");
p->color = 9 * 16 + 8 + (mtwist_rand (&mt) & 3);
for (j = 0; j < 3; j++)
p->org[j] = old_origin[j] + ((mtwist_rand (&mt) & 15) - 8);
@ -787,7 +772,7 @@ R_DrawParticles (void)
D_DrawParticle (p);
p->phys (p);
R_RunParticlePhysics (p);
}
}
}
@ -877,7 +862,7 @@ R_Particles_Init_Cvars (void)
}
void
R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale,
R_Particle_New (const char *type, int texnum, const vec3_t org, float scale,
const vec3_t vel, float die, int color, float alpha, float ramp)
{
particle_t *p;
@ -895,16 +880,15 @@ R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale,
p->scale = scale;
p->alpha = alpha;
VectorCopy (vel, p->vel);
p->type = type;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics (type);
p->die = die;
p->ramp = ramp;
}
void
R_Particle_NewRandom (ptype_t type, int texnum, const vec3_t org, int org_fuzz,
float scale, int vel_fuzz, float die, int color,
float alpha, float ramp)
R_Particle_NewRandom (const char *type, int texnum, const vec3_t org,
int org_fuzz, float scale, int vel_fuzz, float die,
int color, float alpha, float ramp)
{
float o_fuzz = org_fuzz, v_fuzz = vel_fuzz;
int rnd;

View file

@ -150,6 +150,7 @@ sw32_R_Init (void)
sw32_Draw_Init ();
SCR_Init ();
R_InitParticles ();
sw32_R_InitTurb ();
Cmd_AddCommand ("timerefresh", sw32_R_TimeRefresh_f, "Tests the current "

View file

@ -60,6 +60,7 @@ static mtstate_t mt; // private PRNG state
void
sw32_R_InitParticles (void)
{
R_LoadParticles ();
mtwist_seed (&mt, 0xdeadbeef);
}
@ -124,8 +125,7 @@ sw32_R_ReadPointFile_f (void)
p->die = 99999;
p->color = (-c) & 15;
p->type = pt_static;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_static");
VectorZero (p->vel);
VectorCopy (org, p->org);
}
@ -155,19 +155,18 @@ R_ParticleExplosion_QF (const vec3_t org)
p->color = ramp1[0];
p->ramp = mtwist_rand (&mt) & 3;
if (i & 1) {
p->type = pt_explode;
p->physics = R_ParticlePhysics ("pt_explode");
for (j = 0; j < 3; j++) {
p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16);
p->vel[j] = (mtwist_rand (&mt) % 512) - 256;
}
} else {
p->type = pt_explode2;
p->physics = R_ParticlePhysics ("pt_explode2");
for (j = 0; j < 3; j++) {
p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16);
p->vel[j] = (mtwist_rand (&mt) % 512) - 256;
}
}
p->phys = R_ParticlePhysics (p->type);
}
}
@ -191,8 +190,7 @@ R_ParticleExplosion2_QF (const vec3_t org, int colorStart, int colorLength)
p->color = colorStart + (colorMod % colorLength);
colorMod++;
p->type = pt_blob;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_blob");
for (j=0 ; j<3 ; j++)
{
p->org[j] = org[j] + ((mtwist_rand (&mt)%32)-16);
@ -221,21 +219,20 @@ R_BlobExplosion_QF (const vec3_t org)
p->die = vr_data.realtime + 1 + (mtwist_rand (&mt) & 8) * 0.05;
if (i & 1) {
p->type = pt_blob;
p->physics = R_ParticlePhysics ("pt_blob");
p->color = 66 + mtwist_rand (&mt) % 6;
for (j = 0; j < 3; j++) {
p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16);
p->vel[j] = (mtwist_rand (&mt) % 512) - 256;
}
} else {
p->type = pt_blob2;
p->physics = R_ParticlePhysics ("pt_blob2");
p->color = 150 + mtwist_rand (&mt) % 6;
for (j = 0; j < 3; j++) {
p->org[j] = org[j] + ((mtwist_rand (&mt) % 32) - 16);
p->vel[j] = (mtwist_rand (&mt) % 512) - 256;
}
}
p->phys = R_ParticlePhysics (p->type);
}
}
@ -262,8 +259,7 @@ R_LavaSplash_QF (const vec3_t org)
p->die = vr_data.realtime + 2 + (mtwist_rand (&mt) & 31) * 0.02;
p->color = 224 + (mtwist_rand (&mt) & 7);
p->type = pt_grav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_grav");
dir[0] = j * 8 + (mtwist_rand (&mt) & 7);
dir[1] = i * 8 + (mtwist_rand (&mt) & 7);
@ -302,8 +298,7 @@ R_TeleportSplash_QF (const vec3_t org)
p->die = vr_data.realtime + 0.2 + (mtwist_rand (&mt) & 7) * 0.02;
p->color = 7 + (mtwist_rand (&mt) & 7);
p->type = pt_grav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_grav");
dir[0] = j * 8;
dir[1] = i * 8;
@ -347,8 +342,7 @@ R_DarkFieldParticles_ID (entity_t *ent)
p->die = vr_data.realtime + 0.2 + (rnd & 7) * 0.02;
p->color = 150 + mtwist_rand (&mt) % 6;
p->type = pt_slowgrav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_slowgrav");
dir[0] = j * 8;
dir[1] = i * 8;
@ -409,8 +403,7 @@ R_EntityParticles_ID (entity_t *ent)
p->die = vr_data.realtime + 0.01;
p->color = 0x6f;
p->type = pt_explode;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_explode");
p->org[0] = ent->origin[0] + r_avertexnormals[i][0] * dist +
forward[0] * beamlength;
@ -441,8 +434,7 @@ R_RunParticleEffect_QF (const vec3_t org, const vec3_t dir, int color,
p->die = vr_data.realtime + 0.1 * (mtwist_rand (&mt) % 5);
p->color = (color & ~7) + (mtwist_rand (&mt) & 7);
p->type = pt_slowgrav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_slowgrav");
for (j = 0; j < 3; j++) {
p->org[j] = org[j] + ((mtwist_rand (&mt) & 15) - 8);
p->vel[j] = dir[j]; // + (mtwist_rand (&mt)%300)-150;
@ -522,8 +514,7 @@ R_RocketTrail_QF (entity_t *ent)
p->die = vr_data.realtime + 2;
p->ramp = (mtwist_rand (&mt) & 3);
p->color = ramp3[(int) p->ramp];
p->type = pt_fire;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_fire");
for (j = 0; j < 3; j++)
p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3);
@ -561,8 +552,7 @@ R_GrenadeTrail_QF (entity_t *ent)
p->die = vr_data.realtime + 2;
p->ramp = (mtwist_rand (&mt) & 3) + 2;
p->color = ramp3[(int) p->ramp];
p->type = pt_fire;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_fire");
for (j = 0; j < 3; j++)
p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3);
@ -598,8 +588,7 @@ R_BloodTrail_QF (entity_t *ent)
VectorZero (p->vel);
p->die = vr_data.realtime + 2;
p->type = pt_slowgrav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_slowgrav");
p->color = 67 + (mtwist_rand (&mt) & 3);
for (j = 0; j < 3; j++)
p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3);
@ -637,8 +626,7 @@ R_SlightBloodTrail_QF (entity_t *ent)
VectorZero (p->vel);
p->die = vr_data.realtime + 2;
p->type = pt_slowgrav;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_slowgrav");
p->color = 67 + (mtwist_rand (&mt) & 3);
for (j = 0; j < 3; j++)
p->org[j] = old_origin[j] + ((mtwist_rand (&mt) % 6) - 3);
@ -674,8 +662,7 @@ R_WizTrail_QF (entity_t *ent)
active_particles = p;
p->die = vr_data.realtime + 0.5;
p->type = pt_static;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_static");
p->color = 52 + ((tracercount & 4) << 1);
tracercount++;
@ -721,8 +708,7 @@ R_FlameTrail_QF (entity_t *ent)
active_particles = p;
p->die = vr_data.realtime + 0.5;
p->type = pt_static;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_static");
p->color = 230 + ((tracercount & 4) << 1);
tracercount++;
@ -769,8 +755,7 @@ R_VoorTrail_QF (entity_t *ent)
VectorZero (p->vel);
p->die = vr_data.realtime + 0.3;
p->type = pt_static;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics ("pt_static");
p->color = 9 * 16 + 8 + (mtwist_rand (&mt) & 3);
for (j = 0; j < 3; j++)
p->org[j] = old_origin[j] + ((mtwist_rand (&mt) & 15) - 8);
@ -800,7 +785,7 @@ sw32_R_DrawParticles (void)
sw32_D_DrawParticle (p);
p->phys (p);
R_RunParticlePhysics (p);
}
}
}
@ -890,9 +875,9 @@ sw32_R_Particles_Init_Cvars (void)
}
void
sw32_R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale,
const vec3_t vel, float die, int color, float alpha,
float ramp)
sw32_R_Particle_New (const char *type, int texnum, const vec3_t org,
float scale, const vec3_t vel, float die, int color,
float alpha, float ramp)
{
particle_t *p;
@ -909,14 +894,13 @@ sw32_R_Particle_New (ptype_t type, int texnum, const vec3_t org, float scale,
p->scale = scale;
p->alpha = alpha;
VectorCopy (vel, p->vel);
p->type = type;
p->phys = R_ParticlePhysics (p->type);
p->physics = R_ParticlePhysics (type);
p->die = die;
p->ramp = ramp;
}
void
sw32_R_Particle_NewRandom (ptype_t type, int texnum, const vec3_t org,
sw32_R_Particle_NewRandom (const char *type, int texnum, const vec3_t org,
int org_fuzz, float scale, int vel_fuzz, float die,
int color, float alpha, float ramp)
{

View file

@ -114,6 +114,8 @@ vid_render_funcs_t gl_vid_render_funcs = {
gl_R_RenderView,
R_DecayLights,
gl_R_ViewChanged,
R_CompileParticlePhysics,
R_AddParticlePhysicsFunction,
gl_R_ClearParticles,
gl_R_InitParticles,
gl_SCR_ScreenShot_f,

View file

@ -114,6 +114,8 @@ vid_render_funcs_t glsl_vid_render_funcs = {
glsl_R_RenderView,
R_DecayLights,
glsl_R_ViewChanged,
R_CompileParticlePhysics,
R_AddParticlePhysicsFunction,
glsl_R_ClearParticles,
glsl_R_InitParticles,
glsl_SCR_ScreenShot_f,

View file

@ -107,6 +107,8 @@ vid_render_funcs_t sw_vid_render_funcs = {
R_RenderView,
R_DecayLights,
R_ViewChanged,
R_CompileParticlePhysics,
R_AddParticlePhysicsFunction,
R_ClearParticles,
R_InitParticles,
SCR_ScreenShot_f,

View file

@ -112,6 +112,8 @@ vid_render_funcs_t sw32_vid_render_funcs = {
sw32_R_RenderView,
R_DecayLights,
sw32_R_ViewChanged,
R_CompileParticlePhysics,
R_AddParticlePhysicsFunction,
sw32_R_ClearParticles,
sw32_R_InitParticles,
sw32_SCR_ScreenShot_f,

View file

@ -613,12 +613,12 @@ CL_EmitEntities (void)
dl->color[3] = 0.7;
}
VectorCopy (nearloc->loc, trueloc);
r_funcs->particles->R_Particle_New (pt_smokecloud, part_tex_smoke,
r_funcs->particles->R_Particle_New ("pt_smokecloud", part_tex_smoke,
trueloc, 2.0,
vec3_origin, 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,
r_funcs->particles->R_Particle_NewRandom ("pt_fallfade",
part_tex_dot, trueloc, 12,
0.7, 96, r_data->realtime + 5.0,
104 + (rand () & 7), 1.0, 0.0);