about summary refs log tree commit diff
path: root/src/game/client/components/particles.cpp
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-08-27 15:48:50 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-08-27 15:48:50 +0000
commitdfe499248f1b1236487156b28e4a535d7963fe35 (patch)
treea750b0f28cfd3f3e252602681412ac1adc6d29c7 /src/game/client/components/particles.cpp
parentd711dd190cac809a9bd278fba03ed974812bb863 (diff)
downloadzcatch-dfe499248f1b1236487156b28e4a535d7963fe35.tar.gz
zcatch-dfe499248f1b1236487156b28e4a535d7963fe35.zip
major commit. game client restructure. not complete, loads of stuff not working, but the structure is there
Diffstat (limited to 'src/game/client/components/particles.cpp')
-rw-r--r--src/game/client/components/particles.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/game/client/components/particles.cpp b/src/game/client/components/particles.cpp
new file mode 100644
index 00000000..0c449263
--- /dev/null
+++ b/src/game/client/components/particles.cpp
@@ -0,0 +1,155 @@
+#include <base/math.hpp>
+#include <game/generated/gc_data.hpp>
+#include <game/client/gc_render.hpp>
+#include "particles.hpp"
+
+PARTICLES::PARTICLES()
+{
+	on_reset();
+	render_trail.parts = this;
+	render_explosions.parts = this;
+	render_general.parts = this;
+}
+
+
+void PARTICLES::on_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_GROUPS; i++)
+		first_part[i] = -1;
+}
+
+void PARTICLES::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 PARTICLES::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_GROUPS; 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;
+			
+			// TODO: repair me
+			//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;
+				first_free = i;
+			}
+			
+			i = next;
+		}
+	}
+}
+
+void PARTICLES::on_render()
+{
+	static int64 lasttime = 0;
+	int64 t = time_get();
+	update((float)((t-lasttime)/(double)time_freq()));
+	lasttime = t;
+}
+
+void PARTICLES::render_group(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();
+}