yquake2remaster/src/client/cl_particles.c
2012-07-22 15:34:45 +02:00

291 lines
5.1 KiB
C

/*
* 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 + (randk() & 7);
d = randk() & 31;
for (j = 0; j < 3; j++)
{
p->org[j] = org[j] + ((randk() & 7) - 4) + d * dir[j];
p->vel[j] = crandk() * 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 + frandk() * 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 + (randk() & 7);
d = randk() & 7;
for (j = 0; j < 3; j++)
{
p->org[j] = org[j] + ((randk() & 7) - 4) + d * dir[j];
p->vel[j] = crandk() * 20;
}
p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY;
p->alpha = 1.0;
p->alphavel = -1.0f / (0.5f + frandk() * 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 = randk() & 7;
for (j = 0; j < 3; j++)
{
p->org[j] = org[j] + ((randk() & 7) - 4) + d * dir[j];
p->vel[j] = crandk() * 20;
}
p->accel[0] = p->accel[1] = 0;
p->accel[2] = PARTICLE_GRAVITY;
p->alpha = 1.0;
p->alphavel = -1.0f / (0.5f + frandk() * 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 + (randk() & numcolors);
}
else
{
p->color = color;
}
d = (float)(randk() & dirspread);
for (j = 0; j < 3; j++)
{
p->org[j] = org[j] + ((randk() & 7) - 4) + d * dir[j];
p->vel[j] = crandk() * 20;
}
p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY;
p->alpha = 1.0;
p->alphavel = -1.0f / (0.5f + frandk() * alphavel);
}
}