yquake2remaster/src/client/cl_particles.c

244 lines
4.9 KiB
C
Raw Normal View History

/*
* Copyright (C) 1997-2001 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 the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* This file implements all generic particle stuff
*
* =======================================================================
*/
#include "header/client.h"
cparticle_t *active_particles, *free_particles;
cparticle_t particles[MAX_PARTICLES];
int cl_numparticles = MAX_PARTICLES;
void CL_ClearParticles (void) {
int i;
free_particles = &particles[0];
active_particles = NULL;
for (i=0 ; i<cl_numparticles ; i++)
particles[i].next = &particles[i+1];
particles[cl_numparticles-1].next = NULL;
}
void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count) {
int i, j;
cparticle_t *p;
float d;
for (i=0 ; i<count ; i++) {
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = cl.time;
p->color = color + (rand()&7);
d = rand()&31;
for (j=0 ; j<3 ; j++) {
p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
p->vel[j] = crand()*20;
}
p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY+0.2f;
p->alpha = 1.0;
p->alphavel = -1.0 / (0.5 + frand()*0.3);
}
}
void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count) {
int i, j;
cparticle_t *p;
float d;
float time;
time = (float)cl.time;
for (i=0 ; i<count ; i++) {
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = time;
p->color = color + (rand()&7);
d = rand()&7;
for (j=0 ; j<3 ; j++) {
p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
p->vel[j] = crand()*20;
}
p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY;
p->alpha = 1.0;
p->alphavel = -1.0f / (0.5f + frand()*0.3f);
}
}
void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count) {
int i, j;
cparticle_t *p;
float d;
float time;
time = (float)cl.time;
for (i=0 ; i<count ; i++) {
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = time;
p->color = color;
d = rand()&7;
for (j=0 ; j<3 ; j++) {
p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
p->vel[j] = crand()*20;
}
p->accel[0] = p->accel[1] = 0;
p->accel[2] = PARTICLE_GRAVITY;
p->alpha = 1.0;
p->alphavel = -1.0f / (0.5f + frand()*0.3f);
}
}
void CL_AddParticles (void) {
cparticle_t *p, *next;
float alpha;
float time, time2;
vec3_t org;
int color;
cparticle_t *active, *tail;
active = NULL;
tail = NULL;
for (p=active_particles ; p ; p=next) {
next = p->next;
if (p->alphavel != INSTANT_PARTICLE) {
time = (cl.time - p->time)*0.001;
alpha = p->alpha + time*p->alphavel;
if (alpha <= 0) {
/* faded out */
p->next = free_particles;
free_particles = p;
continue;
}
} else {
time = 0.0f;
alpha = p->alpha;
}
p->next = NULL;
if (!tail)
active = tail = p;
else {
tail->next = p;
tail = p;
}
if (alpha > 1.0f)
alpha = 1;
color = p->color;
time2 = time*time;
org[0] = p->org[0] + p->vel[0]*time + p->accel[0]*time2;
org[1] = p->org[1] + p->vel[1]*time + p->accel[1]*time2;
org[2] = p->org[2] + p->vel[2]*time + p->accel[2]*time2;
V_AddParticle (org, color, alpha);
if (p->alphavel == INSTANT_PARTICLE) {
p->alphavel = 0.0;
p->alpha = 0.0;
}
}
active_particles = active;
}
void CL_GenericParticleEffect (vec3_t org, vec3_t dir, int color, int count, int numcolors, int dirspread, float alphavel) {
int i, j;
cparticle_t *p;
float d;
float time;
time = (float)cl.time;
for (i=0 ; i<count ; i++) {
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = time;
if (numcolors > 1)
p->color = color + (rand() & numcolors);
else
p->color = color;
d = (float)(rand() & dirspread);
for (j=0 ; j<3 ; j++) {
p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
p->vel[j] = crand()*20;
}
p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY;
p->alpha = 1.0;
p->alphavel = -1.0f / (0.5f + frand()*alphavel);
}
}