about summary refs log tree commit diff
path: root/src/editor
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-01-12 15:07:57 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-01-12 15:07:57 +0000
commit99f0a47d6b03b005d0a7dae064cb6eb7cb4f60b5 (patch)
tree6c453bff72668da6cc6f6e28621356004a06d441 /src/editor
parent2aba180f8c1bfa2680b1f660148de1dc82b03298 (diff)
downloadzcatch-99f0a47d6b03b005d0a7dae064cb6eb7cb4f60b5.tar.gz
zcatch-99f0a47d6b03b005d0a7dae064cb6eb7cb4f60b5.zip
first round of code cleanup
Diffstat (limited to 'src/editor')
-rwxr-xr-xsrc/editor/array.h238
-rw-r--r--src/editor/ed_layer_game.cpp20
-rw-r--r--src/editor/ed_layer_quads.cpp361
-rw-r--r--src/editor/ed_layer_tiles.cpp294
-rw-r--r--src/editor/editor.cpp2618
-rw-r--r--src/editor/editor.hpp568
6 files changed, 0 insertions, 4099 deletions
diff --git a/src/editor/array.h b/src/editor/array.h
deleted file mode 100755
index fe9f2739..00000000
--- a/src/editor/array.h
+++ /dev/null
@@ -1,238 +0,0 @@
-

-template <class T>

-class array

-{

-	// 

-	//

-	void init()

-	{

-		list = 0;

-		clear();

-	}

-

-public:

-	array()

-	{

-		init();

-	}

-	

-	//

-	array(const array &other)

-	{

-		init();

-		setsize(other.len());

-		for(int i = 0; i < len(); i++)

-			(*this)[i] = other[i];

-	}

-

-

-	// 

-	//

-	virtual ~array()

-	{

-		delete [] list;

-		list = 0;

-	}

-

-	//

-	//

-	void deleteall()

-	{

-		for(int i = 0; i < len(); i++)

-			delete list[i];

-

-		clear();

-	}

-

-

-	//

-	//

-	void clear()

-	{

-		delete [] list;

-		

-		list_size = 1;

-		list = new T[1];

-		num_elements = 0;

-	}

-

-	int find(T val)

-	{

-		for(int i = 0; i < len(); i++)

-			if((*this)[i] == val)

-				return i;

-		return -1;

-	}

-

-	bool exist(T val)

-	{

-		return find(val) != -1;

-	}

-

-	//

-	// returns the number of elements in the list

-	//

-	int len() const

-	{

-		return num_elements;

-	}

-

-	//

-	// This doesn't conserve the order in the list. Be careful

-	//

-	void removebyindexfast(int index)

-	{

-		//ASSUME(_Pos >= 0 && _Pos < num_elements);

-		list[index] = list[num_elements-1];

-		setsize(len()-1);

-	}

-

-	void removefast(const T& _Elem)

-	{

-		for(int i = 0; i < len(); i++)

-			if(list[i] == _Elem)

-			{

-				removebyindexfast(i);

-				return;

-			}

-	}

-

-	//

-	//

-	void removebyindex(int index)

-	{

-		//ASSUME(_Pos >= 0 && _Pos < num_elements);

-

-		for(int i = index+1; i < num_elements; i++)

-			list[i-1] = list[i];

-		

-		setsize(len()-1);

-	}

-

-	void insert(int index, const T& element)

-	{

-		int some_len = len();

-		if (index < some_len)

-			setsize(some_len+1);

-		else

-			setsize(index + 1);

-

-		for(int i = num_elements-2; i >= index; i--)

-			list[i+1] = list[i];

-

-		list[index] = element;

-	}

-

-	bool remove(const T& element)

-	{

-		for(int i = 0; i < len(); i++)

-			if(list[i] == element)

-			{

-				removebyindex(i);

-				return true;

-			}

-		return false;

-	}

-

-	// 

-	//

-	int add(const T& element)

-	{

-		//if(num_elements == list_size)

-		setsize(len()+1);

-		list[num_elements-1] = element;

-		return num_elements-1;

-	}

-

-	// 

-	//

-	int add(const T& elem, int index)

-	{

-		setsize(len()+1);

-		

-		for(int i = num_elements-1; i > index; i--)

-			list[i] = list[i-1];

-

-		list[index] = elem;

-		

-		//num_elements++;

-		return num_elements-1;

-	}

-

-	// 

-	//

-	T& operator[] (int index)

-	{

-		return list[index];

-	}

-

-	const T& operator[] (int index) const

-	{

-		return list[index];

-	}

-

-	//

-	//

-	T *getptr()

-	{

-		return list;

-	}

-

-	const T *getptr() const

-	{

-		return list;

-	}

-

-	//

-	//

-	//

-	void setsize(int new_len)

-	{

-		if (list_size < new_len)

-			allocsize(new_len);

-		num_elements = new_len;

-	}

-

-	// removes unnessasary data, returns how many bytes was earned

-	int optimize()

-	{

-		int Before = memoryusage();

-		setsize(num_elements);

-		return Before - memoryusage();

-	}

-

-	// returns how much memory this dynamic array is using

-	int memoryusage()

-	{

-		return sizeof(array) + sizeof(T)*list_size;

-	}

-

-	//

-	array &operator = (const array &other)

-	{

-		setsize(other.len());

-		for(int i = 0; i < len(); i++)

-			(*this)[i] = other[i];

-		return *this;

-	}		

-private:

-	void allocsize(int new_len)

-	{

-		list_size = new_len;

-		T *new_list = new T[list_size];

-		

-		long end = num_elements < list_size ? num_elements : list_size;

-		for(int i = 0; i < end; i++)

-			new_list[i] = list[i];

-		

-		delete [] list;

-		list = 0;

-		num_elements = num_elements < list_size ? num_elements : list_size;

-		list = new_list;

-	}

-

-	T *list;

-	long list_size;

-	long num_elements;

-};

-

diff --git a/src/editor/ed_layer_game.cpp b/src/editor/ed_layer_game.cpp
deleted file mode 100644
index 0e002559..00000000
--- a/src/editor/ed_layer_game.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <game/client/gc_mapres_tilemap.h>
-#include "editor.hpp"
-
-
-LAYER_GAME::LAYER_GAME(int w, int h)
-: LAYER_TILES(w, h)
-{
-	type_name = "Game";
-	game = 1;
-}
-
-LAYER_GAME::~LAYER_GAME()
-{
-}
-
-void LAYER_GAME::render_properties(RECT *toolbox)
-{
-	LAYER_TILES::render_properties(toolbox);
-	image = -1;
-}
diff --git a/src/editor/ed_layer_quads.cpp b/src/editor/ed_layer_quads.cpp
deleted file mode 100644
index d58a9e0f..00000000
--- a/src/editor/ed_layer_quads.cpp
+++ /dev/null
@@ -1,361 +0,0 @@
-#include "editor.hpp"
-#include <game/g_math.h>
-
-LAYER_QUADS::LAYER_QUADS()
-{
-	type = LAYERTYPE_QUADS;
-	type_name = "Quads";
-	image = -1;
-}
-
-LAYER_QUADS::~LAYER_QUADS()
-{
-}
-
-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);
-}
-
-static void render_quads(QUAD *quads, int num_quads)
-{
-	gfx_quads_begin();
-	float conv = 1/255.0f;
-	for(int i = 0; i < num_quads; i++)
-	{
-		QUAD *q = &quads[i];
-		
-		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 r=1, g=1, b=1, a=1;
-		float offset_x = 0;
-		float offset_y = 0;
-		float rot = 0;
-		
-		if(editor.animate)
-		{
-			if(q->pos_env >= 0 && q->pos_env < editor.map.envelopes.len())
-			{
-				ENVELOPE *e = editor.map.envelopes[q->pos_env];
-				float t = editor.animate_time+q->pos_env_offset/1000.0f;
-				offset_x = e->eval(t, 0);
-				offset_y = e->eval(t, 1);
-				rot = e->eval(t, 2);
-			}
-			
-			if(q->color_env >= 0 && q->color_env < editor.map.envelopes.len())
-			{
-				ENVELOPE *e = editor.map.envelopes[q->color_env];
-				float t = editor.animate_time+q->color_env_offset/1000.0f;
-				r = e->eval(t, 0);
-				g = e->eval(t, 1);
-				b = e->eval(t, 2);
-				a = e->eval(t, 3);
-			}
-		}
-		
-		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 LAYER_QUADS::render()
-{
-	gfx_texture_set(-1);
-	if(image >= 0 && image < editor.map.images.len())
-		gfx_texture_set(editor.map.images[image]->tex_id);
-		
-	render_quads(quads.getptr(), quads.len());
-}
-
-QUAD *LAYER_QUADS::new_quad()
-{
-	QUAD *q = &quads[quads.add(QUAD())];
-
-	q->pos_env = -1;
-	q->color_env = -1;
-	q->pos_env_offset = 0;
-	q->color_env_offset = 0;
-	int x = 0, y = 0;
-	q->points[0].x = x;
-	q->points[0].y = y;
-	q->points[1].x = x+64;
-	q->points[1].y = y;
-	q->points[2].x = x;
-	q->points[2].y = y+64;
-	q->points[3].x = x+64;
-	q->points[3].y = y+64;
-
-	q->points[4].x = x+32; // pivot
-	q->points[4].y = y+32;
-	
-	for(int i = 0; i < 5; i++)
-	{
-		q->points[i].x <<= 10;
-		q->points[i].y <<= 10;
-	}
-	
-
-	q->texcoords[0].x = 0;
-	q->texcoords[0].y = 0;
-	
-	q->texcoords[1].x = 1<<10;
-	q->texcoords[1].y = 0;
-	
-	q->texcoords[2].x = 0;
-	q->texcoords[2].y = 1<<10;
-	
-	q->texcoords[3].x = 1<<10;
-	q->texcoords[3].y = 1<<10;
-	
-	q->colors[0].r = 255; q->colors[0].g = 255; q->colors[0].b = 255; q->colors[0].a = 255;
-	q->colors[1].r = 255; q->colors[1].g = 255; q->colors[1].b = 255; q->colors[1].a = 255;
-	q->colors[2].r = 255; q->colors[2].g = 255; q->colors[2].b = 255; q->colors[2].a = 255;
-	q->colors[3].r = 255; q->colors[3].g = 255; q->colors[3].b = 255; q->colors[3].a = 255;
-
-	return q;
-}
-
-void LAYER_QUADS::brush_selecting(RECT rect)
-{
-	// draw selection rectangle
-	gfx_texture_set(-1);
-	gfx_lines_begin();
-	gfx_lines_draw(rect.x, rect.y, rect.x+rect.w, rect.y);
-	gfx_lines_draw(rect.x+rect.w, rect.y, rect.x+rect.w, rect.y+rect.h);
-	gfx_lines_draw(rect.x+rect.w, rect.y+rect.h, rect.x, rect.y+rect.h);
-	gfx_lines_draw(rect.x, rect.y+rect.h, rect.x, rect.y);
-	gfx_lines_end();
-}
-
-int LAYER_QUADS::brush_grab(LAYERGROUP *brush, RECT rect)
-{
-	// create new layers
-	LAYER_QUADS *grabbed = new LAYER_QUADS();
-	grabbed->image = image;
-	brush->add_layer(grabbed);
-	
-	//dbg_msg("", "%f %f %f %f", rect.x, rect.y, rect.w, rect.h);
-	for(int i = 0; i < quads.len(); i++)
-	{
-		QUAD *q = &quads[i];
-		float px = fx2f(q->points[4].x);
-		float py = fx2f(q->points[4].y);
-		
-		if(px > rect.x && px < rect.x+rect.w && py > rect.y && py < rect.y+rect.h)
-		{
-			dbg_msg("", "grabbed one");
-			QUAD n;
-			n = *q;
-			
-			for(int p = 0; p < 5; p++)
-			{
-				n.points[p].x -= f2fx(rect.x);
-				n.points[p].y -= f2fx(rect.y);
-			}
-			
-			grabbed->quads.add(n);
-		}
-	}
-	
-	return grabbed->quads.len()?1:0;
-}
-
-void LAYER_QUADS::brush_place(LAYER *brush, float wx, float wy)
-{
-	LAYER_QUADS *l = (LAYER_QUADS *)brush;
-	for(int i = 0; i < l->quads.len(); i++)
-	{
-		QUAD n = l->quads[i];
-		
-		for(int p = 0; p < 5; p++)
-		{
-			n.points[p].x += f2fx(wx);
-			n.points[p].y += f2fx(wy);
-		}
-			
-		quads.add(n);
-	}
-}
-
-void LAYER_QUADS::brush_flip_x()
-{
-}
-
-void LAYER_QUADS::brush_flip_y()
-{
-}
-
-void LAYER_QUADS::get_size(float *w, float *h)
-{
-	*w = 0; *h = 0;
-	
-	for(int i = 0; i < quads.len(); i++)
-	{
-		for(int p = 0; p < 5; p++)
-		{
-			*w = max(*w, fx2f(quads[i].points[p].x));
-			*h = max(*h, fx2f(quads[i].points[p].y));
-		}
-	}
-}
-
-extern int selected_points;
-
-void LAYER_QUADS::render_properties(RECT *toolbox)
-{
-	// layer props
-	if(editor.props == PROPS_LAYER)
-	{
-		enum
-		{
-			PROP_IMAGE=0,
-			NUM_PROPS,
-		};
-		
-		PROPERTY props[] = {
-			{"Image", image, PROPTYPE_INT_STEP, -1, 0},
-			{0},
-		};
-		
-		static int ids[NUM_PROPS] = {0};
-		int new_val = 0;
-		int prop = editor.do_properties(toolbox, props, ids, &new_val);		
-		
-		if(prop == PROP_IMAGE)
-		{
-			if(new_val >= 0)
-				image = new_val%editor.map.images.len();
-			else
-				image = -1;
-		}
-	}
-
-	// quad props
-	QUAD *quad = editor.get_selected_quad();
-	if(editor.props == PROPS_QUAD)
-	{
-		if(quad)
-		{
-			RECT slot;
-			ui_hsplit_t(toolbox, 15.0f, &slot, toolbox);
-			ui_do_label(&slot, "Quad Props", 12.0f, -1, -1);
-			
-			enum
-			{
-				PROP_POS_ENV=0,
-				PROP_POS_ENV_OFFSET,
-				PROP_COLOR_ENV,
-				PROP_COLOR_ENV_OFFSET,
-				NUM_PROPS,
-			};
-			
-			PROPERTY props[] = {
-				{"Pos. Env", quad->pos_env, PROPTYPE_INT_STEP, -1, editor.map.envelopes.len()},
-				{"Pos. TO", quad->pos_env_offset, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-				{"Color Env", quad->color_env, PROPTYPE_INT_STEP, -1, editor.map.envelopes.len()},
-				{"Color TO", quad->color_env_offset, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-				
-				{0},
-			};
-			
-			static int ids[NUM_PROPS] = {0};
-			int new_val = 0;
-			int prop = editor.do_properties(toolbox, props, ids, &new_val);		
-			
-			if(prop == PROP_POS_ENV) quad->pos_env = new_val;
-			if(prop == PROP_POS_ENV_OFFSET) quad->pos_env_offset = new_val;
-			if(prop == PROP_COLOR_ENV) quad->color_env = new_val;
-			if(prop == PROP_COLOR_ENV_OFFSET) quad->color_env_offset = new_val;
-		}
-	}
-	
-	// point props
-	if(editor.props == PROPS_QUAD_POINT && quad && selected_points)
-	{
-		RECT slot;
-		ui_hsplit_t(toolbox, 15.0f, &slot, toolbox);
-		ui_do_label(&slot, "Point Props", 14.0f, -1, -1);
-		
-		enum
-		{
-			PROP_COLOR=0,
-			NUM_PROPS,
-		};
-		
-		int color = 0;
-	
-		for(int v = 0; v < 4; v++)
-		{
-			if(selected_points&(1<<v))
-			{
-				color = 0;
-				color |= quad->colors[v].r<<24;
-				color |= quad->colors[v].g<<16;
-				color |= quad->colors[v].b<<8;
-				color |= quad->colors[v].a;
-			}
-		}
-		
-		
-		PROPERTY props[] = {
-			{"Color", color, PROPTYPE_COLOR, -1, editor.map.envelopes.len()},
-			{0},
-		};
-		
-		static int ids[NUM_PROPS] = {0};
-		int new_val = 0;
-		int prop = editor.do_properties(toolbox, props, ids, &new_val);		
-		if(prop == PROP_COLOR)
-		{
-			for(int v = 0; v < 4; v++)
-			{
-				if(selected_points&(1<<v))
-				{
-					color = 0;
-					quad->colors[v].r = (new_val>>24)&0xff;
-					quad->colors[v].g = (new_val>>16)&0xff;
-					quad->colors[v].b = (new_val>>8)&0xff;
-					quad->colors[v].a = new_val&0xff;
-				}
-			}
-		}
-	}	
-}
-
-
diff --git a/src/editor/ed_layer_tiles.cpp b/src/editor/ed_layer_tiles.cpp
deleted file mode 100644
index f697e56e..00000000
--- a/src/editor/ed_layer_tiles.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-#include <game/client/gc_mapres_tilemap.h>
-#include <game/g_math.h>
-#include "editor.hpp"
-
-static void render_tilemap(TILE *tiles, int w, int h, float scale)
-{
-			//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);
-
-	// 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();
-	
-	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(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;
-				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);
-			}
-		}
-	
-	gfx_quads_end();
-}
-
-LAYER_TILES::LAYER_TILES(int w, int h)
-{
-	type = LAYERTYPE_TILES;
-	type_name = "Tiles";
-	width = w;
-	height = h;
-	image = -1;
-	tex_id = -1;
-	game = 0;
-	
-	tiles = new TILE[width*height];
-	mem_zero(tiles, width*height*sizeof(TILE));
-}
-
-LAYER_TILES::~LAYER_TILES()
-{
-	delete [] tiles;
-}
-
-void LAYER_TILES::make_palette()
-{
-	for(int y = 0; y < height; y++)
-		for(int x = 0; x < width; x++)
-			tiles[y*width+x].index = y*16+x;
-}
-
-void LAYER_TILES::render()
-{
-	if(image >= 0 && image < editor.map.images.len())
-		tex_id = editor.map.images[image]->tex_id;
-	gfx_texture_set(tex_id);
-	render_tilemap(tiles, width, height, 32.0f);
-}
-
-int LAYER_TILES::convert_x(float x) const { return (int)(x/32.0f); }
-int LAYER_TILES::convert_y(float y) const { return (int)(y/32.0f); }
-
-void LAYER_TILES::convert(RECT rect, RECTi *out)
-{
-	out->x = convert_x(rect.x);
-	out->y = convert_y(rect.y);
-	out->w = convert_x(rect.x+rect.w+31) - out->x;
-	out->h = convert_y(rect.y+rect.h+31) - out->y;
-}
-
-void LAYER_TILES::snap(RECT *rect)
-{
-	RECTi out;
-	convert(*rect, &out);
-	rect->x = out.x*32.0f;
-	rect->y = out.y*32.0f;
-	rect->w = out.w*32.0f;
-	rect->h = out.h*32.0f;
-}
-
-void LAYER_TILES::clamp(RECTi *rect)
-{
-	if(rect->x < 0)
-	{
-		rect->w += rect->x;
-		rect->x = 0;
-	}
-		
-	if(rect->y < 0)
-	{
-		rect->h += rect->y;
-		rect->y = 0;
-	}
-	
-	if(rect->x+rect->w > width)
-		rect->w = width-rect->x;
-
-	if(rect->y+rect->h > height)
-		rect->h = height-rect->y;
-		
-	if(rect->h < 0)
-		rect->h = 0;
-	if(rect->w < 0)
-		rect->w = 0;
-}
-
-void LAYER_TILES::brush_selecting(RECT rect)
-{
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(1,1,1,0.4f);
-	snap(&rect);
-	gfx_quads_drawTL(rect.x, rect.y, rect.w, rect.h);
-	gfx_quads_end();
-	
-}
-
-int LAYER_TILES::brush_grab(LAYERGROUP *brush, RECT rect)
-{
-	RECTi r;
-	convert(rect, &r);
-	clamp(&r);
-	
-	if(!r.w || !r.h)
-		return 0;
-	
-	// create new layers
-	LAYER_TILES *grabbed = new LAYER_TILES(r.w, r.h);
-	grabbed->tex_id = tex_id;
-	grabbed->image = image;
-	brush->add_layer(grabbed);
-	
-	// copy the tiles
-	for(int y = 0; y < r.h; y++)
-		for(int x = 0; x < r.w; x++)
-			grabbed->tiles[y*grabbed->width+x] = tiles[(r.y+y)*width+(r.x+x)];
-	
-	return 1;
-}
-
-void LAYER_TILES::brush_draw(LAYER *brush, float wx, float wy)
-{
-	//
-	LAYER_TILES *l = (LAYER_TILES *)brush;
-	int sx = convert_x(wx);
-	int sy = convert_y(wy);
-	
-	for(int y = 0; y < l->height; y++)
-		for(int x = 0; x < l->width; x++)
-		{
-			int fx = x+sx;
-			int fy = y+sy;
-			if(fx<0 || fx >= width || fy < 0 || fy >= height)
-				continue;
-				
-			tiles[fy*width+fx] = l->tiles[y*l->width+x];
-		}
-}
-
-void LAYER_TILES::brush_flip_x()
-{
-	for(int y = 0; y < height; y++)
-		for(int x = 0; x < width/2; x++)
-		{
-			TILE tmp = tiles[y*width+x];
-			tiles[y*width+x] = tiles[y*width+x+width-1-x];
-			tiles[y*width+x+width-1-x] = tmp;
-		}
-
-	for(int y = 0; y < height; y++)
-		for(int x = 0; x < width; x++)
-			tiles[y*width+x].flags ^= TILEFLAG_VFLIP;
-}
-
-void LAYER_TILES::brush_flip_y()
-{
-	for(int y = 0; y < height/2; y++)
-		for(int x = 0; x < width; x++)
-		{
-			TILE tmp = tiles[y*width+x];
-			tiles[y*width+x] = tiles[(height-1-y)*width+x];
-			tiles[(height-1-y)*width+x] = tmp;
-		}
-
-	for(int y = 0; y < height; y++)
-		for(int x = 0; x < width; x++)
-			tiles[y*width+x].flags ^= TILEFLAG_HFLIP;
-}
-
-void LAYER_TILES::resize(int new_w, int new_h)
-{
-	TILE *new_data = new TILE[new_w*new_h];
-	mem_zero(new_data, new_w*new_h*sizeof(TILE));
-
-	// copy old data	
-	for(int y = 0; y < min(new_h, height); y++)
-		mem_copy(&new_data[y*new_w], &tiles[y*width], min(width, new_w)*sizeof(TILE));
-	
-	// replace old
-	delete [] tiles;
-	tiles = new_data;
-	width = new_w;
-	height = new_h;
-}
-
-
-void LAYER_TILES::render_properties(RECT *toolbox)
-{
-	if(editor.props != PROPS_LAYER)
-		return;
-	
-	enum
-	{
-		PROP_IMAGE=0,
-		PROP_WIDTH,
-		PROP_HEIGHT,
-		NUM_PROPS,
-	};
-	
-	PROPERTY props[] = {
-		{"Image", image, PROPTYPE_INT_STEP, 0, 0},
-		{"Width", width, PROPTYPE_INT_STEP, 1, 1000000000},
-		{"Height", height, PROPTYPE_INT_STEP, 1, 1000000000},
-		{0},
-	};
-	
-	static int ids[NUM_PROPS] = {0};
-	int new_val = 0;
-	int prop = editor.do_properties(toolbox, props, ids, &new_val);		
-	
-	if(prop == PROP_IMAGE)
-		image = new_val%editor.map.images.len();
-	else if(prop == PROP_WIDTH && new_val > 1)
-		resize(new_val, height);
-	else if(prop == PROP_HEIGHT && new_val > 1)
-		resize(width, new_val);
-}
diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp
deleted file mode 100644
index ad229759..00000000
--- a/src/editor/editor.cpp
+++ /dev/null
@@ -1,2618 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-extern "C" {
-	#include <engine/e_system.h>
-	#include <engine/client/ec_ui.h>
-	#include <engine/e_interface.h>
-	#include <engine/e_datafile.h>
-	#include <engine/e_config.h>
-}
-
-#include <game/client/gc_mapres_image.h>
-#include <game/client/gc_mapres_tilemap.h>
-//#include "game/mapres_col.h"
-#include <game/g_mapres.h>
-#include <game/g_game.h>
-
-#include "editor.hpp"
-
-static int checker_texture = 0;
-static int background_texture = 0;
-static int cursor_texture = 0;
-static int entities_texture = 0;
-
-
-EDITOR editor;
-
-LAYERGROUP::LAYERGROUP()
-{
-	name = "";
-	visible = true;
-	game_group = false;
-	offset_x = 0;
-	offset_y = 0;
-	parallax_x = 100;
-	parallax_y = 100;
-}
-
-LAYERGROUP::~LAYERGROUP()
-{
-	clear();
-}
-
-void LAYERGROUP::convert(RECT *rect)
-{
-	rect->x += offset_x;
-	rect->y += offset_y;
-}
-
-void LAYERGROUP::mapping(float *points)
-{
-	mapscreen_to_world(
-		editor.world_offset_x, editor.world_offset_y,
-		parallax_x/100.0f, parallax_y/100.0f,
-		offset_x, offset_y,
-		gfx_screenaspect(), editor.world_zoom, points);
-		
-	points[0] += editor.editor_offset_x;
-	points[1] += editor.editor_offset_y;
-	points[2] += editor.editor_offset_x;
-	points[3] += editor.editor_offset_y;
-}
-
-void LAYERGROUP::mapscreen()
-{
-	float points[4];
-	mapping(points);
-	gfx_mapscreen(points[0], points[1], points[2], points[3]);
-}
-
-void LAYERGROUP::render()
-{
-	mapscreen();
-	
-	for(int i = 0; i < layers.len(); i++)
-	{
-		if(layers[i]->visible && layers[i] != editor.game_layer)
-			layers[i]->render();
-	}
-}
-
-bool LAYERGROUP::is_empty() const { return layers.len() == 0; }
-void LAYERGROUP::clear() { layers.deleteall(); }
-void LAYERGROUP::add_layer(LAYER *l) { layers.add(l); }
-
-void LAYERGROUP::delete_layer(int index)
-{
-	if(index < 0 || index >= layers.len()) return;
-	delete layers[index];
-	layers.removebyindex(index);
-}	
-
-void LAYERGROUP::get_size(float *w, float *h)
-{
-	*w = 0; *h = 0;
-	for(int i = 0; i < layers.len(); i++)
-	{
-		float lw, lh;
-		layers[i]->get_size(&lw, &lh);
-		*w = max(*w, lw);
-		*h = max(*h, lh);
-	}
-}
-
-
-int LAYERGROUP::swap_layers(int index0, int index1)
-{
-	if(index0 < 0 || index0 >= layers.len()) return index0;
-	if(index1 < 0 || index1 >= layers.len()) return index0;
-	if(index0 == index1) return index0;
-	swap(layers[index0], layers[index1]);
-	return index1;
-}	
-
-/********************************************************
- OTHER
-*********************************************************/
-extern void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners);
-extern void draw_round_rect(float x, float y, float w, float h, float r);
-
-static void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding)
-{
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(color.r, color.g, color.b, color.a);
-	draw_round_rect_ext(r->x,r->y,r->w,r->h,rounding*ui_scale(), corners);
-	gfx_quads_end();
-}
-
-// copied from gc_menu.cpp, should be more generalized
-
-int ui_do_edit_box(void *id, const RECT *rect, char *str, int str_size, bool hidden=false)
-{
-    int inside = ui_mouse_inside(rect);
-	int r = 0;
-	static int at_index = 0;
-
-	if(ui_last_active_item() == id)
-	{
-		int len = strlen(str);
-
-		if (inside && ui_mouse_button(0))
-		{
-			int mx_rel = (int)(ui_mouse_x() - rect->x);
-
-			for (int i = 1; i <= len; i++)
-			{
-				if (gfx_pretty_text_width(14.0f, str, i) + 10 > mx_rel)
-				{
-					at_index = i - 1;
-					break;
-				}
-
-				if (i == len)
-					at_index = len;
-			}
-		}
-
-		if (at_index > len)
-			at_index = len;
-			
-		for(int i = 0; i < inp_num_events(); i++)
-		{
-			INPUTEVENT e = inp_get_event(i);
-			char c = e.ch;
-			int k = e.key;
-
-			if (!(c >= 0 && c < 32))
-			{
-				if (len < str_size - 1 && at_index < str_size - 1)
-				{
-					memmove(str + at_index + 1, str + at_index, len - at_index + 1);
-					str[at_index] = c;
-					at_index++;
-				}
-			}
-
-			if (k == KEY_BACKSPACE && at_index > 0)
-			{
-				memmove(str + at_index - 1, str + at_index, len - at_index + 1);
-				at_index--;
-			}
-			else if (k == KEY_DEL && at_index < len)
-				memmove(str + at_index, str + at_index + 1, len - at_index);
-			else if (k == KEY_ENTER)
-				ui_clear_last_active_item();
-			else if (k == KEY_LEFT && at_index > 0)
-				at_index--;
-			else if (k == KEY_RIGHT && at_index < len)
-				at_index++;
-			else if (k == KEY_HOME)
-				at_index = 0;
-			else if (k == KEY_END)
-				at_index = len;
-		}
-		
-		r = 1;
-	}
-
-	bool just_got_active = false;
-	
-	if(ui_active_item() == id)
-	{
-		if(!ui_mouse_button(0))
-			ui_set_active_item(0);
-	}
-	else if(ui_hot_item() == id)
-	{
-		if(ui_mouse_button(0))
-		{
-			if (ui_last_active_item() != id)
-				just_got_active = true;
-			ui_set_active_item(id);
-		}
-	}
-	
-	if(inside)
-		ui_set_hot_item(id);
-
-	RECT textbox = *rect;
-	ui_draw_rect(&textbox, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f);
-	ui_vmargin(&textbox, 5.0f, &textbox);
-	
-	const char *display_str = str;
-	char stars[128];
-	
-	if(hidden)
-	{
-		unsigned s = strlen(str);
-		if(s >= sizeof(stars))
-			s = sizeof(stars)-1;
-		memset(stars, '*', s);
-		stars[s] = 0;
-		display_str = stars;
-	}
-	
-	ui_do_label(&textbox, display_str, 14, -1, -1);
-
-	if (ui_last_active_item() == id && !just_got_active)
-	{
-		float w = gfx_pretty_text_width(14.0f, display_str, at_index);
-		textbox.x += w*ui_scale();
-		ui_do_label(&textbox, "_", 14, -1, -1);
-	}
-
-	return r;
-}
-
-
-static vec4 get_button_color(const void *id, int checked)
-{
-	if(checked < 0)
-		return vec4(0,0,0,0.5f);
-		
-	if(checked > 0)
-	{
-		if(ui_hot_item() == id)
-			return vec4(1,0,0,0.75f);
-		return vec4(1,0,0,0.5f);
-	}
-	
-	if(ui_hot_item() == id)
-		return vec4(1,1,1,0.75f);
-	return vec4(1,1,1,0.5f);
-}
-
-static void draw_editor_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
-{
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), CORNER_ALL, 5.0f);
-	ui_do_label(r, text, 10, 0, -1);
-}
-
-static void draw_editor_button_l(const void *id, const char *text, int checked, const RECT *r, const void *extra)
-{
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), CORNER_L, 5.0f);
-	ui_do_label(r, text, 10, 0, -1);
-}
-
-static void draw_editor_button_m(const void *id, const char *text, int checked, const RECT *r, const void *extra)
-{
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), 0, 5.0f);
-	ui_do_label(r, text, 10, 0, -1);
-}
-
-static void draw_editor_button_r(const void *id, const char *text, int checked, const RECT *r, const void *extra)
-{
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), CORNER_R, 5.0f);
-	ui_do_label(r, text, 10, 0, -1);
-}
-
-static void draw_inc_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
-{
-	if(ui_hot_item == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), CORNER_R, 5.0f);
-	ui_do_label(r, ">", 10, 0, -1);
-}
-
-static void draw_dec_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
-{
-	if(ui_hot_item == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), CORNER_L, 5.0f);
-	ui_do_label(r, "<", 10, 0, -1);
-}
-
-
-
-static void render_background(RECT view, int texture, float size, float brightness)
-{
-	gfx_texture_set(texture);
-	gfx_blend_normal();
-	gfx_quads_begin();
-	gfx_setcolor(brightness,brightness,brightness,1.0f);
-	gfx_quads_setsubset(0,0, view.w/size, view.h/size);
-	gfx_quads_drawTL(view.x, view.y, view.w, view.h);
-	gfx_quads_end();
-}
-
-
-static int selected_layer = 0;
-static int selected_group = 0;
-static int selected_quad = -1;
-int selected_points = 0;
-static int selected_envelope = 0;
-
-static LAYERGROUP brush;
-static LAYER_TILES tileset_picker(16, 16);
-
-static int ui_do_value_selector(void *id, RECT *r, const char *label, int current, int min, int max, float scale)
-{
-    /* logic */
-    static float value;
-    int ret = 0;
-    int inside = ui_mouse_inside(r);
-
-	if(ui_active_item() == id)
-	{
-		if(!ui_mouse_button(0))
-		{
-			if(inside)
-				ret = 1;
-			editor.lock_mouse = false;
-			ui_set_active_item(0);
-		}
-		else
-		{
-			if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-				value += editor.mouse_delta_x*0.05f;
-			else
-				value += editor.mouse_delta_x;
-			
-			if(fabs(value) > scale)
-			{
-				int count = (int)(value/scale);
-				value = fmod(value, scale);
-				current += count;
-				if(current < min)
-					current = min;
-				if(current > max)
-					current = max;
-			}
-		}
-	}
-	else if(ui_hot_item() == id)
-	{
-		if(ui_mouse_button(0))
-		{
-			editor.lock_mouse = true;
-			value = 0;
-			ui_set_active_item(id);
-		}
-	}
-	
-	if(inside)
-		ui_set_hot_item(id);
-
-	// render
-	char buf[128];
-	sprintf(buf, "%s %d", label, current);
-	ui_draw_rect(r, get_button_color(id, 0), CORNER_ALL, 5.0f);
-	ui_do_label(r, buf, 12, 0, -1);
-	return current;
-}
-
-
-LAYERGROUP *EDITOR::get_selected_group()
-{
-	if(selected_group >= 0 && selected_group < editor.map.groups.len())
-		return editor.map.groups[selected_group];
-	return 0x0;
-}
-
-LAYER *EDITOR::get_selected_layer(int index)
-{
-	LAYERGROUP *group = get_selected_group();
-	if(!group)
-		return 0x0;
-
-	if(selected_layer >= 0 && selected_layer < editor.map.groups[selected_group]->layers.len())
-		return group->layers[selected_layer];
-	return 0x0;
-}
-
-LAYER *EDITOR::get_selected_layer_type(int index, int type)
-{
-	LAYER *p = get_selected_layer(index);
-	if(p && p->type == type)
-		return p;
-	return 0x0;
-}
-
-QUAD *EDITOR::get_selected_quad()
-{
-	LAYER_QUADS *ql = (LAYER_QUADS *)get_selected_layer_type(0, LAYERTYPE_QUADS);
-	if(!ql)
-		return 0;
-	if(selected_quad >= 0 && selected_quad < ql->quads.len())
-		return &ql->quads[selected_quad];
-	return 0;
-}
-
-
-static void do_toolbar(RECT toolbar)
-{
-	RECT button;
-
-	ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar);
-	static int zoom_out_button = 0;
-	if(ui_do_button(&zoom_out_button, "ZO", 0, &button, draw_editor_button_l, "[NumPad-] Zoom out") || inp_key_down(KEY_KP_SUBTRACT))
-		editor.zoom_level += 50;
-		
-	ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar);
-	static int zoom_normal_button = 0;
-	if(ui_do_button(&zoom_normal_button, "1:1", 0, &button, draw_editor_button_m, "[NumPad*] Zoom to normal and remove editor offset") || inp_key_down(KEY_KP_MULTIPLY))
-	{
-		editor.editor_offset_x = 0;
-		editor.editor_offset_y = 0;
-		editor.zoom_level = 100;
-	}
-		
-	ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar);
-	static int zoom_in_button = 0;
-	if(ui_do_button(&zoom_in_button, "ZI", 0, &button, draw_editor_button_r, "[NumPad+] Zoom in") || inp_key_down(KEY_KP_ADD))
-		editor.zoom_level -= 50;
-	
-	if(editor.zoom_level < 50)
-		editor.zoom_level = 50;
-	editor.world_zoom = editor.zoom_level/100.0f;
-
-	ui_vsplit_l(&toolbar, 10.0f, &button, &toolbar);
-
-
-	// brush manipulation
-	{	
-		int enabled = brush.is_empty()?-1:0;
-		
-		// flip buttons
-		ui_vsplit_l(&toolbar, 20.0f, &button, &toolbar);
-		static int flipx_button = 0;
-		if(ui_do_button(&flipx_button, "^X", enabled, &button, draw_editor_button_l, "Flip brush horizontal"))
-		{
-			for(int i = 0; i < brush.layers.len(); i++)
-				brush.layers[i]->brush_flip_x();
-		}
-			
-		ui_vsplit_l(&toolbar, 20.0f, &button, &toolbar);
-		static int flipy_button = 0;
-		if(ui_do_button(&flipy_button, "^Y", enabled, &button, draw_editor_button_r, "Flip brush vertical"))
-		{
-			for(int i = 0; i < brush.layers.len(); i++)
-				brush.layers[i]->brush_flip_y();
-		}
-	}
-
-	// quad manipulation
-	{
-		// do add button
-		ui_vsplit_l(&toolbar, 10.0f, &button, &toolbar);
-		ui_vsplit_l(&toolbar, 60.0f, &button, &toolbar);
-		static int new_button = 0;
-		
-		LAYER_QUADS *qlayer = (LAYER_QUADS *)editor.get_selected_layer_type(0, LAYERTYPE_QUADS);
-		LAYER_TILES *tlayer = (LAYER_TILES *)editor.get_selected_layer_type(0, LAYERTYPE_TILES);
-		if(ui_do_button(&new_button, "Add Quad", qlayer?0:-1, &button, draw_editor_button, "Adds a new quad"))
-		{
-			if(qlayer)
-			{
-				float mapping[4];
-				LAYERGROUP *g = editor.get_selected_group();
-				g->mapping(mapping);
-				int add_x = f2fx(mapping[0] + (mapping[2]-mapping[0])/2);
-				int add_y = f2fx(mapping[1] + (mapping[3]-mapping[1])/2);
-				
-				QUAD *q = qlayer->new_quad();
-				for(int i = 0; i < 5; i++)
-				{
-					q->points[i].x += add_x;
-					q->points[i].y += add_y;
-				}
-			}
-		}
-
-		ui_vsplit_l(&toolbar, 10.0f, &button, &toolbar);
-		ui_vsplit_l(&toolbar, 60.0f, &button, &toolbar);
-		static int sq_button = 0;
-		if(ui_do_button(&sq_button, "Sq. Quad", editor.get_selected_quad()?0:-1, &button, draw_editor_button, "Squares the current quad"))
-		{
-			QUAD *q = editor.get_selected_quad();
-			if(q)
-			{
-				int top = q->points[0].y;
-				int left = q->points[0].x;
-				int bottom = q->points[0].y;
-				int right = q->points[0].x;
-				
-				for(int k = 1; k < 4; k++)
-				{
-					if(q->points[k].y < top) top = q->points[k].y;
-					if(q->points[k].x < left) left = q->points[k].x;
-					if(q->points[k].y > bottom) bottom = q->points[k].y;
-					if(q->points[k].x > right) right = q->points[k].x;
-				}
-				
-				q->points[0].x = left; q->points[0].y = top;
-				q->points[1].x = right; q->points[1].y = top;
-				q->points[2].x = left; q->points[2].y = bottom;
-				q->points[3].x = right; q->points[3].y = bottom;
-			}
-		}
-
-		ui_vsplit_l(&toolbar, 20.0f, &button, &toolbar);
-		ui_vsplit_l(&toolbar, 60.0f, &button, &toolbar);
-		bool in_gamegroup = editor.game_group->layers.find(tlayer) != -1;
-		static int col_button = 0;
-		if(ui_do_button(&col_button, "Make Col", (in_gamegroup&&tlayer)?0:-1, &button, draw_editor_button, "Constructs collision from the current layer"))
-		{
-			LAYER_TILES *gl = editor.game_layer;
-			int w = min(gl->width, tlayer->width);
-			int h = min(gl->height, tlayer->height);
-			dbg_msg("", "w=%d h=%d", w, h);
-			for(int y = 0; y < h; y++)
-				for(int x = 0; x < w; x++)
-				{
-					if(gl->tiles[y*gl->width+x].index <= TILE_SOLID)
-						gl->tiles[y*gl->width+x].index = tlayer->tiles[y*tlayer->width+x].index?TILE_SOLID:TILE_AIR;
-				}
-		}
-	}
-}
-
-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);
-}
-
-static void do_quad(QUAD *q, int index)
-{
-	enum
-	{
-		OP_NONE=0,
-		OP_MOVE_ALL,
-		OP_MOVE_PIVOT,
-		OP_ROTATE,
-	};
-	
-	// some basic values
-	void *id = &q->points[4]; // use pivot addr as id
-	static POINT rotate_points[4];
-	static float last_wx;
-	static float last_wy;
-	static int operation = OP_NONE;
-	static float rotate_angle = 0;
-	float wx = ui_mouse_world_x();
-	float wy = ui_mouse_world_y();
-	
-	// get pivot
-	float center_x = fx2f(q->points[4].x);
-	float center_y = fx2f(q->points[4].y);
-
-	float dx = (center_x - wx);
-	float dy = (center_y - wy);
-	if(dx*dx+dy*dy < 10*10)
-		ui_set_hot_item(id);
-
-	// draw selection background	
-	if(selected_quad == index)
-	{
-		gfx_setcolor(0,0,0,1);
-		gfx_quads_draw(center_x, center_y, 7.0f, 7.0f);
-	}
-	
-	if(ui_active_item() == id)
-	{
-		// check if we only should move pivot
-		if(operation == OP_MOVE_PIVOT)
-		{
-			q->points[4].x += f2fx(wx-last_wx);
-			q->points[4].y += f2fx(wy-last_wy);
-		}
-		else if(operation == OP_MOVE_ALL)
-		{
-			// move all points including pivot
-			for(int v = 0; v < 5; v++)
-			{
-				q->points[v].x += f2fx(wx-last_wx);
-				q->points[v].y += f2fx(wy-last_wy);
-			}
-		}
-		else if(operation == OP_ROTATE)
-		{
-			for(int v = 0; v < 4; v++)
-			{
-				q->points[v] = rotate_points[v];
-				rotate(&q->points[4], &q->points[v], rotate_angle);
-			}
-		}
-		
-		rotate_angle += (editor.mouse_delta_x) * 0.002f;
-		last_wx = wx;
-		last_wy = wy;
-		
-		if(!ui_mouse_button(0))
-		{
-			editor.lock_mouse = false;
-			operation = OP_NONE;
-			ui_set_active_item(0);
-		}
-
-		gfx_setcolor(1,1,1,1);
-	}
-	else if(ui_hot_item() == id)
-	{
-		gfx_setcolor(1,1,1,1);
-		editor.tooltip = "Left mouse button to move. Hold shift to move pivot. Hold ctrl to rotate";
-		
-		if(ui_mouse_button(0))
-		{
-			if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-				operation = OP_MOVE_PIVOT;
-			else if(inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL))
-			{
-				editor.lock_mouse = true;
-				operation = OP_ROTATE;
-				rotate_angle = 0;
-				rotate_points[0] = q->points[0];
-				rotate_points[1] = q->points[1];
-				rotate_points[2] = q->points[2];
-				rotate_points[3] = q->points[3];
-			}
-			else
-				operation = OP_MOVE_ALL;
-				
-			ui_set_active_item(id);
-			selected_quad = index;
-			editor.props = PROPS_QUAD;
-			last_wx = wx;
-			last_wy = wy;
-		}
-	}
-	else
-		gfx_setcolor(0,1,0,1);
-
-	gfx_quads_draw(center_x, center_y, 5.0f, 5.0f);
-}
-
-static void do_quad_point(QUAD *q, int quad_index, int v)
-{
-	void *id = &q->points[v];
-
-	float wx = ui_mouse_world_x();
-	float wy = ui_mouse_world_y();
-	
-	float px = fx2f(q->points[v].x);
-	float py = fx2f(q->points[v].y);
-	
-	float dx = (px - wx);
-	float dy = (py - wy);
-	if(dx*dx+dy*dy < 10*10)
-		ui_set_hot_item(id);
-
-	// draw selection background	
-	if(selected_quad == quad_index && selected_points&(1<<v))
-	{
-		gfx_setcolor(0,0,0,1);
-		gfx_quads_draw(px, py, 7.0f, 7.0f);
-	}
-	
-	enum
-	{
-		OP_NONE=0,
-		OP_MOVEPOINT,
-		OP_MOVEUV
-	};
-	
-	static bool moved;
-	static int operation = OP_NONE;
-
-	if(ui_active_item() == id)
-	{
-		float dx = editor.mouse_delta_wx;
-		float dy = editor.mouse_delta_wy;
-		if(!moved)
-		{
-			if(dx*dx+dy*dy > 0.5f)
-				moved = true;
-		}
-		
-		if(moved)
-		{
-			if(operation == OP_MOVEPOINT)
-			{
-				for(int m = 0; m < 4; m++)
-					if(selected_points&(1<<m))
-					{
-						q->points[m].x += f2fx(dx);
-						q->points[m].y += f2fx(dy);
-					}
-			}
-			else if(operation == OP_MOVEUV)
-			{
-				for(int m = 0; m < 4; m++)
-					if(selected_points&(1<<m))
-					{
-						q->texcoords[m].x += f2fx(dx*0.001f);
-						q->texcoords[m].y += f2fx(dy*0.001f);
-					}
-			}
-		}
-		
-		if(!ui_mouse_button(0))
-		{
-			if(!moved)
-			{
-				if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-					selected_points ^= 1<<v;
-				else
-					selected_points = 1<<v;
-					
-				editor.props = PROPS_QUAD_POINT;
-			}
-			editor.lock_mouse = false;
-			ui_set_active_item(0);
-		}
-
-		gfx_setcolor(1,1,1,1);
-	}
-	else if(ui_hot_item() == id)
-	{
-		gfx_setcolor(1,1,1,1);
-		editor.tooltip = "Left mouse button to move. Hold shift to move the texture.";
-		
-		if(ui_mouse_button(0))
-		{
-			ui_set_active_item(id);
-			moved = false;
-			if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-			{
-				operation = OP_MOVEUV;
-				editor.lock_mouse = true;
-			}
-			else
-				operation = OP_MOVEPOINT;
-				
-			if(!(selected_points&(1<<v)))
-			{
-				if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-					selected_points |= 1<<v;
-				else
-					selected_points = 1<<v;
-				moved = true;
-			}
-															
-			editor.props = PROPS_QUAD_POINT;
-			selected_quad = quad_index;
-		}
-	}
-	else
-		gfx_setcolor(1,0,0,1);
-	
-	gfx_quads_draw(px, py, 5.0f, 5.0f);	
-}
-
-static void do_map_editor(RECT view, RECT toolbar)
-{
-	// do the toolbar
-	if(editor.gui_active)
-		do_toolbar(toolbar);
-	
-	ui_clip_enable(&view);
-	
-	bool show_picker = inp_key_pressed(KEY_SPACE) != 0;
-
-	// render all good stuff
-	if(!show_picker)
-	{
-		for(int g = 0; g < editor.map.groups.len(); g++)
-		{
-			if(editor.map.groups[g]->visible)
-				editor.map.groups[g]->render();
-		}
-		
-		// render the game above everything else
-		if(editor.game_group->visible && editor.game_layer->visible)
-		{
-			editor.game_group->mapscreen();
-			editor.game_layer->render();
-		}
-	}
-
-	static void *editor_id = (void *)&editor_id;
-	int inside = ui_mouse_inside(&view);
-
-	// fetch mouse position		
-	float wx = ui_mouse_world_x();
-	float wy = ui_mouse_world_y();
-	float mx = ui_mouse_x();
-	float my = ui_mouse_y();
-	
-	static float start_wx = 0;
-	static float start_wy = 0;
-	static float start_mx = 0;
-	static float start_my = 0;
-	
-	enum
-	{
-		OP_NONE=0,
-		OP_BRUSH_GRAB,
-		OP_BRUSH_DRAW,
-		OP_PAN_WORLD,
-		OP_PAN_EDITOR,
-	};
-
-	// remap the screen so it can display the whole tileset
-	if(show_picker)
-	{
-		RECT screen = *ui_screen();
-		float size = 32.0*16.0f;
-		float w = size*(screen.w/view.w);
-		float h = size*(screen.h/view.h);
-		float x = -(view.x/screen.w)*w;
-		float y = -(view.y/screen.h)*h;
-		wx = x+w*mx/screen.w;
-		wy = y+h*my/screen.h;
-		gfx_mapscreen(x, y, x+w, y+h);
-		LAYER_TILES *t = (LAYER_TILES *)editor.get_selected_layer_type(0, LAYERTYPE_TILES);
-		if(t)
-		{
-			tileset_picker.image = t->image;
-			tileset_picker.tex_id = t->tex_id;
-			tileset_picker.render();
-		}
-	}
-	
-	static int operation = OP_NONE;
-	
-	// draw layer borders
-	LAYER *edit_layers[16];
-	int num_edit_layers = 0;
-	num_edit_layers = 0;
-	
-	if(show_picker)
-	{
-		edit_layers[0] = &tileset_picker;
-		num_edit_layers++;
-	}
-	else
-	{
-		edit_layers[0] = editor.get_selected_layer(0);
-		if(edit_layers[0])
-			num_edit_layers++;
-
-		LAYERGROUP *g = editor.get_selected_group();
-		if(g)
-		{
-			g->mapscreen();
-			
-			for(int i = 0; i < num_edit_layers; i++)
-			{
-				if(edit_layers[i]->type != LAYERTYPE_TILES)
-					continue;
-					
-				float w, h;
-				edit_layers[i]->get_size(&w, &h);
-
-				gfx_texture_set(-1);
-				gfx_lines_begin();
-				gfx_lines_draw(0,0, w,0);
-				gfx_lines_draw(w,0, w,h);
-				gfx_lines_draw(w,h, 0,h);
-				gfx_lines_draw(0,h, 0,0);
-				gfx_lines_end();
-			}
-		}
-	}
-		
-	if(inside)
-	{
-		ui_set_hot_item(editor_id);
-		
-		// do global operations like pan and zoom
-		if(ui_active_item() == 0 && ui_mouse_button(0))
-		{
-			start_wx = wx;
-			start_wy = wy;
-			start_mx = mx;
-			start_my = my;
-					
-			if(inp_key_pressed(KEY_LALT))
-			{
-				if(inp_key_pressed(KEY_LSHIFT))
-					operation = OP_PAN_EDITOR;
-				else
-					operation = OP_PAN_WORLD;
-				ui_set_active_item(editor_id);
-			}
-		}
-
-		// brush editing
-		{
-			if(brush.is_empty())
-				editor.tooltip = "Use left mouse button to drag and create a brush.";
-			else
-				editor.tooltip = "Use left mouse button to paint with the brush. Right button clears the brush.";
-
-			if(ui_active_item() == editor_id)
-			{
-				RECT r;
-				r.x = start_wx;
-				r.y = start_wy;
-				r.w = wx-start_wx;
-				r.h = wy-start_wy;
-				if(r.w < 0)
-				{
-					r.x += r.w;
-					r.w = -r.w;
-				}
-
-				if(r.h < 0)
-				{
-					r.y += r.h;
-					r.h = -r.h;
-				}
-				
-				if(operation == OP_BRUSH_DRAW)
-				{						
-					if(!brush.is_empty())
-					{
-						// draw with brush
-						for(int k = 0; k < num_edit_layers; k++)
-						{
-							if(edit_layers[k]->type == brush.layers[0]->type)
-								edit_layers[k]->brush_draw(brush.layers[0], wx, wy);
-						}
-					}
-				}
-				else if(operation == OP_BRUSH_GRAB)
-				{
-					if(!ui_mouse_button(0))
-					{
-						// grab brush
-						dbg_msg("editor", "grabbing %f %f %f %f", r.x, r.y, r.w, r.h);
-						
-						// TODO: do all layers
-						int grabs = 0;
-						for(int k = 0; k < num_edit_layers; k++)
-							grabs += edit_layers[k]->brush_grab(&brush, r);
-						if(grabs == 0)
-							brush.clear();
-					}
-					else
-					{
-						editor.map.groups[selected_group]->mapscreen();
-						for(int k = 0; k < num_edit_layers; k++)
-							edit_layers[k]->brush_selecting(r);
-						gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
-					}
-				}
-			}
-			else
-			{
-				if(ui_mouse_button(1))
-					brush.clear();
-					
-				if(ui_mouse_button(0) && operation == OP_NONE)
-				{
-					ui_set_active_item(editor_id);
-					
-					if(brush.is_empty())
-						operation = OP_BRUSH_GRAB;
-					else
-					{
-						operation = OP_BRUSH_DRAW;
-						for(int k = 0; k < num_edit_layers; k++)
-						{
-							if(edit_layers[k]->type == brush.layers[0]->type)
-								edit_layers[k]->brush_place(brush.layers[0], wx, wy);
-						}
-						
-					}
-				}
-				
-				if(!brush.is_empty())
-				{
-					brush.offset_x = -(int)wx;
-					brush.offset_y = -(int)wy;
-					for(int i = 0; i < brush.layers.len(); i++)
-					{
-						if(brush.layers[i]->type == LAYERTYPE_TILES)
-						{
-							brush.offset_x = -(int)(wx/32.0f)*32;
-							brush.offset_y = -(int)(wy/32.0f)*32;
-							break;
-						}
-					}
-				
-					LAYERGROUP *g = editor.get_selected_group();
-					brush.offset_x += g->offset_x;
-					brush.offset_y += g->offset_y;
-					brush.parallax_x = g->parallax_x;
-					brush.parallax_y = g->parallax_y;
-					brush.render();
-					float w, h;
-					brush.get_size(&w, &h);
-					
-					gfx_texture_set(-1);
-					gfx_lines_begin();
-					gfx_lines_draw(0,0, w,0);
-					gfx_lines_draw(w,0, w,h);
-					gfx_lines_draw(w,h, 0,h);
-					gfx_lines_draw(0,h, 0,0);
-					gfx_lines_end();
-					
-				}
-			}
-		}
-		
-		if(!show_picker && brush.is_empty())
-		{
-			// fetch layers
-			LAYERGROUP *g = editor.get_selected_group();
-			if(g)
-				g->mapscreen();
-				
-			for(int k = 0; k < num_edit_layers; k++)
-			{
-				if(edit_layers[k]->type == LAYERTYPE_QUADS)
-				{
-					LAYER_QUADS *layer = (LAYER_QUADS *)edit_layers[k];
-	
-					gfx_texture_set(-1);
-					gfx_quads_begin();				
-					for(int i = 0; i < layer->quads.len(); i++)
-					{
-						for(int v = 0; v < 4; v++)
-							do_quad_point(&layer->quads[i], i, v);
-							
-						do_quad(&layer->quads[i], i);
-					}
-					gfx_quads_end();
-				}
-			}
-			
-			gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
-		}		
-		
-		// do panning
-		if(ui_active_item() == editor_id)
-		{
-			if(operation == OP_PAN_WORLD)
-			{
-				editor.world_offset_x -= editor.mouse_delta_x*editor.world_zoom;
-				editor.world_offset_y -= editor.mouse_delta_y*editor.world_zoom;
-			}
-			else if(operation == OP_PAN_EDITOR)
-			{
-				editor.editor_offset_x -= editor.mouse_delta_x*editor.world_zoom;
-				editor.editor_offset_y -= editor.mouse_delta_y*editor.world_zoom;
-			}
-		}
-
-		
-		// release mouse
-		if(!ui_mouse_button(0))
-		{
-			operation = OP_NONE;
-			ui_set_active_item(0);
-		}
-		
-	}
-
-	// render screen sizes	
-	if(editor.proof_borders)
-	{
-		LAYERGROUP *g = editor.game_group;
-		g->mapscreen();
-		
-		gfx_texture_set(-1);
-		gfx_lines_begin();
-		
-		float last_points[4];
-		float start = 1.0f; //9.0f/16.0f;
-		float end = 16.0f/9.0f;
-		const int num_steps = 20;
-		for(int i = 0; i <= num_steps; i++)
-		{
-			float points[4];
-			float aspect = start + (end-start)*(i/(float)num_steps);
-			
-			mapscreen_to_world(
-				editor.world_offset_x, editor.world_offset_y,
-				1.0f, 1.0f, 0.0f, 0.0f, aspect, 1.0f, points);
-			
-			if(i == 0)
-			{
-				gfx_lines_draw(points[0], points[1], points[2], points[1]);
-				gfx_lines_draw(points[0], points[3], points[2], points[3]);
-			}
-
-			if(i != 0)
-			{
-				gfx_lines_draw(points[0], points[1], last_points[0], last_points[1]);
-				gfx_lines_draw(points[2], points[1], last_points[2], last_points[1]);
-				gfx_lines_draw(points[0], points[3], last_points[0], last_points[3]);
-				gfx_lines_draw(points[2], points[3], last_points[2], last_points[3]);
-			}
-
-			if(i == num_steps)
-			{
-				gfx_lines_draw(points[0], points[1], points[0], points[3]);
-				gfx_lines_draw(points[2], points[1], points[2], points[3]);
-			}
-			
-			mem_copy(last_points, points, sizeof(points));
-		}
-
-		if(0)
-		{
-			gfx_setcolor(1.0f,0,0,1);		
-			for(int i = 0; i < 4; i++)
-			{
-				float points[4];
-				float aspects[] = {4.0f/3.0f, 5.0f/4.0f, 16.0f/10.0f, 16.0f/9.0f};
-				float aspect = aspects[i];
-				
-				mapscreen_to_world(
-					editor.world_offset_x, editor.world_offset_y,
-					1.0f, 1.0f, 0.0f, 0.0f, aspect, 1.0f, points);
-				
-				RECT r;
-				r.x = points[0];
-				r.y = points[1];
-				r.w = points[2]-points[0];
-				r.h = points[3]-points[1];
-				
-				gfx_lines_draw(r.x, r.y, r.x+r.w, r.y);
-				gfx_lines_draw(r.x+r.w, r.y, r.x+r.w, r.y+r.h);
-				gfx_lines_draw(r.x+r.w, r.y+r.h, r.x, r.y+r.h);
-				gfx_lines_draw(r.x, r.y+r.h, r.x, r.y);
-			}
-		}
-			
-		gfx_lines_end();
-	}
-	
-	gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
-	ui_clip_disable();
-}
-
-int EDITOR::do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val)
-{
-	int change = -1;
-
-	for(int i = 0; props[i].name; i++)
-	{
-		RECT slot;
-		ui_hsplit_t(toolbox, 13.0f, &slot, toolbox);
-		RECT label, shifter;
-		ui_vsplit_mid(&slot, &label, &shifter);
-		ui_hmargin(&shifter, 1.0f, &shifter);
-		ui_do_label(&label, props[i].name, 10.0f, -1, -1);
-		
-		if(props[i].type == PROPTYPE_INT_STEP)
-		{
-			RECT inc, dec;
-			char buf[64];
-			
-			ui_vsplit_r(&shifter, 10.0f, &shifter, &inc);
-			ui_vsplit_l(&shifter, 10.0f, &dec, &shifter);
-			sprintf(buf, "%d", props[i].value);
-			ui_draw_rect(&shifter, vec4(1,1,1,0.5f), 0, 0.0f);
-			ui_do_label(&shifter, buf, 10.0f, 0, -1);
-			
-			if(ui_do_button(&ids[i], 0, 0, &dec, draw_dec_button, "Decrease"))
-			{
-				if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-					*new_val = props[i].value-5;
-				else
-					*new_val = props[i].value-1;
-				change = i;
-			}
-			if(ui_do_button(((char *)&ids[i])+1, 0, 0, &inc, draw_inc_button, "Increase"))
-			{
-				if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-					*new_val = props[i].value+5;
-				else
-					*new_val = props[i].value+1;
-				change = i;
-			}
-		}
-		else if(props[i].type == PROPTYPE_INT_SCROLL)
-		{
-			int new_value = ui_do_value_selector(&ids[i], &shifter, "", props[i].value, props[i].min, props[i].max, 1.0f);
-			if(new_value != props[i].value)
-			{
-				*new_val = new_value;
-				change = i;
-			}
-		}
-		else if(props[i].type == PROPTYPE_COLOR)
-		{
-			static const char *texts[4] = {"R", "G", "B", "A"};
-			static int shift[] = {24, 16, 8, 0};
-			int new_color = 0;
-			
-			for(int c = 0; c < 4; c++)
-			{
-				int v = (props[i].value >> shift[c])&0xff;
-				new_color |= ui_do_value_selector(((char *)&ids[i])+c, &shifter, texts[c], v, 0, 255, 1.0f)<<shift[c];
-
-				if(c != 3)
-				{
-					ui_hsplit_t(toolbox, 13.0f, &slot, toolbox);
-					ui_vsplit_mid(&slot, 0, &shifter);
-					ui_hmargin(&shifter, 1.0f, &shifter);
-				}
-			}
-			
-			if(new_color != props[i].value)
-			{
-				*new_val = new_color;
-				change = i;
-			}
-		}
-	}
-	
-	return change;
-}
-
-static void render_layers(RECT toolbox, RECT toolbar, RECT view)
-{
-	RECT layersbox = toolbox;
-	RECT propsbox;
-
-	do_map_editor(view, toolbar);
-	
-	if(!editor.gui_active)
-		return;
-			
-	RECT slot, button;
-	char buf[64];
-
-	int valid_group = 0;
-	int valid_layer = 0;
-	if(selected_group >= 0 && selected_group < editor.map.groups.len())
-		valid_group = 1;
-
-	if(valid_group && selected_layer >= 0 && selected_layer < editor.map.groups[selected_group]->layers.len())
-		valid_layer = 1;
-		
-	int valid_group_mask = valid_group ? 0 : -1;
-	int valid_layer_mask = valid_layer ? 0 : -1;
-	
-	{
-		ui_hsplit_t(&layersbox, 12.0f, &slot, &layersbox);
-		
-		// new layer group
-		ui_vsplit_l(&slot, 12.0f, &button, &slot);
-		static int new_layer_group_button = 0;
-		if(ui_do_button(&new_layer_group_button, "G+", 0, &button, draw_editor_button, "New group"))
-		{
-			editor.map.new_group();
-			selected_group = editor.map.groups.len()-1;
-			editor.props = PROPS_GROUP;
-		}
-			
-		// new tile layer
-		ui_vsplit_l(&slot, 10.0f, &button, &slot);
-		ui_vsplit_l(&slot, 12.0f, &button, &slot);
-		static int new_tile_layer_button = 0;
-		if(ui_do_button(&new_tile_layer_button, "T+", valid_group_mask, &button, draw_editor_button, "New tile layer"))
-		{
-			LAYER *l = new LAYER_TILES(50, 50);
-			editor.map.groups[selected_group]->add_layer(l);
-			selected_layer = editor.map.groups[selected_group]->layers.len()-1;
-			editor.props = PROPS_LAYER;
-		}
-
-		// new quad layer
-		ui_vsplit_l(&slot, 2.0f, &button, &slot);
-		ui_vsplit_l(&slot, 12.0f, &button, &slot);
-		static int new_quad_layer_button = 0;
-		if(ui_do_button(&new_quad_layer_button, "Q+", valid_group_mask, &button, draw_editor_button, "New quad layer"))
-		{
-			LAYER *l = new LAYER_QUADS;
-			editor.map.groups[selected_group]->add_layer(l);
-			selected_layer = editor.map.groups[selected_group]->layers.len()-1;
-			editor.props = PROPS_LAYER;
-		}
-
-		// remove layer
-		ui_vsplit_r(&slot, 12.0f, &slot, &button);
-		static int delete_layer_button = 0;
-		if(ui_do_button(&delete_layer_button, "L-", valid_layer_mask, &button, draw_editor_button, "Delete layer"))
-			editor.map.groups[selected_group]->delete_layer(selected_layer);
-
-		// remove group
-		ui_vsplit_r(&slot, 2.0f, &slot, &button);
-		ui_vsplit_r(&slot, 12.0f, &slot, &button);
-		static int delete_group_button = 0;
-		if(ui_do_button(&delete_group_button, "G-", valid_group_mask, &button, draw_editor_button, "Delete group"))
-			editor.map.delete_group(selected_group);
-	}
-
-	ui_hsplit_t(&layersbox, 5.0f, &slot, &layersbox);
-	
-	// render layers	
-	{
-		for(int g = 0; g < editor.map.groups.len(); g++)
-		{
-			RECT visible_toggle;
-			ui_hsplit_t(&layersbox, 12.0f, &slot, &layersbox);
-			ui_vsplit_l(&slot, 12, &visible_toggle, &slot);
-			if(ui_do_button(&editor.map.groups[g]->visible, editor.map.groups[g]->visible?"V":"H", 0, &visible_toggle, draw_editor_button_l, "Toggle group visibility"))
-				editor.map.groups[g]->visible = !editor.map.groups[g]->visible;
-
-			sprintf(buf, "#%d %s", g, editor.map.groups[g]->name);
-			if(ui_do_button(&editor.map.groups[g], buf, g==selected_group, &slot, draw_editor_button_r, "Select group"))
-			{
-				selected_group = g;
-				selected_layer = 0;
-				editor.props = PROPS_GROUP;
-			}
-			
-			ui_hsplit_t(&layersbox, 2.0f, &slot, &layersbox);
-			
-			for(int i = 0; i < editor.map.groups[g]->layers.len(); i++)
-			{
-				//visible
-				ui_hsplit_t(&layersbox, 12.0f, &slot, &layersbox);
-				ui_vsplit_l(&slot, 12.0f, 0, &button);
-				ui_vsplit_l(&button, 15, &visible_toggle, &button);
-
-				if(ui_do_button(&editor.map.groups[g]->layers[i]->visible, editor.map.groups[g]->layers[i]->visible?"V":"H", 0, &visible_toggle, draw_editor_button_l, "Toggle layer visibility"))
-					editor.map.groups[g]->layers[i]->visible = !editor.map.groups[g]->layers[i]->visible;
-
-				sprintf(buf, "#%d %s ", i, editor.map.groups[g]->layers[i]->type_name);
-				if(ui_do_button(editor.map.groups[g]->layers[i], buf, g==selected_group&&i==selected_layer, &button, draw_editor_button_r, "Select layer"))
-				{
-					selected_layer = i;
-					selected_group = g;
-					editor.props = PROPS_LAYER;
-				}
-				ui_hsplit_t(&layersbox, 2.0f, &slot, &layersbox);
-			}
-			ui_hsplit_t(&layersbox, 5.0f, &slot, &layersbox);
-		}
-	}
-	
-	propsbox = layersbox;
-	
-	// group properties
-	if(editor.props == PROPS_GROUP && valid_group)
-	{
-		ui_hsplit_t(&propsbox, 12.0f, &slot, &propsbox);
-		ui_do_label(&slot, "Group Props", 12.0f, -1, -1);
-	
-		enum
-		{
-			PROP_ORDER=0,
-			PROP_POS_X,
-			PROP_POS_Y,
-			PROP_PARA_X,
-			PROP_PARA_Y,
-			NUM_PROPS,
-		};
-		
-		PROPERTY props[] = {
-			{"Order", selected_group, PROPTYPE_INT_STEP, 0, editor.map.groups.len()-1},
-			{"Pos X", -editor.map.groups[selected_group]->offset_x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-			{"Pos Y", -editor.map.groups[selected_group]->offset_y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-			{"Para X", editor.map.groups[selected_group]->parallax_x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-			{"Para Y", editor.map.groups[selected_group]->parallax_y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-			{0},
-		};
-		
-		static int ids[NUM_PROPS] = {0};
-		int new_val = 0;
-		
-		// cut the properties that isn't needed
-		if(editor.get_selected_group()->game_group)
-			props[PROP_POS_X].name = 0;
-			
-		int prop = editor.do_properties(&propsbox, props, ids, &new_val);
-		if(prop == PROP_ORDER)
-			selected_group = editor.map.swap_groups(selected_group, new_val);
-			
-		// these can not be changed on the game group
-		if(!editor.get_selected_group()->game_group)
-		{
-			if(prop == PROP_PARA_X)
-				editor.map.groups[selected_group]->parallax_x = new_val;
-			else if(prop == PROP_PARA_Y)
-				editor.map.groups[selected_group]->parallax_y = new_val;
-			else if(prop == PROP_POS_X)
-				editor.map.groups[selected_group]->offset_x = -new_val;
-			else if(prop == PROP_POS_Y)
-				editor.map.groups[selected_group]->offset_y = -new_val;
-		}
-	}
-	
-	// layer properties
-	if(editor.get_selected_layer(0))
-	{
-		LAYERGROUP *current_group = editor.map.groups[selected_group];
-		LAYER *current_layer = editor.get_selected_layer(0);
-		
-		if(editor.props == PROPS_LAYER)
-		{
-			ui_hsplit_t(&propsbox, 15.0f, &slot, &propsbox);
-			ui_do_label(&slot, "Layer Props", 12.0f, -1, -1);
-			
-			enum
-			{
-				PROP_GROUP=0,
-				PROP_ORDER,
-				NUM_PROPS,
-			};
-			
-			PROPERTY props[] = {
-				{"Group", selected_group, PROPTYPE_INT_STEP, 0, editor.map.groups.len()-1},
-				{"Order", selected_layer, PROPTYPE_INT_STEP, 0, current_group->layers.len()},
-				{0},
-			};
-			
-			static int ids[NUM_PROPS] = {0};
-			int new_val = 0;
-			int prop = editor.do_properties(&propsbox, props, ids, &new_val);		
-			
-			if(prop == PROP_ORDER)
-				selected_layer = current_group->swap_layers(selected_layer, new_val);
-			else if(prop == PROP_GROUP && current_layer->type != LAYERTYPE_GAME)
-			{
-				if(new_val >= 0 && new_val < editor.map.groups.len())
-				{
-					current_group->layers.remove(current_layer);
-					editor.map.groups[new_val]->layers.add(current_layer);
-					selected_group = new_val;
-					selected_layer = editor.map.groups[new_val]->layers.len()-1;
-				}
-			}
-		}
-			
-		current_layer->render_properties(&propsbox);
-	}
-}
-
-static void render_images(RECT toolbox, RECT view)
-{
-	static int selected_image = 0;
-	
-	for(int i = 0; i < editor.map.images.len(); i++)
-	{
-		char buf[128];
-		sprintf(buf, "#%d %dx%d", i, editor.map.images[i]->width, editor.map.images[i]->height);
-		RECT slot;
-		ui_hsplit_t(&toolbox, 15.0f, &slot, &toolbox);
-		
-		if(ui_do_button(&editor.map.images[i], buf, selected_image == i, &slot, draw_editor_button, "Select image"))
-			selected_image = i;
-		
-		ui_hsplit_t(&toolbox, 2.0f, 0, &toolbox);
-		
-		// render image
-		if(selected_image == i)
-		{
-			RECT r;
-			ui_margin(&view, 10.0f, &r);
-			if(r.h < r.w)
-				r.w = r.h;
-			else
-				r.h = r.w;
-			gfx_texture_set(editor.map.images[i]->tex_id);
-			gfx_blend_normal();
-			gfx_quads_begin();
-			gfx_quads_drawTL(r.x, r.y, r.w, r.h);
-			gfx_quads_end();
-			
-		}
-	}
-	
-	RECT slot;
-	ui_hsplit_t(&toolbox, 5.0f, &slot, &toolbox);
-	ui_hsplit_t(&toolbox, 15.0f, &slot, &toolbox);
-
-	// new image
-	static int new_image_button = 0;
-	if(ui_do_button(&new_image_button, "(Load New Image)", 0, &slot, draw_editor_button, "Load a new image to use in the map"))
-		editor.dialog = DIALOG_LOAD_IMAGE;
-
-	ui_hsplit_t(&toolbox, 15.0f, &slot, &toolbox);
-}
-	
-static void editor_listdir_callback(const char *name, int is_dir, void *user)
-{
-	if(name[0] == '.') // skip this shit!
-		return;
-	
-	RECT *view = (RECT *)user;
-	RECT button;
-	ui_hsplit_t(view, 15.0f, &button, view);
-	ui_hsplit_t(view, 2.0f, 0, view);
-	
-	if(ui_do_button((void*)(10+(int)button.y), name, 0, &button, draw_editor_button, 0))
-	{
-		char buf[512];
-		sprintf(buf, "tilesets/%s", name);
-		
-		IMAGE imginfo;
-		if(!gfx_load_png(&imginfo, buf))
-			return;
-		
-		IMAGE *img = new IMAGE;
-		*img = imginfo;
-		img->tex_id = gfx_load_texture_raw(imginfo.width, imginfo.height, imginfo.format, imginfo.data, IMG_AUTO);
-		editor.map.images.add(img);
-		
-		//tilesets_set_img(tilesets_new(), img.width, img.height, img.data);
-		editor.dialog = DIALOG_NONE;
-	}
-}
-
-static void render_dialog_load_image()
-{
-	// GUI coordsys
-	gfx_clear(0.25f,0.25f,0.25f);
-		
-	gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
-	
-	RECT view = *ui_screen();
-	fs_listdir("tilesets", editor_listdir_callback, &view);
-	
-	if(inp_key_pressed(KEY_ESC))
-		editor.dialog = DIALOG_NONE;
-}
-
-static void render_modebar(RECT view)
-{
-	RECT button;
-
-	// mode buttons
-	{
-		ui_vsplit_l(&view, 40.0f, &button, &view);
-		static int map_button = 0;
-		if(ui_do_button(&map_button, "Map", editor.mode == MODE_MAP, &button, draw_editor_button_l, "Switch to edit global map settings"))
-			editor.mode = MODE_MAP;
-		
-		ui_vsplit_l(&view, 40.0f, &button, &view);
-		static int tile_button = 0;
-		if(ui_do_button(&tile_button, "Layers", editor.mode == MODE_LAYERS, &button, draw_editor_button_m, "Switch to edit layers"))
-			editor.mode = MODE_LAYERS;
-
-		ui_vsplit_l(&view, 40.0f, &button, &view);
-		static int img_button = 0;
-		if(ui_do_button(&img_button, "Images", editor.mode == MODE_IMAGES, &button, draw_editor_button_r, "Switch to manage images"))
-			editor.mode = MODE_IMAGES;
-	}
-
-	ui_vsplit_l(&view, 5.0f, 0, &view);
-	
-	// animate button
-	ui_vsplit_l(&view, 30.0f, &button, &view);
-	static int animate_button = 0;
-	if(ui_do_button(&animate_button, "Anim", editor.animate, &button, draw_editor_button, "[ctrl+m] Toggle animation") ||
-		(inp_key_down('M') && (inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL))))
-	{
-		editor.animate_start = time_get();
-		editor.animate = !editor.animate;
-	}
-
-	ui_vsplit_l(&view, 5.0f, 0, &view);
-
-	// proof button
-	ui_vsplit_l(&view, 30.0f, &button, &view);
-	static int proof_button = 0;
-	if(ui_do_button(&proof_button, "Proof", editor.proof_borders, &button, draw_editor_button, "[ctrl-p] Toggles proof borders. These borders represent what a player maximum can see.") ||
-		(inp_key_down('P') && (inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL))))
-	{
-		editor.proof_borders = !editor.proof_borders;
-	}
-	
-	// spacing
-	//ui_vsplit_l(&view, 10.0f, 0, &view);
-}
-
-static void render_statusbar(RECT view)
-{
-	RECT button;
-	ui_vsplit_r(&view, 60.0f, &view, &button);
-	static int envelope_button = 0;
-	if(ui_do_button(&envelope_button, "Envelopes", editor.show_envelope_editor, &button, draw_editor_button, "Toggles the envelope editor"))
-		editor.show_envelope_editor = (editor.show_envelope_editor+1)%4;
-	
-	if(editor.tooltip)
-		ui_do_label(&view, editor.tooltip, 12.0f, -1, -1);
-}
-
-static void render_envelopeeditor(RECT view)
-{
-	if(selected_envelope < 0) selected_envelope = 0;
-	if(selected_envelope >= editor.map.envelopes.len()) selected_envelope--;
-
-	ENVELOPE *envelope = 0;
-	if(selected_envelope >= 0 && selected_envelope < editor.map.envelopes.len())
-		envelope = editor.map.envelopes[selected_envelope];
-
-	bool show_colorbar = false;
-	if(envelope && envelope->channels == 4)
-		show_colorbar = true;
-
-	RECT toolbar, curvebar, colorbar;
-	ui_hsplit_t(&view, 20.0f, &toolbar, &view);
-	ui_hsplit_t(&view, 20.0f, &curvebar, &view);
-	ui_margin(&toolbar, 2.0f, &toolbar);
-	ui_margin(&curvebar, 2.0f, &curvebar);
-
-	if(show_colorbar)
-	{
-		ui_hsplit_t(&view, 20.0f, &colorbar, &view);
-		ui_margin(&colorbar, 2.0f, &colorbar);
-		render_background(colorbar, checker_texture, 16.0f, 1.0f);
-	}
-
-	render_background(view, checker_texture, 32.0f, 0.1f);
-
-	// do the toolbar
-	{
-		RECT button;
-		ENVELOPE *new_env = 0;
-		
-		ui_vsplit_r(&toolbar, 50.0f, &toolbar, &button);
-		static int new_4d_button = 0;
-		if(ui_do_button(&new_4d_button, "Color+", 0, &button, draw_editor_button, "Creates a new color envelope"))
-			new_env = editor.map.new_envelope(4);
-
-		ui_vsplit_r(&toolbar, 5.0f, &toolbar, &button);
-		ui_vsplit_r(&toolbar, 50.0f, &toolbar, &button);
-		static int new_2d_button = 0;
-		if(ui_do_button(&new_2d_button, "Pos.+", 0, &button, draw_editor_button, "Creates a new pos envelope"))
-			new_env = editor.map.new_envelope(3);
-		
-		if(new_env) // add the default points
-		{
-			if(new_env->channels == 4)
-			{
-				new_env->add_point(0, 1,1,1,1);
-				new_env->add_point(1000, 1,1,1,1);
-			}
-			else
-			{
-				new_env->add_point(0, 0);
-				new_env->add_point(1000, 0);
-			}
-		}
-		
-		RECT shifter, inc, dec;
-		ui_vsplit_l(&toolbar, 60.0f, &shifter, &toolbar);
-		ui_vsplit_r(&shifter, 15.0f, &shifter, &inc);
-		ui_vsplit_l(&shifter, 15.0f, &dec, &shifter);
-		char buf[512];
-		sprintf(buf, "%d/%d", selected_envelope+1, editor.map.envelopes.len());
-		ui_draw_rect(&shifter, vec4(1,1,1,0.5f), 0, 0.0f);
-		ui_do_label(&shifter, buf, 14.0f, 0, -1);
-		
-		static int prev_button = 0;
-		if(ui_do_button(&prev_button, 0, 0, &dec, draw_dec_button, "Previous Envelope"))
-			selected_envelope--;
-		
-		static int next_button = 0;
-		if(ui_do_button(&next_button, 0, 0, &inc, draw_inc_button, "Next Envelope"))
-			selected_envelope++;
-			
-		if(envelope)
-		{
-			ui_vsplit_l(&toolbar, 15.0f, &button, &toolbar);
-			ui_vsplit_l(&toolbar, 35.0f, &button, &toolbar);
-			ui_do_label(&button, "Name:", 14.0f, -1, -1);
-
-			ui_vsplit_l(&toolbar, 80.0f, &button, &toolbar);
-			static int name_box = 0;
-			ui_do_edit_box(&name_box, &button, envelope->name, sizeof(envelope->name));
-		}
-	}
-	
-	if(envelope)
-	{
-		static array<int> selection;
-		static int envelope_editor_id = 0;
-		static int active_channels = 0xf;
-		
-		if(envelope)
-		{
-			RECT button;	
-			
-			ui_vsplit_l(&toolbar, 15.0f, &button, &toolbar);
-
-			static const char *names[4][4] = {
-				{"X", "", "", ""},
-				{"X", "Y", "", ""},
-				{"X", "Y", "R", ""},
-				{"R", "G", "B", "A"},
-			};
-			
-			static int channel_buttons[4] = {0};
-			int bit = 1;
-			ui_draw_button_func draw_func;
-			
-			for(int i = 0; i < envelope->channels; i++, bit<<=1)
-			{
-				ui_vsplit_l(&toolbar, 15.0f, &button, &toolbar);
-				
-				if(i == 0) draw_func = draw_editor_button_l;
-				else if(i == envelope->channels-1) draw_func = draw_editor_button_r;
-				else draw_func = draw_editor_button_m;
-				
-				if(ui_do_button(&channel_buttons[i], names[envelope->channels-1][i], active_channels&bit, &button, draw_func, 0))
-					active_channels ^= bit;
-			}
-		}		
-		
-		float end_time = envelope->end_time();
-		if(end_time < 1)
-			end_time = 1;
-		
-		envelope->find_top_bottom();
-		float top = envelope->top;
-		float bottom = envelope->bottom;
-		
-		if(top < 1)
-			top = 1;
-		if(bottom >= 0)
-			bottom = 0;
-		
-		float timescale = end_time/view.w;
-		float valuescale = (top-bottom)/view.h;
-		
-		if(ui_mouse_inside(&view))
-			ui_set_hot_item(&envelope_editor_id);
-			
-		if(ui_hot_item() == &envelope_editor_id)
-		{
-			// do stuff
-			if(envelope)
-			{
-				if(ui_mouse_button_clicked(1))
-				{
-					// add point
-					int time = (int)(((ui_mouse_x()-view.x)*timescale)*1000.0f);
-					//float env_y = (ui_mouse_y()-view.y)/timescale;
-					envelope->add_point(time,
-						f2fx(envelope->eval(time, 0)),
-						f2fx(envelope->eval(time, 1)),
-						f2fx(envelope->eval(time, 2)),
-						f2fx(envelope->eval(time, 3)));
-				}
-				
-				editor.tooltip = "Press right mouse button to create a new point";
-			}
-		}
-
-		vec3 colors[] = {vec3(1,0.2f,0.2f), vec3(0.2f,1,0.2f), vec3(0.2f,0.2f,1), vec3(1,1,0.2f)};
-
-		// render lines
-		{
-			gfx_texture_set(-1);
-			gfx_lines_begin();
-			for(int c = 0; c < envelope->channels; c++)
-			{
-				if(active_channels&(1<<c))
-					gfx_setcolor(colors[c].r,colors[c].g,colors[c].b,1);
-				else
-					gfx_setcolor(colors[c].r*0.5f,colors[c].g*0.5f,colors[c].b*0.5f,1);
-				
-				float prev_x = 0;
-				float prev_value = envelope->eval(0.000001f, c);
-				int steps = (int)((view.w/ui_screen()->w) * gfx_screenwidth());
-				for(int i = 1; i <= steps; i++)
-				{
-					float a = i/(float)steps;
-					float v = envelope->eval(a*end_time, c);
-					v = (v-bottom)/(top-bottom);
-					
-					gfx_lines_draw(view.x + prev_x*view.w, view.y+view.h - prev_value*view.h, view.x + a*view.w, view.y+view.h - v*view.h);
-					prev_x = a;
-					prev_value = v;
-				}
-			}
-			gfx_lines_end();
-		}
-		
-		// render curve options
-		{
-			for(int i = 0; i < envelope->points.len()-1; i++)
-			{
-				float t0 = envelope->points[i].time/1000.0f/end_time;
-				float t1 = envelope->points[i+1].time/1000.0f/end_time;
-
-				//dbg_msg("", "%f", end_time);
-				
-				RECT v;
-				v.x = curvebar.x + (t0+(t1-t0)*0.5f) * curvebar.w;
-				v.y = curvebar.y;
-				v.h = curvebar.h;
-				v.w = curvebar.h;
-				v.x -= v.w/2;
-				void *id = &envelope->points[i].curvetype;
-				const char *type_name[] = {
-					"N", "L", "S", "F", "M"
-					};
-				
-				if(ui_do_button(id, type_name[envelope->points[i].curvetype], 0, &v, draw_editor_button, "Switch curve type"))
-					envelope->points[i].curvetype = (envelope->points[i].curvetype+1)%NUM_CURVETYPES;
-			}
-		}
-		
-		// render colorbar
-		if(show_colorbar)
-		{
-			gfx_texture_set(-1);
-			gfx_quads_begin();
-			for(int i = 0; i < envelope->points.len()-1; i++)
-			{
-				float r0 = fx2f(envelope->points[i].values[0]);
-				float g0 = fx2f(envelope->points[i].values[1]);
-				float b0 = fx2f(envelope->points[i].values[2]);
-				float a0 = fx2f(envelope->points[i].values[3]);
-				float r1 = fx2f(envelope->points[i+1].values[0]);
-				float g1 = fx2f(envelope->points[i+1].values[1]);
-				float b1 = fx2f(envelope->points[i+1].values[2]);
-				float a1 = fx2f(envelope->points[i+1].values[3]);
-
-				gfx_setcolorvertex(0, r0, g0, b0, a0);
-				gfx_setcolorvertex(1, r1, g1, b1, a1);
-				gfx_setcolorvertex(2, r1, g1, b1, a1);
-				gfx_setcolorvertex(3, r0, g0, b0, a0);
-
-				float x0 = envelope->points[i].time/1000.0f/end_time;
-//				float y0 = (fx2f(envelope->points[i].values[c])-bottom)/(top-bottom);
-				float x1 = envelope->points[i+1].time/1000.0f/end_time;
-				//float y1 = (fx2f(envelope->points[i+1].values[c])-bottom)/(top-bottom);
-				RECT v;
-				v.x = colorbar.x + x0*colorbar.w;
-				v.y = colorbar.y;
-				v.w = (x1-x0)*colorbar.w;
-				v.h = colorbar.h;
-				
-				gfx_quads_drawTL(v.x, v.y, v.w, v.h);
-			}
-			gfx_quads_end();
-		}
-		
-		// render handles
-		{
-			static bool move = false;
-			
-			int current_value = 0, current_time = 0;
-			
-			gfx_texture_set(-1);
-			gfx_quads_begin();
-			for(int c = 0; c < envelope->channels; c++)
-			{
-				if(!(active_channels&(1<<c)))
-					continue;
-				
-				for(int i = 0; i < envelope->points.len(); i++)
-				{
-					float x0 = envelope->points[i].time/1000.0f/end_time;
-					float y0 = (fx2f(envelope->points[i].values[c])-bottom)/(top-bottom);
-					RECT final;
-					final.x = view.x + x0*view.w;
-					final.y = view.y+view.h - y0*view.h;
-					final.x -= 2.0f;
-					final.y -= 2.0f;
-					final.w = 4.0f;
-					final.h = 4.0f;
-					
-					void *id = &envelope->points[i].values[c];
-					
-					if(ui_mouse_inside(&final))
-						ui_set_hot_item(id);
-						
-					float colormod = 1.0f;
-
-					if(ui_active_item() == id)
-					{
-						if(!ui_mouse_button(0))
-						{
-							ui_set_active_item(0);
-							move = false;
-						}
-						else
-						{
-							envelope->points[i].values[c] -= f2fx(editor.mouse_delta_y*valuescale);
-							if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-							{
-								if(i != 0)
-								{
-									envelope->points[i].time += (int)((editor.mouse_delta_x*timescale)*1000.0f);
-									if(envelope->points[i].time < envelope->points[i-1].time)
-										envelope->points[i].time = envelope->points[i-1].time + 1;
-									if(i+1 != envelope->points.len() && envelope->points[i].time > envelope->points[i+1].time)
-										envelope->points[i].time = envelope->points[i+1].time - 1;
-								}
-							}
-						}
-						
-						colormod = 100.0f;
-						gfx_setcolor(1,1,1,1);
-					}
-					else if(ui_hot_item() == id)
-					{
-						if(ui_mouse_button(0))
-						{
-							selection.clear();
-							selection.add(i);
-							ui_set_active_item(id);
-						}
-
-						// remove point
-						if(ui_mouse_button_clicked(1))
-							envelope->points.removebyindex(i);
-							
-						colormod = 100.0f;
-						gfx_setcolor(1,0.75f,0.75f,1);
-						editor.tooltip = "Left mouse to drag. Hold shift to alter time point aswell. Right click to delete.";
-					}
-
-					if(ui_active_item() == id || ui_hot_item() == id)
-					{
-						current_time = envelope->points[i].time;
-						current_value = envelope->points[i].values[c];
-					}
-					
-					gfx_setcolor(colors[c].r*colormod, colors[c].g*colormod, colors[c].b*colormod, 1.0f);
-					gfx_quads_drawTL(final.x, final.y, final.w, final.h);
-				}
-			}
-			gfx_quads_end();
-
-			char buf[512];
-			sprintf(buf, "%.3f %.3f", current_time/1000.0f, fx2f(current_value));
-			ui_do_label(&toolbar, buf, 14.0f, 0, -1);
-		}
-	}
-}
-
-static void editor_render()
-{
-	// basic start
-	gfx_clear(1.0f,0.0f,1.0f);
-	RECT view = *ui_screen();
-	gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
-	
-	// reset tip
-	editor.tooltip = 0;
-	
-	// render checker
-	render_background(view, checker_texture, 32.0f, 1.0f);
-	
-	RECT modebar, toolbar, statusbar, envelope_editor, propsbar;
-	
-	if(editor.gui_active)
-	{
-		
-		ui_hsplit_t(&view, 16.0f, &toolbar, &view);
-		ui_vsplit_l(&view, 80.0f, &propsbar, &view);
-		ui_hsplit_b(&view, 16.0f, &view, &statusbar);
-
-				
-		float brightness = 0.25f;
-
-		render_background(propsbar, background_texture, 128.0f, brightness);
-		ui_margin(&propsbar, 2.0f, &propsbar);
-		
-		render_background(toolbar, background_texture, 128.0f, brightness);
-		ui_margin(&toolbar, 2.0f, &toolbar);
-		ui_vsplit_l(&toolbar, 220.0f, &modebar, &toolbar);
-
-		render_background(statusbar, background_texture, 128.0f, brightness);
-		ui_margin(&statusbar, 2.0f, &statusbar);
-		
-		if(editor.show_envelope_editor)
-		{
-			float size = 125.0f;
-			if(editor.show_envelope_editor == 2)
-				size *= 2.0f;
-			else if(editor.show_envelope_editor == 3)
-				size *= 3.0f;
-			ui_hsplit_b(&view, size, &view, &envelope_editor);
-			render_background(envelope_editor, background_texture, 128.0f, brightness);
-			ui_margin(&envelope_editor, 2.0f, &envelope_editor);
-		}
-	}
-	
-	if(editor.dialog == DIALOG_LOAD_IMAGE)
-		render_dialog_load_image();
-	else if(editor.mode == MODE_LAYERS)
-		render_layers(propsbar, toolbar, view);
-	else if(editor.mode == MODE_IMAGES)
-		render_images(propsbar, view);
-		
-	gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
-
-	if(editor.gui_active)
-	{
-		render_modebar(modebar);
-		if(editor.show_envelope_editor)
-			render_envelopeeditor(envelope_editor);
-		render_statusbar(statusbar);
-	}
-	
-	//do_propsdialog();
-
-	// render butt ugly mouse cursor
-	float mx = ui_mouse_x();
-	float my = ui_mouse_y();
-	gfx_texture_set(cursor_texture);
-	gfx_quads_begin();
-	gfx_quads_drawTL(mx,my, 16.0f, 16.0f);
-	gfx_quads_end();	
-}
-
-void editor_reset(bool create_default=true)
-{
-	editor.map.groups.deleteall();
-	editor.map.envelopes.deleteall();
-	editor.map.images.deleteall();
-	
-	editor.game_layer = 0;
-	editor.game_group = 0;
-
-	// create default layers
-	if(create_default)
-	{
-		editor.make_game_group(editor.map.new_group());
-		editor.make_game_layer(new LAYER_GAME(50, 50));
-		editor.game_group->add_layer(editor.game_layer);
-	}
-}
-
-void EDITOR::make_game_layer(LAYER *layer)
-{
-	editor.game_layer = (LAYER_GAME *)layer;
-	editor.game_layer->tex_id = entities_texture;
-	editor.game_layer->readonly = true;
-}
-
-void EDITOR::make_game_group(LAYERGROUP *group)
-{
-	editor.game_group = group;
-	editor.game_group->game_group = true;
-	editor.game_group->name = "Game";
-}
-
-typedef struct 
-{
-	int version;
-	int width;
-	int height;
-	int external;
-	int image_name;
-	int image_data;
-} MAPITEM_IMAGE;
-
-typedef struct
-{
-	int version;
-	int offset_x;
-	int offset_y;
-	int parallax_x;
-	int parallax_y;
-
-	int start_layer;
-	int num_layers;
-} MAPITEM_GROUP;
-
-typedef struct
-{
-	int version;
-	int type;
-	int flags;
-} MAPITEM_LAYER;
-
-typedef struct
-{
-	MAPITEM_LAYER layer;
-	int version;
-	
-	int width;
-	int height;
-	int flags;
-	
-	COLOR color;
-	int color_env;
-	int color_env_offset;
-	
-	int image;
-	int data;
-} MAPITEM_LAYER_TILEMAP;
-
-typedef struct
-{
-	MAPITEM_LAYER layer;
-	int version;
-	
-	int num_quads;
-	int data;
-	int image;
-} MAPITEM_LAYER_QUADS;
-
-typedef struct
-{
-	int version;
-} MAPITEM_VERSION;
-
-template<typename T>
-static int make_version(int i, const T &v)
-{ return (i<<16)+sizeof(T); }
-
-enum
-{
-	MAPITEMTYPE_VERSION=0,
-	MAPITEMTYPE_INFO,
-	MAPITEMTYPE_IMAGE,
-	MAPITEMTYPE_ENVELOPE,
-	MAPITEMTYPE_GROUP,
-	MAPITEMTYPE_LAYER,
-};
-
-
-void editor_load_old(DATAFILE *df)
-{
-	// load tilemaps
-	int game_width = 0;
-	int game_height = 0;
-	{
-		int start, num;
-		datafile_get_type(df, MAPRES_TILEMAP, &start, &num);
-		for(int t = 0; t < num; t++)
-		{
-			mapres_tilemap *tmap = (mapres_tilemap *)datafile_get_item(df, start+t,0,0);
-			
-			LAYER_TILES *l = new LAYER_TILES(tmap->width, tmap->height);
-			
-			if(tmap->main)
-			{
-				// move game layer to correct position
-				for(int i = 0; i < editor.map.groups[0]->layers.len()-1; i++)
-				{
-					if(editor.map.groups[0]->layers[i] == editor.game_layer)
-						editor.map.groups[0]->swap_layers(i, i+1);
-				}
-				
-				game_width = tmap->width;
-				game_height = tmap->height;
-			}
-
-			// add new layer
-			editor.map.groups[0]->add_layer(l);
-
-			// process the data
-			unsigned char *src_data = (unsigned char *)datafile_get_data(df, tmap->data);
-			TILE *dst_data = l->tiles;
-			
-			for(int y = 0; y < tmap->height; y++)
-				for(int x = 0; x < tmap->width; x++, dst_data++, src_data+=2)
-				{
-					dst_data->index = src_data[0];
-					dst_data->flags = src_data[1];
-				}
-				
-			l->image = tmap->image;
-		}
-	}
-	
-	// load images
-	{
-		int start, count;
-		datafile_get_type(df, MAPRES_IMAGE, &start, &count);
-		for(int i = 0; i < count; i++)
-		{
-			mapres_image *imgres = (mapres_image *)datafile_get_item(df, start+i, 0, 0);
-			void *data = datafile_get_data(df, imgres->image_data);
-
-			IMAGE *img = new IMAGE;
-			img->width = imgres->width;
-			img->height = imgres->height;
-			img->format = IMG_RGBA;
-			
-			// copy image data
-			img->data = mem_alloc(img->width*img->height*4, 1);
-			mem_copy(img->data, data, img->width*img->height*4);
-			img->tex_id = gfx_load_texture_raw(img->width, img->height, img->format, img->data, IMG_AUTO);
-			editor.map.images.add(img);
-			
-			// unload image
-			datafile_unload_data(df, imgres->image_data);
-		}
-	}
-	
-	// load entities
-	{
-		LAYER_GAME *g = editor.game_layer;
-		g->resize(game_width, game_height);
-		for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++)
-		{
-			// fetch entities of this class
-			int start, num;
-			datafile_get_type(df, t, &start, &num);
-
-
-			for(int i = 0; i < num; i++)
-			{
-				mapres_entity *e = (mapres_entity *)datafile_get_item(df, start+i,0,0);
-				int x = e->x/32;
-				int y = e->y/32;
-				int id = -1;
-					
-				if(t == MAPRES_SPAWNPOINT) id = ENTITY_SPAWN;
-				else if(t == MAPRES_SPAWNPOINT_RED) id = ENTITY_SPAWN_RED;
-				else if(t == MAPRES_SPAWNPOINT_BLUE) id = ENTITY_SPAWN_BLUE;
-				else if(t == MAPRES_FLAGSTAND_RED) id = ENTITY_FLAGSTAND_RED;
-				else if(t == MAPRES_FLAGSTAND_BLUE) id = ENTITY_FLAGSTAND_BLUE;
-				else if(t == MAPRES_ITEM)
-				{
-					if(e->data[0] == ITEM_WEAPON_SHOTGUN) id = ENTITY_WEAPON_SHOTGUN;
-					else if(e->data[0] == ITEM_WEAPON_ROCKET) id = ENTITY_WEAPON_ROCKET;
-					else if(e->data[0] == ITEM_NINJA) id = ENTITY_POWERUP_NINJA;
-					else if(e->data[0] == ITEM_ARMOR) id = ENTITY_ARMOR_1;
-					else if(e->data[0] == ITEM_HEALTH) id = ENTITY_HEATH_1;
-				}
-						
-				if(id > 0 && x >= 0 && x < g->width && y >= 0 && y < g->height)
-					g->tiles[y*g->width+x].index = id;
-			}
-		}
-	}
-}
-
-int EDITOR::save(const char *filename)
-{
-	dbg_msg("editor", "saving to '%s'...", filename);
-	DATAFILE_OUT *df = datafile_create(filename);
-	if(!df)
-	{
-		dbg_msg("editor", "failed to open file '%s'...", filename);
-		return 0;
-	}
-		
-	// save version
-	{
-		MAPITEM_VERSION item;
-		item.version = 1;
-		datafile_add_item(df, MAPITEMTYPE_VERSION, 0, sizeof(item), &item);
-	}
-
-	// save images
-	for(int i = 0; i < map.images.len(); i++)
-	{
-		IMAGE *img = map.images[i];
-		MAPITEM_IMAGE item;
-		item.version = 1;
-		
-		item.width = img->width;
-		item.height = img->height;
-		item.external = 0;
-		item.image_name = -1;
-		item.image_data = datafile_add_data(df, item.width*item.height*4, img->data);
-		datafile_add_item(df, MAPITEMTYPE_IMAGE, i, sizeof(item), &item);
-	}
-	
-	// save layers
-	int layer_count = 0;
-	for(int g = 0; g < map.groups.len(); g++)
-	{
-		LAYERGROUP *group = map.groups[g];
-		MAPITEM_GROUP gitem;
-		gitem.version = 1;
-		
-		gitem.parallax_x = group->parallax_x;
-		gitem.parallax_y = group->parallax_y;
-		gitem.offset_x = group->offset_x;
-		gitem.offset_y = group->offset_y;
-		gitem.start_layer = layer_count;
-		gitem.num_layers = 0;
-		
-		for(int l = 0; l < group->layers.len(); l++)
-		{
-			if(group->layers[l]->type == LAYERTYPE_TILES)
-			{
-				dbg_msg("editor", "saving tiles layer");
-				LAYER_TILES *layer = (LAYER_TILES *)group->layers[l];
-				MAPITEM_LAYER_TILEMAP item;
-				item.version = 2;
-				
-				item.layer.flags = 0;
-				item.layer.type = layer->type;
-				
-				item.color.r = 255; // not in use right now
-				item.color.g = 255;
-				item.color.b = 255;
-				item.color.a = 255;
-				item.color_env = -1;
-				item.color_env_offset = 0;
-				
-				item.width = layer->width;
-				item.height = layer->height;
-				item.flags = layer->game;
-				item.image = layer->image;
-				item.data = datafile_add_data(df, layer->width*layer->height*sizeof(TILE), layer->tiles);
-				datafile_add_item(df, MAPITEMTYPE_LAYER, layer_count, sizeof(item), &item);
-				
-				gitem.num_layers++;
-				layer_count++;
-			}
-			else if(group->layers[l]->type == LAYERTYPE_QUADS)
-			{
-				dbg_msg("editor", "saving quads layer");
-				LAYER_QUADS *layer = (LAYER_QUADS *)group->layers[l];
-				if(layer->quads.len())
-				{
-					MAPITEM_LAYER_QUADS item;
-					item.version = 1;
-					item.layer.flags = 0;
-					item.layer.type = layer->type;
-					item.image = layer->image;
-					
-					// add the data
-					item.num_quads = layer->quads.len();
-					item.data = datafile_add_data_swapped(df, layer->quads.len()*sizeof(QUAD), layer->quads.getptr());
-					datafile_add_item(df, MAPITEMTYPE_LAYER, layer_count, sizeof(item), &item);
-					
-					// clean up
-					//mem_free(quads);
-
-					gitem.num_layers++;
-					layer_count++;
-				}
-			}
-		}
-		
-		datafile_add_item(df, MAPITEMTYPE_GROUP, g, sizeof(gitem), &gitem);
-	}
-	
-	// finish the data file
-	datafile_finish(df);
-	dbg_msg("editor", "done");
-	return 1;
-}
-
-
-int EDITOR::load(const char *filename)
-{
-	DATAFILE *df = datafile_load(filename);
-	if(!df)
-		return 0;
-
-	// check version
-	MAPITEM_VERSION *item = (MAPITEM_VERSION *)datafile_find_item(df, MAPITEMTYPE_VERSION, 0);
-	if(!item)
-	{
-		// import old map
-		editor_reset();
-		editor_load_old(df);
-	}
-	else if(item->version == 1)
-	{
-		editor_reset(false);
-		
-		// load images
-		{
-			int start, num;
-			datafile_get_type(df, MAPITEMTYPE_IMAGE, &start, &num);
-			for(int i = 0; i < num; i++)
-			{
-				MAPITEM_IMAGE *item = (MAPITEM_IMAGE *)datafile_get_item(df, start+i, 0, 0);
-				void *data = datafile_get_data(df, item->image_data);
-				
-				IMAGE *img = new IMAGE;
-				img->width = item->width;
-				img->height = item->height;
-				img->format = IMG_RGBA;
-				
-				// copy image data
-				img->data = mem_alloc(img->width*img->height*4, 1);
-				mem_copy(img->data, data, img->width*img->height*4);
-				img->tex_id = gfx_load_texture_raw(img->width, img->height, img->format, img->data, IMG_AUTO);
-				editor.map.images.add(img);
-				
-				// unload image
-				datafile_unload_data(df, item->image_data);
-			}
-		}
-		
-		// load groups
-		{
-			int layers_start, layers_num;
-			datafile_get_type(df, MAPITEMTYPE_LAYER, &layers_start, &layers_num);
-			
-			int start, num;
-			datafile_get_type(df, MAPITEMTYPE_GROUP, &start, &num);
-			for(int g = 0; g < num; g++)
-			{
-				MAPITEM_GROUP *gitem = (MAPITEM_GROUP *)datafile_get_item(df, start+g, 0, 0);
-				LAYERGROUP *group = map.new_group();
-				group->parallax_x = gitem->parallax_x;
-				group->parallax_y = gitem->parallax_y;
-				group->offset_x = gitem->offset_x;
-				group->offset_y = gitem->offset_y;
-				
-				for(int l = 0; l < gitem->num_layers; l++)
-				{
-					MAPITEM_LAYER *layer_item = (MAPITEM_LAYER *)datafile_get_item(df, layers_start+gitem->start_layer+l, 0, 0);
-					if(!layer_item)
-						continue;
-						
-					if(layer_item->type == LAYERTYPE_TILES)
-					{
-						MAPITEM_LAYER_TILEMAP *tilemap_item = (MAPITEM_LAYER_TILEMAP *)layer_item;
-						LAYER_TILES *tiles = 0;
-						
-						if(tilemap_item->flags&1)
-						{
-							tiles = new LAYER_GAME(tilemap_item->width, tilemap_item->height);
-							editor.make_game_layer(tiles);
-							make_game_group(group);
-						}
-						else
-							tiles = new LAYER_TILES(tilemap_item->width, tilemap_item->height);
-						
-						group->add_layer(tiles);
-						void *data = datafile_get_data(df, tilemap_item->data);
-						tiles->image = tilemap_item->image;
-						tiles->game = tilemap_item->flags&1;
-						
-						mem_copy(tiles->tiles, data, tiles->width*tiles->height*sizeof(TILE));
-						
-						if(tiles->game && tilemap_item->version == make_version(1, *tilemap_item))
-						{
-							for(int i = 0; i < tiles->width*tiles->height; i++)
-							{
-								if(tiles->tiles[i].index)
-									tiles->tiles[i].index += ENTITY_OFFSET;
-							}
-						}
-						
-						datafile_unload_data(df, tilemap_item->data);
-					}
-					else if(layer_item->type == LAYERTYPE_QUADS)
-					{
-						MAPITEM_LAYER_QUADS *quads_item = (MAPITEM_LAYER_QUADS *)layer_item;
-						LAYER_QUADS *layer = new LAYER_QUADS;
-						layer->image = quads_item->image;
-						if(layer->image < -1 || layer->image >= map.images.len())
-							layer->image = -1;
-						void *data = datafile_get_data_swapped(df, quads_item->data);
-						group->add_layer(layer);
-						layer->quads.setsize(quads_item->num_quads);
-						mem_copy(layer->quads.getptr(), data, sizeof(QUAD)*quads_item->num_quads);
-						datafile_unload_data(df, quads_item->data);
-					}
-				}
-			}
-		}
-	}
-	
-	datafile_unload(df);
-	
-	return 0;
-}
-
-
-extern "C" void editor_init()
-{
-	checker_texture = gfx_load_texture("data/editor/checker.png", IMG_AUTO);
-	background_texture = gfx_load_texture("data/editor/background.png", IMG_AUTO);
-	cursor_texture = gfx_load_texture("data/editor/cursor.png", IMG_AUTO);
-	entities_texture = gfx_load_texture("data/editor/entities.png", IMG_AUTO);
-	
-	tileset_picker.make_palette();
-	tileset_picker.readonly = true;
-	
-	editor_reset();
-	//editor.load("debug_test.map");
-	
-#if 0
-	IMAGE *img = new IMAGE;
-	gfx_load_png(img, "tilesets/grassland_main.png");
-	img->tex_id = gfx_load_texture_raw(img->width, img->height, img->format, img->data);
-	editor.map.images.add(img);
-	
-
-	ENVELOPE *e = editor.map.new_envelope(4);
-	e->add_point(0, 0, 0);
-	e->add_point(1000, f2fx(1), f2fx(0.75f));
-	e->add_point(2000, f2fx(0.75f), f2fx(1));
-	e->add_point(3000, 0, 0);
-	
-	editor.animate = true;
-	editor.animate_start = time_get();
-	
-	editor.show_envelope_editor = 1;
-#endif
-
-	if(1)
-	{
-		float w, h;
-		float amount = 1300*1000;
-		float max = 1500;
-		dbg_msg("", "%f %f %f %f", (900*(5/4.0f))*900.0f, (900*(4/3.0f))*900.0f, (900*(16/9.0f))*900.0f, (900*(16/10.0f))*900.0f);
-		dbg_msg("", "%f", 900*(16/9.0f));
-		calc_screen_params(amount, max, max, 5.0f/4.0f, &w, &h); dbg_msg("", "5:4 %f %f %f", w, h, w*h);
-		calc_screen_params(amount, max, max, 4.0f/3.0f, &w, &h); dbg_msg("", "4:3 %f %f %f", w, h, w*h);
-		calc_screen_params(amount, max, max, 16.0f/9.0f, &w, &h); dbg_msg("", "16:9 %f %f %f", w, h, w*h);
-		calc_screen_params(amount, max, max, 16.0f/10.0f, &w, &h); dbg_msg("", "16:10 %f %f %f", w, h, w*h);
-		
-		calc_screen_params(amount, max, max, 9.0f/16.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h);
-		calc_screen_params(amount, max, max, 16.0f/3.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h);
-		calc_screen_params(amount, max, max, 3.0f/16.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h);
-	}
-}
-
-extern "C" void editor_update_and_render()
-{
-	static int mouse_x = 0;
-	static int mouse_y = 0;
-
-	editor.animate_time = (time_get()-editor.animate_start)/(float)time_freq();
-
-	// handle mouse movement
-	float mx, my, mwx, mwy;
-	int rx, ry;
-	{
-		inp_mouse_relative(&rx, &ry);
-		editor.mouse_delta_x = rx;
-		editor.mouse_delta_y = ry;
-		
-		if(!editor.lock_mouse)
-		{
-			mouse_x += rx;
-			mouse_y += ry;
-		}
-		
-		if(mouse_x < 0) mouse_x = 0;
-		if(mouse_y < 0) mouse_y = 0;
-		if(mouse_x >= ui_screen()->w) mouse_x = (int)ui_screen()->w-1;
-		if(mouse_y >= ui_screen()->h) mouse_y = (int)ui_screen()->h-1;
-
-		// update the ui
-		mx = mouse_x;
-		my = mouse_y;
-		mwx = 0;
-		mwy = 0;
-		
-		// fix correct world x and y
-		LAYERGROUP *g = editor.get_selected_group();
-		if(g)
-		{
-			float points[4];
-			g->mapping(points);
-
-			float world_width = points[2]-points[0];
-			float world_height = points[3]-points[1];
-			
-			mwx = points[0] + world_width * (mouse_x/ui_screen()->w);
-			mwy = points[1] + world_height * (mouse_y/ui_screen()->h);
-			editor.mouse_delta_wx = editor.mouse_delta_x*(world_width / ui_screen()->w);
-			editor.mouse_delta_wy = editor.mouse_delta_y*(world_height / ui_screen()->h);
-		}
-		
-		int buttons = 0;
-		if(inp_key_pressed(KEY_MOUSE_1)) buttons |= 1;
-		if(inp_key_pressed(KEY_MOUSE_2)) buttons |= 2;
-		if(inp_key_pressed(KEY_MOUSE_3)) buttons |= 4;
-		
-		ui_update(mx,my,mwx,mwy,buttons);
-	}
-	
-	// toggle gui
-	if(inp_key_down(KEY_TAB))
-		editor.gui_active = !editor.gui_active;
-
-	if(inp_key_down(KEY_F5))
-		editor.save("data/maps/debug_test2.map");
-	
-	if(inp_key_down(KEY_F8))
-		editor.load("data/maps/debug_test.map");
-	
-	editor_render();
-	inp_clear_events();
-}
-
diff --git a/src/editor/editor.hpp b/src/editor/editor.hpp
deleted file mode 100644
index fb2b2368..00000000
--- a/src/editor/editor.hpp
+++ /dev/null
@@ -1,568 +0,0 @@
-#include <stdlib.h>
-#include <math.h>
-#include "array.h"
-
-extern "C" {
-	#include <engine/e_system.h>
-	#include <engine/client/ec_ui.h>
-	#include <engine/e_interface.h>
-	#include <engine/e_datafile.h>
-	#include <engine/e_config.h>
-}
-
-// EDITOR SPECIFIC
-template<typename T>
-void swap(T &a, T &b)
-{
-	T tmp = a;
-	a = b;
-	b = tmp;
-}
-
-enum
-{
-	MODE_MAP=0,
-	MODE_LAYERS,
-	MODE_IMAGES,
-	
-	DIALOG_NONE=0,
-	DIALOG_LOAD_IMAGE,
-	
-	LAYERTYPE_INVALID=0,
-	LAYERTYPE_GAME,
-	LAYERTYPE_TILES,
-	LAYERTYPE_QUADS,
-};
-
-typedef struct
-{
-	int x, y; // 22.10 fixed point
-} POINT;
-
-// float to fixed
-inline int f2fx(float v) { return (int)(v*(float)(1<<10)); }
-inline float fx2f(int v) { return v*(1.0f/(1<<10)); }
-
-typedef struct // as in file
-{
-	int r, g, b, a;
-} COLOR;
-
-typedef struct // as in file
-{
-	POINT points[5];
-	COLOR colors[4];
-	POINT texcoords[4];
-	
-	int pos_env;
-	int pos_env_offset;
-	
-	int color_env;
-	int color_env_offset;
-} QUAD;
-
-typedef struct // as in file
-{
-	POINT position;
-	int type;
-} ENTITY;
-
-enum
-{
-	ENTITY_NULL=0,
-	ENTITY_SPAWN,
-	ENTITY_SPAWN_RED,
-	ENTITY_SPAWN_BLUE,
-	ENTITY_FLAGSTAND_RED,
-	ENTITY_FLAGSTAND_BLUE,
-	ENTITY_ARMOR_1,
-	ENTITY_HEATH_1,
-	ENTITY_WEAPON_SHOTGUN,
-	ENTITY_WEAPON_ROCKET,
-	ENTITY_POWERUP_NINJA,
-	NUM_ENTITIES,
-	
-	TILE_AIR=0,
-	TILE_SOLID,
-	TILE_NOHOOK,
-	
-	ENTITY_OFFSET=255-16*4,
-};
-
-typedef struct // as in file
-{
-	unsigned char index;
-	unsigned char flags;
-	unsigned char reserved1;
-	unsigned char reserved2;
-} TILE;
-
-enum
-{
-	CURVETYPE_STEP=0,
-	CURVETYPE_LINEAR,
-	CURVETYPE_SLOW,
-	CURVETYPE_FAST,
-	CURVETYPE_SMOOTH,
-	NUM_CURVETYPES,
-	
-};
-
-typedef struct // as in file
-{
-	int time; // in ms
-	int curvetype;
-	int values[4]; // 1-4 depending on envelope (22.10 fixed point)
-} ENVPOINT;
-
-class ENVELOPE
-{
-public:
-	int channels;
-	array<ENVPOINT> points;
-	char name[32];
-	float bottom, top;
-	
-	ENVELOPE(int chan)
-	{
-		channels = chan;
-		name[0] = 0;
-		bottom = 0;
-		top = 0;
-	}
-	
-	static int sort_comp(const void *v0, const void *v1)
-	{
-		const ENVPOINT *p0 = (const ENVPOINT *)v0;
-		const ENVPOINT *p1 = (const ENVPOINT *)v1;
-		if(p0->time < p1->time)
-			return -1;
-		if(p0->time > p1->time)
-			return 1;
-		return 0;
-	}
-	
-	void resort()
-	{
-		qsort(points.getptr(), points.len(), sizeof(ENVPOINT), sort_comp);
-		find_top_bottom();
-	}
-
-	void find_top_bottom()
-	{
-		top = -1000000000.0f;
-		bottom = 1000000000.0f;
-		for(int i = 0; i < points.len(); i++)
-		{
-			for(int c = 0; c < channels; c++)
-			{
-				float v = fx2f(points[i].values[c]);
-				if(v > top) top = v;
-				if(v < bottom) bottom = v;
-			}
-		}
-	}
-	
-	float eval(float time, int channel)
-	{
-		if(channel >= channels)
-			return 0;
-		if(points.len() == 0)
-			return 0;
-		if(points.len() == 1)
-			return points[0].values[channel];
-		
-		time = fmod(time, end_time())*1000.0f;
-		for(int i = 0; i < points.len() - 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;
-				
-				float v0 = fx2f(points[i].values[channel]);
-				float v1 = fx2f(points[i+1].values[channel]);
-				
-				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
-				}
-		
-				return v0 + (v1-v0) * a;
-			}
-		}
-		
-		return points[points.len()-1].values[channel];
-	}
-	
-	void add_point(int time, int v0, int v1=0, int v2=0, int v3=0)
-	{
-		ENVPOINT p;
-		p.time = time;
-		p.values[0] = v0;
-		p.values[1] = v1;
-		p.values[2] = v2;
-		p.values[3] = v3;
-		p.curvetype = CURVETYPE_LINEAR;
-		points.add(p);
-		resort();
-	}
-	
-	float end_time()
-	{
-		if(points.len())
-			return points[points.len()-1].time*(1.0f/1000.0f);
-		return 0;
-	}
-};
-
-
-class LAYER;
-class LAYERGROUP;
-class MAP;
-
-class LAYER
-{
-public:
-	LAYER()
-	{
-		type = LAYERTYPE_INVALID;
-		type_name = "(invalid)";
-		visible = true;
-		readonly = false;
-	}
-	
-	virtual ~LAYER()
-	{
-	}
-	
-	
-	virtual void brush_selecting(RECT rect) {}
-	virtual int brush_grab(LAYERGROUP *brush, RECT rect) { return 0; }
-	virtual void brush_draw(LAYER *brush, float x, float y) {}
-	virtual void brush_place(LAYER *brush, float x, float y) {}
-	virtual void brush_flip_x() {}
-	virtual void brush_flip_y() {}
-	
-	virtual void render() {}
-	virtual void render_properties(RECT *toolbox) {}
-	
-	virtual void get_size(float *w, float *h) { *w = 0; *h = 0;}
-	
-	const char *type_name;
-	int type;
-
-	bool readonly;
-	bool visible;
-};
-
-class LAYERGROUP
-{
-public:
-	array<LAYER*> layers;
-	
-	int offset_x;
-	int offset_y;
-
-	int parallax_x;
-	int parallax_y;
-	
-	const char *name;
-	bool game_group;
-	bool visible;
-	
-	LAYERGROUP();
-	~LAYERGROUP();
-	
-	void convert(RECT *rect);
-	void render();
-	void mapscreen();
-	void mapping(float *points);
-	
-	bool is_empty() const;
-	void clear();
-	void add_layer(LAYER *l);
-
-	void get_size(float *w, float *h);
-	
-	void delete_layer(int index);
-	int swap_layers(int index0, int index1);
-};
-
-class IMAGE : public IMAGE_INFO
-{
-public:
-	IMAGE()
-	{
-		tex_id = -1;
-		name[0] = 0;
-	}
-	
-	int tex_id;
-	char name[128];
-};
-
-class MAP
-{
-public:
-	array<LAYERGROUP*> groups;
-	array<IMAGE*> images;
-	array<ENVELOPE*> envelopes;
-	
-	ENVELOPE *new_envelope(int channels)
-	{
-		ENVELOPE *e = new ENVELOPE(channels);
-		envelopes.add(e);
-		return e;
-	}
-	
-	LAYERGROUP *new_group()
-	{
-		LAYERGROUP *g = new LAYERGROUP;
-		groups.add(g);
-		return g;
-	}
-	
-	int swap_groups(int index0, int index1)
-	{
-		if(index0 < 0 || index0 >= groups.len()) return index0;
-		if(index1 < 0 || index1 >= groups.len()) return index0;
-		if(index0 == index1) return index0;
-		swap(groups[index0], groups[index1]);
-		return index1;
-	}
-	
-	void delete_group(int index)
-	{
-		if(index < 0 || index >= groups.len()) return;
-		delete groups[index];
-		groups.removebyindex(index);
-	}
-};
-
-
-struct PROPERTY
-{
-	const char *name;
-	int value;
-	int type;
-	int min;
-	int max;
-};
-
-enum
-{
-	PROPTYPE_NULL=0,
-	PROPTYPE_INT_STEP,
-	PROPTYPE_INT_SCROLL,
-	PROPTYPE_COLOR,
-	
-	PROPS_NONE=0,
-	PROPS_GROUP,
-	PROPS_LAYER,
-	PROPS_QUAD,
-	PROPS_QUAD_POINT,
-};
-
-class EDITOR
-{
-public:	
-	EDITOR()
-	{
-		mode = MODE_LAYERS;
-		dialog = 0;
-		tooltip = 0;
-
-		world_offset_x = 0;
-		world_offset_y = 0;
-		editor_offset_x = 0.0f;
-		editor_offset_y = 0.0f;
-		
-		world_zoom = 1.0f;
-		zoom_level = 100;
-		lock_mouse = false;
-		mouse_delta_x = 0;
-		mouse_delta_y = 0;
-		mouse_delta_wx = 0;
-		mouse_delta_wy = 0;
-		
-		gui_active = true;
-		proof_borders = false;
-		
-		
-		animate = false;
-		animate_start = 0;
-		animate_time = 0;
-		
-		props = PROPS_NONE;
-		
-		show_envelope_editor = 0;
-	}
-	
-	void make_game_group(LAYERGROUP *group);
-	void make_game_layer(LAYER *layer);
-	
-	int save(const char *filename);
-	int load(const char *filename);
-
-	QUAD *get_selected_quad();
-	LAYER *get_selected_layer_type(int index, int type);
-	LAYER *get_selected_layer(int index);
-	LAYERGROUP *get_selected_group();
-	
-	class LAYER_GAME *game_layer;
-	LAYERGROUP *game_group;
-	
-	int do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val);
-	
-	int mode;
-	int dialog;
-	const char *tooltip;
-
-	float world_offset_x;
-	float world_offset_y;
-	float editor_offset_x;
-	float editor_offset_y;
-	float world_zoom;
-	int zoom_level;
-	bool lock_mouse;
-	bool gui_active;
-	bool proof_borders;
-	float mouse_delta_x;
-	float mouse_delta_y;
-	float mouse_delta_wx;
-	float mouse_delta_wy;
-	
-	bool animate;
-	int64 animate_start;
-	float animate_time;
-	
-	int props;
-	
-	int show_envelope_editor;
-	
-	MAP map;
-};
-
-extern EDITOR editor;
-
-typedef struct
-{
-	int x, y;
-	int w, h;
-} RECTi;
-
-class LAYER_TILES : public LAYER
-{
-public:
-	LAYER_TILES(int w, int h);
-	~LAYER_TILES();
-
-	void resize(int new_w, int new_h);
-
-	void make_palette();
-	virtual void render();
-
-	int convert_x(float x) const;
-	int convert_y(float y) const;
-	void convert(RECT rect, RECTi *out);
-	void snap(RECT *rect);
-	void clamp(RECTi *rect);
-
-	virtual void brush_selecting(RECT rect);
-	virtual int brush_grab(LAYERGROUP *brush, RECT rect);
-	virtual void brush_draw(LAYER *brush, float wx, float wy);
-	virtual void brush_flip_x();
-	virtual void brush_flip_y();
-	
-	virtual void render_properties(RECT *toolbox);
-
-	void get_size(float *w, float *h) { *w = width*32.0f;  *h = height*32.0f; }
-	
-	int tex_id;
-	int game;
-	int image;
-	int width;
-	int height;
-	TILE *tiles;
-};
-
-class LAYER_QUADS : public LAYER
-{
-public:
-	LAYER_QUADS();
-	~LAYER_QUADS();
-
-	virtual void render();
-	QUAD *new_quad();
-
-	virtual void brush_selecting(RECT rect);
-	virtual int brush_grab(LAYERGROUP *brush, RECT rect);
-	virtual void brush_place(LAYER *brush, float wx, float wy);
-	virtual void brush_flip_x();
-	virtual void brush_flip_y();
-	
-	virtual void render_properties(RECT *toolbox);
-	
-	void get_size(float *w, float *h);
-	
-	int image;
-	array<QUAD> quads;
-};
-
-
-class LAYER_GAME : public LAYER_TILES
-{
-public:
-	LAYER_GAME(int w, int h);
-	~LAYER_GAME();
-
-	virtual void render_properties(RECT *toolbox);
-};
-
-
-inline void calc_screen_params(float amount, float wmax, float hmax, float aspect, float *w, float *h)
-{
-	float f = sqrt(amount) / sqrt(aspect);
-	*w = f*aspect;
-	*h = f;
-	
-	// limit the view
-	if(*w > wmax)
-	{
-		*w = wmax;
-		*h = *w/aspect;
-	}
-	
-	if(*h > hmax)
-	{
-		*h = hmax;
-		*w = *h*aspect;
-	}
-}
-
-inline void mapscreen_to_world(float center_x, float center_y, float parallax_x, float parallax_y,
-	float offset_x, float offset_y, float aspect, float zoom, float *points)
-{
-	float width, height;
-	calc_screen_params(1300*1000, 1500, 1050, aspect, &width, &height);
-	center_x *= parallax_x;
-	center_y *= parallax_y;
-	width *= zoom;
-	height *= zoom;
-	points[0] = offset_x+center_x-width/2;
-	points[1] = offset_y+center_y-height/2;
-	points[2] = offset_x+center_x+width/2;
-	points[3] = offset_y+center_y+height/2;
-}