diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-01-29 21:39:41 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-01-29 21:39:41 +0000 |
| commit | 7bc733dc10f3d01985021b7b5d6ae140dd5af6f1 (patch) | |
| tree | c9b0fcd8d128ec9abd40c10dfe4fcf245650a870 /src/game/client/gc_particles.cpp | |
| parent | 0dab7db963e2706182ea120c98f746f5e265c14c (diff) | |
| download | zcatch-7bc733dc10f3d01985021b7b5d6ae140dd5af6f1.tar.gz zcatch-7bc733dc10f3d01985021b7b5d6ae140dd5af6f1.zip | |
large update. cleaned up some code. added new effects for almost everything
Diffstat (limited to 'src/game/client/gc_particles.cpp')
| -rw-r--r-- | src/game/client/gc_particles.cpp | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/src/game/client/gc_particles.cpp b/src/game/client/gc_particles.cpp new file mode 100644 index 00000000..bdeb26fd --- /dev/null +++ b/src/game/client/gc_particles.cpp @@ -0,0 +1,146 @@ +#include <engine/e_client_interface.h> +#include "gc_client.h" +#include "../generated/gc_data.h" + +// NOTE: the way the particle system works isn't very cache friendly + +enum +{ + MAX_PARTICLES=1024*8, +}; + +static particle particles[MAX_PARTICLES]; +static int first_free = -1; +static int first_part[NUM_PARTGROUPS] = {-1}; + +void particle_reset() +{ + // reset particles + for(int i = 0; i < MAX_PARTICLES; i++) + { + particles[i].prev_part = i-1; + particles[i].next_part = i+1; + } + + particles[0].prev_part = 0; + particles[MAX_PARTICLES-1].next_part = -1; + first_free = 0; + + for(int i = 0; i < NUM_PARTGROUPS; i++) + first_part[i] = -1; +} + + +void particle_add(int group, particle *part) +{ + if (first_free == -1) + return; + + // remove from the free list + int id = first_free; + first_free = particles[id].next_part; + particles[first_free].prev_part = -1; + + // copy data + particles[id] = *part; + + // insert to the group list + particles[id].prev_part = -1; + particles[id].next_part = first_part[group]; + if(first_part[group] != -1) + particles[first_part[group]].prev_part = id; + first_part[group] = id; + + // set some parameters + particles[id].life = 0; +} + +void particle_update(float time_passed) +{ + static float friction_fraction = 0; + friction_fraction += time_passed; + + if(friction_fraction > 2.0f) // safty messure + friction_fraction = 0; + + int friction_count = 0; + while(friction_fraction > 0.05f) + { + friction_count++; + friction_fraction -= 0.05f; + } + + for(int g = 0; g < NUM_PARTGROUPS; g++) + { + int i = first_part[g]; + while(i != -1) + { + int next = particles[i].next_part; + particles[i].vel += flow_get(particles[i].pos)*time_passed * particles[i].flow_affected; + particles[i].vel.y += particles[i].gravity*time_passed; + + for(int f = 0; f < friction_count; f++) // apply friction + particles[i].vel *= particles[i].friction; + + // move the point + vec2 vel = particles[i].vel*time_passed; + move_point(&particles[i].pos, &vel, 0.1f+0.9f*frandom(), NULL); + particles[i].vel = vel* (1.0f/time_passed); + + particles[i].life += time_passed; + particles[i].rot += time_passed * particles[i].rotspeed; + + // check particle death + if(particles[i].life > particles[i].life_span) + { + // remove it from the group list + if(particles[i].prev_part != -1) + particles[particles[i].prev_part].next_part = particles[i].next_part; + else + first_part[g] = particles[i].next_part; + + if(particles[i].next_part != -1) + particles[particles[i].next_part].prev_part = particles[i].prev_part; + + // insert to the free list + if(first_free != -1) + particles[first_free].prev_part = i; + particles[i].prev_part = -1; + particles[i].next_part = first_free; + } + + i = next; + } + } +} + +void particle_render(int group) +{ + gfx_blend_normal(); + //gfx_blend_additive(); + gfx_texture_set(data->images[IMAGE_PARTICLES].id); + gfx_quads_begin(); + + int i = first_part[group]; + while(i != -1) + { + select_sprite(particles[i].spr); + float a = particles[i].life / particles[i].life_span; + vec2 p = particles[i].pos; + float size = mix(particles[i].start_size, particles[i].end_size, a); + + gfx_quads_setrotation(particles[i].rot); + + gfx_setcolor( + particles[i].color.r, + particles[i].color.g, + particles[i].color.b, + particles[i].color.a); // pow(a, 0.75f) * + + gfx_quads_draw(p.x, p.y, size, size); + + i = particles[i].next_part; + } + gfx_quads_end(); + gfx_blend_normal(); +} |