about summary refs log tree commit diff
path: root/src/game/client/render_map.cpp
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-10-20 23:46:39 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-10-20 23:46:39 +0000
commitd15860e44f3cbe0c92add6acd24ace564442645d (patch)
treee0763557279c211b032b18d3b2773e4a073752cd /src/game/client/render_map.cpp
parentad9c1b0a22fb451f909d8f12510c560fa8889be2 (diff)
downloadzcatch-d15860e44f3cbe0c92add6acd24ace564442645d.tar.gz
zcatch-d15860e44f3cbe0c92add6acd24ace564442645d.zip
renamed gc_render* to render*
Diffstat (limited to 'src/game/client/render_map.cpp')
-rw-r--r--src/game/client/render_map.cpp274
1 files changed, 274 insertions, 0 deletions
diff --git a/src/game/client/render_map.cpp b/src/game/client/render_map.cpp
new file mode 100644
index 00000000..118a4d73
--- /dev/null
+++ b/src/game/client/render_map.cpp
@@ -0,0 +1,274 @@
+/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
+#include <math.h>
+#include <base/math.hpp>
+#include <engine/e_client_interface.h>
+
+#include "render.hpp"
+
+void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result)
+{
+	if(num_points == 0)
+	{
+		result[0] = 0;
+		result[1] = 0;
+		result[2] = 0;
+		result[3] = 0;
+		return;
+	}
+	
+	if(num_points == 1)
+	{
+		result[0] = fx2f(points[0].values[0]);
+		result[1] = fx2f(points[0].values[1]);
+		result[2] = fx2f(points[0].values[2]);
+		result[3] = fx2f(points[0].values[3]);
+		return;
+	}
+	
+	time = fmod(time, points[num_points-1].time/1000.0f)*1000.0f;
+	for(int i = 0; i < num_points-1; i++)
+	{
+		if(time >= points[i].time && time <= points[i+1].time)
+		{
+			float delta = points[i+1].time-points[i].time;
+			float a = (time-points[i].time)/delta;
+
+
+			if(points[i].curvetype == CURVETYPE_SMOOTH)
+				a = -2*a*a*a + 3*a*a; // second hermite basis
+			else if(points[i].curvetype == CURVETYPE_SLOW)
+				a = a*a*a;
+			else if(points[i].curvetype == CURVETYPE_FAST)
+			{
+				a = 1-a;
+				a = 1-a*a*a;
+			}
+			else if (points[i].curvetype == CURVETYPE_STEP)
+				a = 0;
+			else
+			{
+				// linear
+			}
+					
+			for(int c = 0; c < channels; c++)
+			{
+				float v0 = fx2f(points[i].values[c]);
+				float v1 = fx2f(points[i+1].values[c]);
+				result[c] = v0 + (v1-v0) * a;
+			}
+			
+			return;
+		}
+	}
+	
+	result[0] = fx2f(points[num_points-1].values[0]);
+	result[1] = fx2f(points[num_points-1].values[1]);
+	result[2] = fx2f(points[num_points-1].values[2]);
+	result[3] = fx2f(points[num_points-1].values[3]);
+	return;
+}
+
+
+static void rotate(POINT *center, POINT *point, float rotation)
+{
+	int x = point->x - center->x;
+	int y = point->y - center->y;
+	point->x = (int)(x * cosf(rotation) - y * sinf(rotation) + center->x);
+	point->y = (int)(x * sinf(rotation) + y * cosf(rotation) + center->y);
+}
+
+void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, int env, float *channels), int renderflags)
+{
+	gfx_quads_begin();
+	float conv = 1/255.0f;
+	for(int i = 0; i < num_quads; i++)
+	{
+		QUAD *q = &quads[i];
+		
+		float r=1, g=1, b=1, a=1;
+
+		if(q->color_env >= 0)
+		{
+			float channels[4];
+			eval(q->color_env_offset/1000.0f, q->color_env, channels);
+			r = channels[0];
+			g = channels[1];
+			b = channels[2];
+			a = channels[3];
+		}		
+		
+		bool opaque = false;
+		if(a < 0.01f || (q->colors[0].a < 0.01f && q->colors[1].a < 0.01f && q->colors[2].a < 0.01f && q->colors[3].a < 0.01f))
+			opaque = true;
+			
+		if(opaque && !(renderflags&LAYERRENDERFLAG_OPAQUE))
+			continue;
+		if(!opaque && !(renderflags&LAYERRENDERFLAG_TRANSPARENT))
+			continue;
+		
+		gfx_quads_setsubset_free(
+			fx2f(q->texcoords[0].x), fx2f(q->texcoords[0].y),
+			fx2f(q->texcoords[1].x), fx2f(q->texcoords[1].y),
+			fx2f(q->texcoords[2].x), fx2f(q->texcoords[2].y),
+			fx2f(q->texcoords[3].x), fx2f(q->texcoords[3].y)
+		);
+
+		float offset_x = 0;
+		float offset_y = 0;
+		float rot = 0;
+		
+		// TODO: fix this
+		if(q->pos_env >= 0)
+		{
+			float channels[4];
+			eval(q->pos_env_offset/1000.0f, q->pos_env, channels);
+			offset_x = channels[0];
+			offset_y = channels[1];
+			rot = channels[2]/360.0f*pi*2;
+		}
+		
+		
+		gfx_setcolorvertex(0, q->colors[0].r*conv*r, q->colors[0].g*conv*g, q->colors[0].b*conv*b, q->colors[0].a*conv*a);
+		gfx_setcolorvertex(1, q->colors[1].r*conv*r, q->colors[1].g*conv*g, q->colors[1].b*conv*b, q->colors[1].a*conv*a);
+		gfx_setcolorvertex(2, q->colors[2].r*conv*r, q->colors[2].g*conv*g, q->colors[2].b*conv*b, q->colors[2].a*conv*a);
+		gfx_setcolorvertex(3, q->colors[3].r*conv*r, q->colors[3].g*conv*g, q->colors[3].b*conv*b, q->colors[3].a*conv*a);
+
+		POINT *points = q->points;
+	
+		if(rot != 0)
+		{
+			static POINT rotated[4];
+			rotated[0] = q->points[0];
+			rotated[1] = q->points[1];
+			rotated[2] = q->points[2];
+			rotated[3] = q->points[3];
+			points = rotated;
+			
+			rotate(&q->points[4], &rotated[0], rot);
+			rotate(&q->points[4], &rotated[1], rot);
+			rotate(&q->points[4], &rotated[2], rot);
+			rotate(&q->points[4], &rotated[3], rot);
+		}
+		
+		gfx_quads_draw_freeform(
+			fx2f(points[0].x)+offset_x, fx2f(points[0].y)+offset_y,
+			fx2f(points[1].x)+offset_x, fx2f(points[1].y)+offset_y,
+			fx2f(points[2].x)+offset_x, fx2f(points[2].y)+offset_y,
+			fx2f(points[3].x)+offset_x, fx2f(points[3].y)+offset_y
+		);
+	}
+	gfx_quads_end();	
+}
+
+void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int renderflags)
+{
+	//gfx_texture_set(img_get(tmap->image));
+	float screen_x0, screen_y0, screen_x1, screen_y1;
+	gfx_getscreen(&screen_x0, &screen_y0, &screen_x1, &screen_y1);
+	//gfx_mapscreen(screen_x0-50, screen_y0-50, screen_x1+50, screen_y1+50);
+
+	// calculate the final pixelsize for the tiles	
+	float tile_pixelsize = 1024/32.0f;
+	float final_tilesize = scale/(screen_x1-screen_x0) * gfx_screenwidth();
+	float final_tilesize_scale = final_tilesize/tile_pixelsize;
+	
+	gfx_quads_begin();
+	gfx_setcolor(color.r, color.g, color.b, color.a);
+	
+	int starty = (int)(screen_y0/scale)-1;
+	int startx = (int)(screen_x0/scale)-1;
+	int endy = (int)(screen_y1/scale)+1;
+	int endx = (int)(screen_x1/scale)+1;
+	
+	// adjust the texture shift according to mipmap level
+	float texsize = 1024.0f;
+	float frac = (1.25f/texsize) * (1/final_tilesize_scale);
+	float nudge = (0.5f/texsize) * (1/final_tilesize_scale);
+
+	for(int y = starty; y < endy; y++)
+		for(int x = startx; x < endx; x++)
+		{
+			int mx = x;
+			int my = y;
+			
+			if(renderflags&TILERENDERFLAG_EXTEND)
+			{
+				if(mx<0)
+					mx = 0;
+				if(mx>=w)
+					mx = w-1;
+				if(my<0)
+					my = 0;
+				if(my>=h)
+					my = h-1;
+			}
+			else
+			{
+				if(mx<0)
+					continue; // mx = 0;
+				if(mx>=w)
+					continue; // mx = w-1;
+				if(my<0)
+					continue; // my = 0;
+				if(my>=h)
+					continue; // my = h-1;
+			}
+			
+			int c = mx + my*w;
+				
+			unsigned char index = tiles[c].index;
+			if(index)
+			{
+				unsigned char flags = tiles[c].flags;
+				
+				bool render = false;
+				if(flags&TILEFLAG_OPAQUE)
+				{
+					if(renderflags&LAYERRENDERFLAG_OPAQUE)
+						render = true;
+				}
+				else
+				{
+					if(renderflags&LAYERRENDERFLAG_TRANSPARENT)
+						render = true;
+				}
+				
+				if(render)
+				{
+					
+					int tx = index%16;
+					int ty = index/16;
+					int px0 = tx*(1024/16);
+					int py0 = ty*(1024/16);
+					int px1 = (tx+1)*(1024/16)-1;
+					int py1 = (ty+1)*(1024/16)-1;
+					
+					float u0 = nudge + px0/texsize+frac;
+					float v0 = nudge + py0/texsize+frac;
+					float u1 = nudge + px1/texsize-frac;
+					float v1 = nudge + py1/texsize-frac;
+					
+					if(flags&TILEFLAG_VFLIP)
+					{
+						float tmp = u0;
+						u0 = u1;
+						u1 = tmp;
+					}
+
+					if(flags&TILEFLAG_HFLIP)
+					{
+						float tmp = v0;
+						v0 = v1;
+						v1 = tmp;
+					}
+					
+					gfx_quads_setsubset(u0,v0,u1,v1);
+					gfx_quads_drawTL(x*scale, y*scale, scale, scale);
+				}
+			}
+			x += tiles[c].skip;
+		}
+	
+	gfx_quads_end();
+	gfx_mapscreen(screen_x0, screen_y0, screen_x1, screen_y1);
+}