about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2007-12-02 17:55:45 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2007-12-02 17:55:45 +0000
commite96ad33a3473b7db60f88e7b6c59630cacd147c3 (patch)
treeeb41ebea8f83ce4e5676cce99193850f1ef4a892 /src
parent59f0a07555c124e14185dd29078b3b5e99ea09d8 (diff)
downloadzcatch-e96ad33a3473b7db60f88e7b6c59630cacd147c3.tar.gz
zcatch-e96ad33a3473b7db60f88e7b6c59630cacd147c3.zip
fixed the editor
Diffstat (limited to 'src')
-rw-r--r--src/editor/editor.cpp643
-rw-r--r--src/engine/client/client.c208
-rw-r--r--src/engine/client/gfx.c108
-rw-r--r--src/engine/interface.h26
-rw-r--r--src/game/client/game_client.cpp21
-rw-r--r--src/game/client/menu.cpp4
-rw-r--r--src/game/client/menu2.cpp51
7 files changed, 579 insertions, 482 deletions
diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp
index 3586629b..aa5a493d 100644
--- a/src/editor/editor.cpp
+++ b/src/editor/editor.cpp
@@ -105,6 +105,7 @@ struct tilemap
 {
 	int width;
 	int height;
+	int render_flags;
 	tile *tiles;
 };
 
@@ -116,6 +117,7 @@ static void tilemap_new(tilemap *tm, int width, int height)
 	
 	tm->width = width;
 	tm->height = height;
+	tm->render_flags = 0;
 	tm->tiles = (tile *)mem_alloc(size, 1);
 	mem_zero(tm->tiles, size);
 }
@@ -219,6 +221,7 @@ static const int MAX_LAYERS = 64;
 static layer layers[MAX_LAYERS];
 static int num_layers = 0;
 static int current_layer = 0;
+static int current_hover_layer = -1;
 
 static int layers_remove(int index)
 {
@@ -377,10 +380,20 @@ static tileset *tilesets_get(int index)
 /********************************************************
  UI                                                      
 *********************************************************/
-static void render_tilemap(tilemap *tm, float sx, float sy, float scale)
+
+static const int TILEMAPFLAG_READONLY = 1;
+static const int TILEMAPFLAG_UISPACE = 2;
+static const int TILEMAPFLAG_HILIGHTED = 4;
+
+static void render_tilemap(tilemap *tm, float sx, float sy, float scale, int flags)
 {
 	float frac = (1.0f/1024.0f); //2.0f;
+	
 	gfx_quads_begin();
+	
+	if(flags&TILEMAPFLAG_HILIGHTED)
+		gfx_setcolor(1.0f,0.5f,0.5f,1.0f);
+	
 	for(int y = 0; y < tm->height; y++)
 		for(int x = 0; x < tm->width; x++)
 		{
@@ -444,17 +457,13 @@ static const char *editor_filename = 0;
 static int editor_mode = 0; // 0 == tiles, 1 == ents
 static int editor_selected_ent = -1;
 
-static const int TILEMAPFLAG_READONLY = 1;
-static const int TILEMAPFLAG_UISPACE = 2;
-
 static int ui_do_tilemap(void *id, tilemap *tm, int flags, float x, float y, float scale)
 {
 	/*
 	int do_input = 1;
-	if(inp_key_pressed(input::lalt) || inp_key_pressed(input::ralt))
+	if(inp_key_pressed(KEY_LALT) || inp_key_pressed(KEY_RALT))
 		do_input = 0;*/
 	
-	
 	float mx = ui_mouse_world_x();
 	float my = ui_mouse_world_y();
 	if(flags&TILEMAPFLAG_UISPACE)
@@ -519,14 +528,14 @@ static int ui_do_tilemap(void *id, tilemap *tm, int flags, float x, float y, flo
 	ui_set_hot_item(id);
 	
 	// render the tilemap
-	render_tilemap(tm, x, y, scale);
+	render_tilemap(tm, x, y, scale, flags);
 	
 	if(ui_hot_item() == id)
 	{
 		if(brush.tiles != 0)
 		{
 			// draw brush
-			render_tilemap(&brush, (tmx-brush.width/2)*scale, (tmy-brush.height/2)*scale, scale);
+			render_tilemap(&brush, (tmx-brush.width/2)*scale, (tmy-brush.height/2)*scale, scale, flags);
 			
 			gfx_texture_set(-1);
 			gfx_blend_additive();
@@ -704,7 +713,171 @@ void draw_editor_button(const void *id, const char *text, int checked, float x,
     gfx_pretty_text(x+1, y-1, 6.5f, text, -1);
 }
 
+
+
+int editor_load(const char *filename)
+{
+	editor_reset();
+	
+	DATAFILE *df = datafile_load(filename);
+	if(!df)
+		return 0;
+	
+	// load tilesets
+	{
+		int start, count;
+		datafile_get_type(df, MAPRES_IMAGE, &start, &count);
+		for(int i = 0; i < count; i++)
+		{
+			mapres_image *img = (mapres_image *)datafile_get_item(df, start+i, 0, 0);
+			void *data = datafile_get_data(df, img->image_data);
+			int id = tilesets_new();
+			void *data_cpy = mem_alloc(img->width*img->height*4, 1);
+			mem_copy(data_cpy, data, img->width*img->height*4);
+			tilesets_set_img(id, img->width, img->height, data_cpy);
+		}
+	}
+	
+	// load tilemaps
+	{
+		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);
+			//unsigned char *data = (unsigned char *)datafile_get_data(df, tmap->data);
+			
+			layer *l = layers_get(layers_new(tmap->width, tmap->height));
+			mem_copy(l->tm.tiles, datafile_get_data(df, tmap->data), tmap->width*tmap->height*2);
+			l->tileset_id = tmap->image;
+			l->main_layer = tmap->main;
+			
+			// force a main layer
+			if(num == 1)
+				l->main_layer = 1;
+		}
+	}
+	
+	// load entities
+	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);
+			
+			// map type	
+			int type = 0;
+			for(int k = 0; ent_types[k].name; k++)
+			{
+				if(ent_types[k].id == t &&
+					memcmp(ent_types[k].fields, e->data, ent_types[k].numfields*sizeof(int)) == 0)
+				{
+					type = k;
+					break;
+				}
+			}
+			
+			//dbg_msg("editor", "ent type=%d pos=(%d,%d)", type, e->x, e->y);
+			ents_new(type, e->x, e->y);
+		}
+	}
+
+	return 1;
+}
+
+int editor_save(const char *filename)
+{
+	DATAFILE_OUT *df = datafile_create(filename);
+
+	// add tilesets
+	for(int i = 0; i < tilesets_count(); i++)
+	{
+		mapres_image img;
+		tileset *ts = tilesets_get(i);
+		img.width = ts->img.width;
+		img.height = ts->img.height;
+		img.image_data = datafile_add_data(df, ts->img.width*ts->img.height*4, ts->img.data);
+		datafile_add_item(df, MAPRES_IMAGE, i, sizeof(img), &img);
+	}
+	
+	// add tilemaps
+	for(int i = 0; i < layers_count(); i++)
+	{
+		layer *l = layers_get(i);
+		mapres_tilemap tm;
+		tm.image = l->tileset_id;
+		tm.width = l->tm.width;
+		tm.height = l->tm.height;
+		tm.x = 0;
+		tm.y = 0;
+		tm.main = l->main_layer;
+		tm.scale = 1<<16;
+		tm.data = datafile_add_data(df, l->tm.width*l->tm.height*2, l->tm.tiles);
+		datafile_add_item(df, MAPRES_TILEMAP, i, sizeof(tm), &tm);
+	}
+	
+	// add collision
+	char *collisiondata = 0x0;
+	for(int i = 0; i < layers_count(); i++)
+	{
+		layer *l = layers_get(i);
+		if(l->main_layer)
+		{
+			mapres_collision col;
+			col.width = l->tm.width;
+			col.height = l->tm.height;
+			
+			collisiondata = (char *)mem_alloc(col.width*col.height, 1);
+			for(int y = 0, c = 0; y < col.height; y++)
+				for(int x = 0; x < col.width; x++, c++)
+				{
+					if(l->tm.tiles[c].index)
+						collisiondata[c] = 1;
+					else
+						collisiondata[c] = 0;
+				}
+			
+			col.data_index = datafile_add_data(df, col.width*col.height, collisiondata);
+			datafile_add_item(df, MAPRES_COLLISIONMAP, 0, sizeof(col), &col);
+			break;
+		}
+	}
+	
+	// add entities
+	for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++)
+	{
+		int id = 0;
+		for(int i = 0; i < ents_count(); i++)
+		{
+			entity *ent = ents_get(i);
+			if(ent_types[ent->type].id != t)
+				continue;
+				
+			int savebuf[64];
+			mapres_entity *mapent = (mapres_entity *)savebuf;
+			mapent->x = ent->x;
+			mapent->y = ent->y;
+			dbg_msg("editor", "saving ent idx=%d pos=(%d,%d)", i, ent->x, ent->y);
+			memcpy(mapent->data, ent_types[ent->type].fields, ent_types[ent->type].numfields*sizeof(int));
+			datafile_add_item(df, t, id, (ent_types[ent->type].numfields+2)*sizeof(int), mapent);
+			id++;
+		}
+	}
+	
+	// finish and clean up
+	datafile_finish(df);
+	mem_free(collisiondata);
+	
+	return 0;
+}
+
+
 static int editor_loadimage = -1;
+static int editor_loadmap = -1;
 
 static void editor_listdir_callback(const char *name, int is_dir, void *user)
 {
@@ -729,8 +902,8 @@ static void editor_listdir_callback(const char *name, int is_dir, void *user)
 
 static void editor_render_loadfile_dialog()
 {
-	gfx_clear(0.2f,0.2f,0.8f);
 	// GUI coordsys
+	gfx_clear(0.2f,0.2f,0.8f);
 	gfx_mapscreen(0,0,400.0f,300.0f);
 	
 	int index = 0;
@@ -740,14 +913,38 @@ static void editor_render_loadfile_dialog()
 		editor_loadimage = -1;
 }
 
-static void editor_render()
+static void editor_listdir_map_callback(const char *name, int is_dir, void *user)
 {
-	if(editor_loadimage != -1)
-	{
-		editor_render_loadfile_dialog();
+	if(name[0] == '.') // skip this shit!
 		return;
+	
+	int *y = (int*)user;
+	if(ui_do_button((void*)(*y + 1), name, 0, 10, 10 + *y * 8, 100, 6, draw_editor_button, 0))
+	{
+		char buf[512];
+		sprintf(buf, "data/maps/%s", name);
+		
+		editor_load(buf);
+		editor_loadmap = -1;
 	}
+	*y += 1;
+}
+
+static void editor_render_loadmap_dialog()
+{
+	// GUI coordsys
+	gfx_clear(0.2f,0.2f,0.8f);
+	gfx_mapscreen(0,0,400.0f,300.0f);
 	
+	int index = 0;
+	fs_listdir("data/maps", editor_listdir_map_callback, &index);
+	
+	if(inp_key_pressed(KEY_ESC))
+		editor_loadmap = -1;
+}
+
+static void editor_render_normal()
+{
 	// background color
 	gfx_clear(0.2f,0.2f,0.8f);
 	
@@ -762,22 +959,26 @@ static void editor_render()
 		gfx_texture_set(-1);
 		if(l->tileset_id >= 0 && l->tileset_id < tilesets_count())
 			gfx_texture_set(tilesets_get(l->tileset_id)->tex_id);
+			
+		int f = 0;
+		if(current_hover_layer == i)
+			f = TILEMAPFLAG_HILIGHTED;
 		
 		if(editor_mode == 0)
 		{
 			if(l == layers_get_current())
 			{
 				// do current layer
-				ui_do_tilemap(&l->tm, &l->tm, 0, 0, 0, 32.0f);
+				ui_do_tilemap(&l->tm, &l->tm, f, 0, 0, 32.0f);
 			}
 			else if(l->visible)
 			{
 				// render layer
-				render_tilemap(&l->tm, 0, 0, 32.0f);
+				render_tilemap(&l->tm, 0, 0, 32.0f, f);
 			}
 		}
 		else
-			render_tilemap(&l->tm, 0, 0, 32.0f);			
+			render_tilemap(&l->tm, 0, 0, 32.0f, f);
 	}
 
 	if(editor_mode == 1)
@@ -805,6 +1006,8 @@ static void editor_render()
 		float layerbox_y = 0;
 		int count = 1;
 		int main_layer = -1;
+		
+		current_hover_layer = -1;
 		for(int i = 0; i < layers_count(); i++)
 		{
 			layer *l = layers_get(i);
@@ -833,6 +1036,9 @@ static void editor_render()
 				layers_get(i)->visible = layers_get(i)->visible^1;
 			
 			// layer bytton
+			if(ui_mouse_inside(layerbox_x+8, layerbox_y+i*14, toolbox_width-8, 12))
+				current_hover_layer = i;
+				
 			if(ui_do_button(&layers_get(i)->tileset_id, buf, current_layer == i, layerbox_x+8, layerbox_y+i*14, toolbox_width-8, 12, draw_editor_button, 0))
 				current_layer = i;
 		}
@@ -972,313 +1178,165 @@ static void editor_render()
 		if(ui_do_button(&del, "Del", 0, 0, y, toolbox_width, 6, draw_editor_button, 0))
 			ents_delete(editor_selected_ent);
 	}
+	
 }
 
-int editor_load(const char *filename)
+static void editor_render()
 {
-	DATAFILE *df = datafile_load(filename);
-	if(!df)
-		return 0;
-	
-	// load tilesets
-	{
-		int start, count;
-		datafile_get_type(df, MAPRES_IMAGE, &start, &count);
-		for(int i = 0; i < count; i++)
-		{
-			mapres_image *img = (mapres_image *)datafile_get_item(df, start+i, 0, 0);
-			void *data = datafile_get_data(df, img->image_data);
-			int id = tilesets_new();
-			void *data_cpy = mem_alloc(img->width*img->height*4, 1);
-			mem_copy(data_cpy, data, img->width*img->height*4);
-			tilesets_set_img(id, img->width, img->height, data_cpy);
-		}
-	}
+	if(editor_loadimage != -1)
+		editor_render_loadfile_dialog();
+	else if(editor_loadmap != -1)
+		editor_render_loadmap_dialog();
+	else
+		editor_render_normal();
 	
-	// load tilemaps
+	// render butt ugly mouse cursor
+	float mx = ui_mouse_x();
+	float my = ui_mouse_y();
+	gfx_texture_set(-1);
+	gfx_quads_begin();
+	gfx_setcolor(0,0,0,1);
+	gfx_quads_draw_freeform(mx,my,mx,my,
+							mx+7,my,
+							mx,my+7);
+	gfx_setcolor(1,1,1,1);
+	gfx_quads_draw_freeform(mx+1,my+1,mx+1,my+1,
+							mx+5,my+1,
+							mx+1,my+5);
+	gfx_quads_end();	
+}
+
+extern "C" void editor_update_and_render()
+{
+	static int mouse_x = 0;
+	static int mouse_y = 0;
+		
+	// handle mouse movement
+	float mx, my, mwx, mwy;
+	int rx, ry;
 	{
-		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);
-			//unsigned char *data = (unsigned char *)datafile_get_data(df, tmap->data);
-			
-			layer *l = layers_get(layers_new(tmap->width, tmap->height));
-			mem_copy(l->tm.tiles, datafile_get_data(df, tmap->data), tmap->width*tmap->height*2);
-			l->tileset_id = tmap->image;
-			l->main_layer = tmap->main;
-			
-			// force a main layer
-			if(num == 1)
-				l->main_layer = 1;
-		}
+		inp_mouse_relative(&rx, &ry);
+		mouse_x += rx;
+		mouse_y += ry;
+		if(mouse_x < 0) mouse_x = 0;
+		if(mouse_y < 0) mouse_y = 0;
+		if(mouse_x > gfx_screenwidth()) mouse_x = gfx_screenwidth();
+		if(mouse_y > gfx_screenheight()) mouse_y = gfx_screenheight();
+
+		// update the ui
+		mx = (mouse_x/(float)gfx_screenwidth())*400.0f;
+		my = (mouse_y/(float)gfx_screenheight())*300.0f;
+		mwx = world_offset_x+mx*world_zoom; // adjust to zoom and offset
+		mwy = world_offset_y+my*world_zoom; // adjust to zoom and offset
+		
+		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);
 	}
 	
-	// load entities
-	for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++)
+	// render the editor
+	editor_render();
+
+	if(inp_key_pressed(KEY_LALT) || inp_key_pressed(KEY_RALT))
 	{
-		// fetch entities of this class
-		int start, num;
-		datafile_get_type(df, t, &start, &num);
+		// steal focus
+		static int moveid;
+		ui_set_hot_item(&moveid);
 
-		for(int i = 0; i < num; i++)
+		if(inp_key_pressed(KEY_MOUSE_1))
 		{
-			mapres_entity *e = (mapres_entity *)datafile_get_item(df, start+i,0,0);
-			
-			// map type	
-			int type = 0;
-			for(int k = 0; ent_types[k].name; k++)
-			{
-				if(ent_types[k].id == t &&
-					memcmp(ent_types[k].fields, e->data, ent_types[k].numfields*sizeof(int)) == 0)
-				{
-					type = k;
-					break;
-				}
-			}
-			
-			//dbg_msg("editor", "ent type=%d pos=(%d,%d)", type, e->x, e->y);
-			ents_new(type, e->x, e->y);
+			world_offset_x -= rx*2;
+			world_offset_y -= ry*2;
 		}
 	}
 
-	return 1;
-}
+	//
+	if(inp_key_pressed(KEY_F1))
+		inp_mouse_mode_absolute();
+	if(inp_key_pressed(KEY_F2))
+		inp_mouse_mode_relative();
 
-int editor_save(const char *filename)
-{
-	DATAFILE_OUT *df = datafile_create(filename);
-
-	// add tilesets
-	for(int i = 0; i < tilesets_count(); i++)
+	// mode switch
+	if(inp_key_down(KEY_TAB))
+		editor_mode ^= 1;
+	
+	// zoom in
+	if(inp_key_down(KEY_KP_ADD))
 	{
-		mapres_image img;
-		tileset *ts = tilesets_get(i);
-		img.width = ts->img.width;
-		img.height = ts->img.height;
-		img.image_data = datafile_add_data(df, ts->img.width*ts->img.height*4, ts->img.data);
-		datafile_add_item(df, MAPRES_IMAGE, i, sizeof(img), &img);
+		world_zoom--;
+		if(world_zoom < 3)
+			world_zoom = 3;
 	}
 	
-	// add tilemaps
-	for(int i = 0; i < layers_count(); i++)
+	// zoom out
+	if(inp_key_down(KEY_KP_SUBTRACT))
 	{
-		layer *l = layers_get(i);
-		mapres_tilemap tm;
-		tm.image = l->tileset_id;
-		tm.width = l->tm.width;
-		tm.height = l->tm.height;
-		tm.x = 0;
-		tm.y = 0;
-		tm.main = l->main_layer;
-		tm.scale = 1<<16;
-		tm.data = datafile_add_data(df, l->tm.width*l->tm.height*2, l->tm.tiles);
-		datafile_add_item(df, MAPRES_TILEMAP, i, sizeof(tm), &tm);
+		world_zoom++;
+		if(world_zoom > 8)
+			world_zoom = 8;
 	}
 	
-	// add collision
-	char *collisiondata = 0x0;
-	for(int i = 0; i < layers_count(); i++)
+	if(inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL))
 	{
-		layer *l = layers_get(i);
-		if(l->main_layer)
+		if(inp_key_down('L'))
 		{
-			mapres_collision col;
-			col.width = l->tm.width;
-			col.height = l->tm.height;
-			
-			collisiondata = (char *)mem_alloc(col.width*col.height, 1);
-			for(int y = 0, c = 0; y < col.height; y++)
-				for(int x = 0; x < col.width; x++, c++)
+			int w = 50, h = 50;
+			for(int i = 0; i < layers_count(); i++)
+			{
+				layer *l = layers_get(i);	
+				if(l->main_layer)
 				{
-					if(l->tm.tiles[c].index)
-						collisiondata[c] = 1;
-					else
-						collisiondata[c] = 0;
+					w = l->tm.width;
+					h = l->tm.height;
+					break;
 				}
-			
-			col.data_index = datafile_add_data(df, col.width*col.height, collisiondata);
-			datafile_add_item(df, MAPRES_COLLISIONMAP, 0, sizeof(col), &col);
-			break;
+			}					
+			// copy main layer size
+			layers_new(w, h);
 		}
-	}
-	
-	// add entities
-	for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++)
-	{
-		int id = 0;
-		for(int i = 0; i < ents_count(); i++)
+		
+		if(inp_key_down('O'))
+			editor_loadmap = 1;
+		
+		if(inp_key_down('S'))
 		{
-			entity *ent = ents_get(i);
-			if(ent_types[ent->type].id != t)
-				continue;
-				
-			int savebuf[64];
-			mapres_entity *mapent = (mapres_entity *)savebuf;
-			mapent->x = ent->x;
-			mapent->y = ent->y;
-			dbg_msg("editor", "saving ent idx=%d pos=(%d,%d)", i, ent->x, ent->y);
-			memcpy(mapent->data, ent_types[ent->type].fields, ent_types[ent->type].numfields*sizeof(int));
-			datafile_add_item(df, t, id, (ent_types[ent->type].numfields+2)*sizeof(int), mapent);
-			id++;
+			dbg_msg("editor", "save");
+			editor_save(editor_filename);
 		}
+
 	}
 	
-	// finish and clean up
-	datafile_finish(df);
-	mem_free(collisiondata);
+	if(inp_key_down(KEY_F5))
+	{
+		dbg_msg("editor", "quick save");
+		editor_save("quicksave.map");
+	}
 	
-	return 0;
+	if(inp_key_down(KEY_F8))
+	{
+		dbg_msg("editor", "quick load");
+		int s = current_layer;
+		editor_reset();
+		editor_load("quicksave.map");
+		current_layer = s;
+		if(current_layer >= layers_count())
+			current_layer = layers_count();
+			
+	}
 }
 
-static int editor_loop()
+extern "C" void editor_init()
 {
-	int mouse_x = 0;
-	int mouse_y = 0;
-	
-	inp_mouse_mode_relative();
-	
-	while(!(inp_key_pressed(KEY_LCTRL) && inp_key_pressed('Q')))
-	{	
-		// update input
-		inp_update();
-		
-		// handle mouse movement
-		float mx, my, mwx, mwy;
-		int rx, ry;
-		{
-			inp_mouse_relative(&rx, &ry);
-			mouse_x += rx;
-			mouse_y += ry;
-			if(mouse_x < 0) mouse_x = 0;
-			if(mouse_y < 0) mouse_y = 0;
-			if(mouse_x > gfx_screenwidth()) mouse_x = gfx_screenwidth();
-			if(mouse_y > gfx_screenheight()) mouse_y = gfx_screenheight();
-
-			// update the ui
-			mx = (mouse_x/(float)gfx_screenwidth())*400.0f;
-			my = (mouse_y/(float)gfx_screenheight())*300.0f;
-			mwx = world_offset_x+mx*world_zoom; // adjust to zoom and offset
-			mwy = world_offset_y+my*world_zoom; // adjust to zoom and offset
-			
-			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);
-		}
-		
-		//
-		editor_render();
-
-		if(inp_key_pressed(KEY_LALT) || inp_key_pressed(KEY_RALT))
-		{
-			static int moveid;
-			ui_set_hot_item(&moveid);
-			if(inp_key_pressed(KEY_MOUSE_1))
-			{
-				world_offset_x -= rx*2;
-				world_offset_y -= ry*2;
-			}
-		}
-		
-		
-		// render butt ugly mouse cursor
-		gfx_texture_set(-1);
-		gfx_quads_begin();
-		gfx_setcolor(0,0,0,1);
-		gfx_quads_draw_freeform(mx,my,mx,my,
-								mx+7,my,
-								mx,my+7);
-		gfx_setcolor(1,1,1,1);
-		gfx_quads_draw_freeform(mx+1,my+1,mx+1,my+1,
-								mx+5,my+1,
-								mx+1,my+5);
-		gfx_quads_end();
-		
-		// swap the buffers
-		gfx_swap();
-		
-		//
-		if(inp_key_pressed(KEY_F1))
-			inp_mouse_mode_absolute();
-		if(inp_key_pressed(KEY_F2))
-			inp_mouse_mode_relative();
-
-		// mode switch
-		if(inp_key_down(KEY_TAB))
-			editor_mode ^= 1;
-		
-		// zoom in
-		if(inp_key_down(KEY_KP_ADD))
-		{
-			world_zoom--;
-			if(world_zoom < 3)
-				world_zoom = 3;
-		}
-		
-		// zoom out
-		if(inp_key_down(KEY_KP_SUBTRACT))
-		{
-			world_zoom++;
-			if(world_zoom > 8)
-				world_zoom = 8;
-		}
-		
-		if(inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL))
-		{
-			if(inp_key_down('L'))
-			{
-				int w = 50, h = 50;
-				for(int i = 0; i < layers_count(); i++)
-				{
-					layer *l = layers_get(i);	
-					if(l->main_layer)
-					{
-						w = l->tm.width;
-						h = l->tm.height;
-						break;
-					}
-				}					
-				// copy main layer size
-				layers_new(w, h);
-			}
-			
-			if(inp_key_down('S'))
-			{
-				dbg_msg("editor", "save");
-				editor_save(editor_filename);
-			}
-
-		}
-		
-		if(inp_key_down(KEY_F5))
-		{
-			dbg_msg("editor", "quick save");
-			editor_save("quicksave.map");
-		}
-		
-		if(inp_key_down(KEY_F8))
-		{
-			dbg_msg("editor", "quick load");
-			int s = current_layer;
-			editor_reset();
-			editor_load("quicksave.map");
-			current_layer = s;
-			if(current_layer >= layers_count())
-				current_layer = layers_count();
-				
-		}
-		
-		// be nice
-		thread_sleep(1);
-	}
-	
-	return 0;
+	// reset and start
+	font_texture = gfx_load_texture("data/debug_font.png");
+	checker_texture = gfx_load_texture("data/checker.png");
+	editor_reset();
 }
 
+/*
 extern void modmenu_init();
 
 extern "C" int editor_main(int argc, char **argv)
@@ -1310,13 +1368,6 @@ extern "C" int editor_main(int argc, char **argv)
 	if(!gfx_init())
 		return -1;
 	
-	modmenu_init();
-	
-	// reset and start
-	font_texture = gfx_load_texture("data/debug_font.png");
-	checker_texture = gfx_load_texture("data/checker.png");
-	editor_reset();
-
 	// load or new
 	if(!editor_load(editor_filename))
 	{
@@ -1327,4 +1378,4 @@ extern "C" int editor_main(int argc, char **argv)
 	editor_loop();
 	
 	return 0;
-}
+}*/
diff --git a/src/engine/client/client.c b/src/engine/client/client.c
index dcac2234..6f8a2761 100644
--- a/src/engine/client/client.c
+++ b/src/engine/client/client.c
@@ -47,6 +47,7 @@ static int64 local_start_time;
 
 static int debug_font;
 static float frametime = 0.0001f;
+static int frames = 0;
 static NETADDR4 server_address;
 static int window_must_refocus = 0;
 static int snaploss = 0;
@@ -827,12 +828,99 @@ static void client_pump_network()
 		client_process_packet(&packet);
 }
 
+static void client_update()
+{
+
+	/* switch snapshot */
+	if(recived_snapshots >= 3)
+	{
+		int repredict = 0;
+		int64 now = st_get(&game_time, time_get());
+
+		while(1)
+		{
+			SNAPSTORAGE_HOLDER *cur = snapshots[SNAP_CURRENT];
+			int64 tickstart = (cur->tick)*time_freq()/50;
+
+			if(tickstart < now)
+			{
+				SNAPSTORAGE_HOLDER *next = snapshots[SNAP_CURRENT]->next;
+				if(next)
+				{
+					snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT];
+					snapshots[SNAP_CURRENT] = next;
+					
+					/* set tick */
+					current_tick = snapshots[SNAP_CURRENT]->tick;
+					
+					if(snapshots[SNAP_CURRENT] && snapshots[SNAP_PREV])
+					{
+						modc_newsnapshot();
+						repredict = 1;
+					}
+				}
+				else
+					break;
+			}
+			else
+				break;
+		}
+
+		if(snapshots[SNAP_CURRENT] && snapshots[SNAP_PREV])
+		{
+			int64 curtick_start = (snapshots[SNAP_CURRENT]->tick)*time_freq()/50;
+			int64 prevtick_start = (snapshots[SNAP_PREV]->tick)*time_freq()/50;
+			int64 pred_now = st_get(&predicted_time, time_get());
+			/*tg_add(&predicted_time_graph, pred_now, 0); */
+			int prev_pred_tick = (int)(pred_now*50/time_freq());
+			int new_pred_tick = prev_pred_tick+1;
+
+			intratick = (now - prevtick_start) / (float)(curtick_start-prevtick_start);
+
+			graph_add(&intra_graph, intratick*0.25f);
+
+			curtick_start = new_pred_tick*time_freq()/50;
+			prevtick_start = prev_pred_tick*time_freq()/50;
+			intrapredtick = (pred_now - prevtick_start) / (float)(curtick_start-prevtick_start);
+			
+			if(new_pred_tick > current_predtick)
+			{
+				current_predtick = new_pred_tick;
+				repredict = 1;
+				
+				/* send input */
+				client_send_input();
+			}
+		}
+
+		/* only do sane predictions */
+		if(repredict)
+		{
+			if(current_predtick > current_tick && current_predtick < current_tick+50)
+				modc_predict();
+		}
+	}
+
+	/* STRESS TEST: join the server again */
+	if(client_state() == CLIENTSTATE_OFFLINE && config.stress && (frames%100) == 0)
+		client_connect(config.cl_stress_server);
+	
+	/* pump the network */
+	client_pump_network();
+	
+	/* update the server browser */
+	client_serverbrowse_update();
+}
+
+extern int editor_update_and_render();
+extern void editor_init();
+
 static void client_run()
 {
 	NETADDR4 bindaddr;
 	int64 reporttime = time_get();
 	int64 reportinterval = time_freq()*1;
-	int frames = 0;
+	int editor_active = 0;
 
 	local_start_time = time_get();
 	snapshot_part = 0;
@@ -841,6 +929,9 @@ static void client_run()
 	if(!gfx_init())
 		return;
 
+	/* init the editor */
+	editor_init();
+
 	/* sound is allowed to fail */
 	snd_init();
 	
@@ -866,80 +957,6 @@ static void client_run()
 	{	
 		int64 frame_start_time = time_get();
 		frames++;
-
-		/* switch snapshot */
-		if(recived_snapshots >= 3)
-		{
-			int repredict = 0;
-			int64 now = st_get(&game_time, time_get());
-
-			while(1)
-			{
-				SNAPSTORAGE_HOLDER *cur = snapshots[SNAP_CURRENT];
-				int64 tickstart = (cur->tick)*time_freq()/50;
-
-				if(tickstart < now)
-				{
-					SNAPSTORAGE_HOLDER *next = snapshots[SNAP_CURRENT]->next;
-					if(next)
-					{
-						snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT];
-						snapshots[SNAP_CURRENT] = next;
-						
-						/* set tick */
-						current_tick = snapshots[SNAP_CURRENT]->tick;
-						
-						if(snapshots[SNAP_CURRENT] && snapshots[SNAP_PREV])
-						{
-							modc_newsnapshot();
-							repredict = 1;
-						}
-					}
-					else
-						break;
-				}
-				else
-					break;
-			}
-
-			if(snapshots[SNAP_CURRENT] && snapshots[SNAP_PREV])
-			{
-				int64 curtick_start = (snapshots[SNAP_CURRENT]->tick)*time_freq()/50;
-				int64 prevtick_start = (snapshots[SNAP_PREV]->tick)*time_freq()/50;
-				int64 pred_now = st_get(&predicted_time, time_get());
-				/*tg_add(&predicted_time_graph, pred_now, 0); */
-				int prev_pred_tick = (int)(pred_now*50/time_freq());
-				int new_pred_tick = prev_pred_tick+1;
-
-				intratick = (now - prevtick_start) / (float)(curtick_start-prevtick_start);
-
-				graph_add(&intra_graph, intratick*0.25f);
-
-				curtick_start = new_pred_tick*time_freq()/50;
-				prevtick_start = prev_pred_tick*time_freq()/50;
-				intrapredtick = (pred_now - prevtick_start) / (float)(curtick_start-prevtick_start);
-				
-				if(new_pred_tick > current_predtick)
-				{
-					current_predtick = new_pred_tick;
-					repredict = 1;
-					
-					/* send input */
-					client_send_input();
-				}
-			}
-
-			/* only do sane predictions */
-			if(repredict)
-			{
-				if(current_predtick > current_tick && current_predtick < current_tick+50)
-					modc_predict();
-			}
-		}
-
-		/* STRESS TEST: join the server again */
-		if(client_state() == CLIENTSTATE_OFFLINE && config.stress && (frames%100) == 0)
-			client_connect(config.cl_stress_server);
 		
 		/* update input */
 		inp_update();
@@ -972,6 +989,7 @@ static void client_run()
 			gfx_screenshot();
 
 		/* some debug keys */
+		/*
 		if(config.debug)
 		{
 			if(inp_key_pressed(KEY_F1))
@@ -984,35 +1002,42 @@ static void client_run()
 				ack_game_tick = -1;
 				client_send_input();
 			}
-		}
+		}*/
 
 		/* panic quit button */
 		if(inp_key_pressed(KEY_LCTRL) && inp_key_pressed(KEY_LSHIFT) && inp_key_pressed('Q'))
 			break;
+
+		if(inp_key_pressed(KEY_LCTRL) && inp_key_pressed(KEY_LSHIFT) && inp_key_down('E'))
+			editor_active = editor_active^1;
 		
 		if(!gfx_window_open())
 			break;
 			
-		/* pump the network */
-		client_pump_network();
-		
-		/* update the server browser */
-		client_serverbrowse_update();
-		
 		/* render */
-		if(config.stress)
+		if(editor_active)
+		{
+			editor_update_and_render();
+			gfx_swap();
+		}
+		else
 		{
-			if((frames%10) == 0)
+			client_update();
+			
+			if(config.stress)
+			{
+				if((frames%10) == 0)
+				{
+					client_render();
+					gfx_swap();
+				}
+			}
+			else
 			{
 				client_render();
 				gfx_swap();
 			}
 		}
-		else
-		{
-			client_render();
-			gfx_swap();
-		}
 		
 		/* check conditions */
 		if(client_state() == CLIENTSTATE_QUITING)
@@ -1053,10 +1078,7 @@ int main(int argc, char **argv)
 	dbg_msg("client", "starting...");
 	engine_init("Teewars", argc, argv);
 	
-	if(config.cl_editor)
-		editor_main(argc, argv);
-	else
-		client_run();
+	client_run();
 		
 	engine_writeconfig();
 	return 0;
diff --git a/src/engine/client/gfx.c b/src/engine/client/gfx.c
index c85e2a91..945a615e 100644
--- a/src/engine/client/gfx.c
+++ b/src/engine/client/gfx.c
@@ -78,6 +78,59 @@ static const unsigned char null_texture_data[] = {
 	0x00,0x00,0xff,0xff, 0x00,0x00,0xff,0xff, 0xff,0xff,0x00,0xff, 0xff,0xff,0x00,0xff, 
 };
 
+
+typedef struct
+{
+	float m_CharStartTable[256];
+	float m_CharEndTable[256];
+	int font_texture;
+} pretty_font;
+
+pretty_font default_font = 
+{
+{
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+        0, 0.421875, 0.359375, 0.265625, 0.25, 0.1875, 0.25, 0.4375, 0.390625, 0.390625, 0.34375, 0.28125, 0.421875, 0.390625, 0.4375, 0.203125, 
+        0.265625, 0.28125, 0.28125, 0.265625, 0.25, 0.28125, 0.28125, 0.265625, 0.28125, 0.265625, 0.4375, 0.421875, 0.3125, 0.28125, 0.3125, 0.3125, 
+        0.25, 0.234375, 0.28125, 0.265625, 0.265625, 0.296875, 0.3125, 0.25, 0.25, 0.421875, 0.28125, 0.265625, 0.328125, 0.171875, 0.234375, 0.25, 
+        0.28125, 0.234375, 0.265625, 0.265625, 0.28125, 0.265625, 0.234375, 0.09375, 0.234375, 0.234375, 0.265625, 0.390625, 0.203125, 0.390625, 0.296875, 0.28125, 
+        0.375, 0.3125, 0.3125, 0.3125, 0.296875, 0.3125, 0.359375, 0.296875, 0.3125, 0.4375, 0.390625, 0.328125, 0.4375, 0.203125, 0.3125, 0.296875, 
+        0.3125, 0.296875, 0.359375, 0.3125, 0.328125, 0.3125, 0.296875, 0.203125, 0.296875, 0.296875, 0.328125, 0.375, 0.421875, 0.375, 0.28125, 0.3125, 
+        0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 
+        0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 
+        0, 0.421875, 0.3125, 0.265625, 0.25, 0.25, 0.421875, 0.265625, 0.375, 0.21875, 0.375, 0.328125, 0.3125, 0, 0.21875, 0.28125, 
+        0.359375, 0.28125, 0.34375, 0.34375, 0.421875, 0.3125, 0.265625, 0.421875, 0.421875, 0.34375, 0.375, 0.328125, 0.125, 0.125, 0.125, 0.296875, 
+        0.234375, 0.234375, 0.234375, 0.234375, 0.234375, 0.234375, 0.109375, 0.265625, 0.296875, 0.296875, 0.296875, 0.296875, 0.375, 0.421875, 0.359375, 0.390625, 
+        0.21875, 0.234375, 0.25, 0.25, 0.25, 0.25, 0.25, 0.296875, 0.21875, 0.265625, 0.265625, 0.265625, 0.265625, 0.234375, 0.28125, 0.3125, 
+        0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.1875, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.375, 0.421875, 0.359375, 0.390625, 
+        0.3125, 0.3125, 0.296875, 0.296875, 0.296875, 0.296875, 0.296875, 0.28125, 0.28125, 0.3125, 0.3125, 0.3125, 0.3125, 0.296875, 0.3125, 0.296875, 
+},
+{
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+        0.2, 0.5625, 0.625, 0.71875, 0.734375, 0.796875, 0.765625, 0.546875, 0.59375, 0.59375, 0.65625, 0.703125, 0.546875, 0.59375, 0.5625, 0.6875, 
+        0.71875, 0.609375, 0.703125, 0.703125, 0.71875, 0.703125, 0.703125, 0.6875, 0.703125, 0.703125, 0.5625, 0.546875, 0.671875, 0.703125, 0.671875, 0.671875, 
+        0.734375, 0.75, 0.734375, 0.734375, 0.734375, 0.6875, 0.6875, 0.734375, 0.71875, 0.5625, 0.65625, 0.765625, 0.703125, 0.8125, 0.75, 0.734375, 
+        0.734375, 0.765625, 0.71875, 0.71875, 0.703125, 0.71875, 0.75, 0.890625, 0.75, 0.75, 0.71875, 0.59375, 0.6875, 0.59375, 0.6875, 0.703125, 
+        0.5625, 0.671875, 0.6875, 0.671875, 0.671875, 0.671875, 0.625, 0.671875, 0.671875, 0.5625, 0.546875, 0.703125, 0.5625, 0.78125, 0.671875, 0.671875, 
+        0.6875, 0.671875, 0.65625, 0.671875, 0.65625, 0.671875, 0.6875, 0.78125, 0.6875, 0.671875, 0.65625, 0.609375, 0.546875, 0.609375, 0.703125, 0.671875, 
+        0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 
+        0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 
+        0, 0.5625, 0.671875, 0.734375, 0.734375, 0.734375, 0.546875, 0.71875, 0.609375, 0.765625, 0.609375, 0.65625, 0.671875, 0, 0.765625, 0.703125, 
+        0.625, 0.703125, 0.640625, 0.640625, 0.609375, 0.671875, 0.703125, 0.546875, 0.5625, 0.578125, 0.609375, 0.65625, 0.859375, 0.859375, 0.859375, 0.671875, 
+        0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.84375, 0.734375, 0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.609375, 0.640625, 0.59375, 
+        0.734375, 0.75, 0.734375, 0.734375, 0.734375, 0.734375, 0.734375, 0.6875, 0.765625, 0.71875, 0.71875, 0.71875, 0.71875, 0.75, 0.734375, 0.6875, 
+        0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.796875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.5625, 0.609375, 0.625, 0.59375, 
+        0.6875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.703125, 0.703125, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.6875, 0.671875, 
+},
+0
+};
+
+double extra_kerning[256*256] = {0};
+
+pretty_font *current_font = &default_font;
+
 static void flush()
 {
 	if(num_vertices == 0)
@@ -222,6 +275,9 @@ int gfx_init()
 	/* set vsync as needed */
 	gfx_set_vsync(config.gfx_vsync);
 
+	/* UGLY as hell, please remove */
+    current_font->font_texture = gfx_load_texture("data/big_font.png");
+
 	return 1;
 }
 
@@ -797,58 +853,6 @@ void gfx_quads_text(float x, float y, float size, const char *text)
 	gfx_quads_end();
 }
 
-typedef struct
-{
-	float m_CharStartTable[256];
-	float m_CharEndTable[256];
-	int font_texture;
-} pretty_font;
-
-pretty_font default_font = 
-{
-{
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0.421875, 0.359375, 0.265625, 0.25, 0.1875, 0.25, 0.4375, 0.390625, 0.390625, 0.34375, 0.28125, 0.421875, 0.390625, 0.4375, 0.203125, 
-        0.265625, 0.28125, 0.28125, 0.265625, 0.25, 0.28125, 0.28125, 0.265625, 0.28125, 0.265625, 0.4375, 0.421875, 0.3125, 0.28125, 0.3125, 0.3125, 
-        0.25, 0.234375, 0.28125, 0.265625, 0.265625, 0.296875, 0.3125, 0.25, 0.25, 0.421875, 0.28125, 0.265625, 0.328125, 0.171875, 0.234375, 0.25, 
-        0.28125, 0.234375, 0.265625, 0.265625, 0.28125, 0.265625, 0.234375, 0.09375, 0.234375, 0.234375, 0.265625, 0.390625, 0.203125, 0.390625, 0.296875, 0.28125, 
-        0.375, 0.3125, 0.3125, 0.3125, 0.296875, 0.3125, 0.359375, 0.296875, 0.3125, 0.4375, 0.390625, 0.328125, 0.4375, 0.203125, 0.3125, 0.296875, 
-        0.3125, 0.296875, 0.359375, 0.3125, 0.328125, 0.3125, 0.296875, 0.203125, 0.296875, 0.296875, 0.328125, 0.375, 0.421875, 0.375, 0.28125, 0.3125, 
-        0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 
-        0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 
-        0, 0.421875, 0.3125, 0.265625, 0.25, 0.25, 0.421875, 0.265625, 0.375, 0.21875, 0.375, 0.328125, 0.3125, 0, 0.21875, 0.28125, 
-        0.359375, 0.28125, 0.34375, 0.34375, 0.421875, 0.3125, 0.265625, 0.421875, 0.421875, 0.34375, 0.375, 0.328125, 0.125, 0.125, 0.125, 0.296875, 
-        0.234375, 0.234375, 0.234375, 0.234375, 0.234375, 0.234375, 0.109375, 0.265625, 0.296875, 0.296875, 0.296875, 0.296875, 0.375, 0.421875, 0.359375, 0.390625, 
-        0.21875, 0.234375, 0.25, 0.25, 0.25, 0.25, 0.25, 0.296875, 0.21875, 0.265625, 0.265625, 0.265625, 0.265625, 0.234375, 0.28125, 0.3125, 
-        0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.1875, 0.3125, 0.3125, 0.3125, 0.3125, 0.3125, 0.375, 0.421875, 0.359375, 0.390625, 
-        0.3125, 0.3125, 0.296875, 0.296875, 0.296875, 0.296875, 0.296875, 0.28125, 0.28125, 0.3125, 0.3125, 0.3125, 0.3125, 0.296875, 0.3125, 0.296875, 
-},
-{
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0.2, 0.5625, 0.625, 0.71875, 0.734375, 0.796875, 0.765625, 0.546875, 0.59375, 0.59375, 0.65625, 0.703125, 0.546875, 0.59375, 0.5625, 0.6875, 
-        0.71875, 0.609375, 0.703125, 0.703125, 0.71875, 0.703125, 0.703125, 0.6875, 0.703125, 0.703125, 0.5625, 0.546875, 0.671875, 0.703125, 0.671875, 0.671875, 
-        0.734375, 0.75, 0.734375, 0.734375, 0.734375, 0.6875, 0.6875, 0.734375, 0.71875, 0.5625, 0.65625, 0.765625, 0.703125, 0.8125, 0.75, 0.734375, 
-        0.734375, 0.765625, 0.71875, 0.71875, 0.703125, 0.71875, 0.75, 0.890625, 0.75, 0.75, 0.71875, 0.59375, 0.6875, 0.59375, 0.6875, 0.703125, 
-        0.5625, 0.671875, 0.6875, 0.671875, 0.671875, 0.671875, 0.625, 0.671875, 0.671875, 0.5625, 0.546875, 0.703125, 0.5625, 0.78125, 0.671875, 0.671875, 
-        0.6875, 0.671875, 0.65625, 0.671875, 0.65625, 0.671875, 0.6875, 0.78125, 0.6875, 0.671875, 0.65625, 0.609375, 0.546875, 0.609375, 0.703125, 0.671875, 
-        0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 
-        0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 
-        0, 0.5625, 0.671875, 0.734375, 0.734375, 0.734375, 0.546875, 0.71875, 0.609375, 0.765625, 0.609375, 0.65625, 0.671875, 0, 0.765625, 0.703125, 
-        0.625, 0.703125, 0.640625, 0.640625, 0.609375, 0.671875, 0.703125, 0.546875, 0.5625, 0.578125, 0.609375, 0.65625, 0.859375, 0.859375, 0.859375, 0.671875, 
-        0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.84375, 0.734375, 0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.609375, 0.640625, 0.59375, 
-        0.734375, 0.75, 0.734375, 0.734375, 0.734375, 0.734375, 0.734375, 0.6875, 0.765625, 0.71875, 0.71875, 0.71875, 0.71875, 0.75, 0.734375, 0.6875, 
-        0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.796875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.5625, 0.609375, 0.625, 0.59375, 
-        0.6875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.703125, 0.703125, 0.671875, 0.671875, 0.671875, 0.671875, 0.671875, 0.6875, 0.671875, 
-},
-0
-};
-
-double extra_kerning[256*256] = {0};
-
-pretty_font *current_font = &default_font;
-
 static int word_length(const char *text)
 {
 	int s = 1;
diff --git a/src/engine/interface.h b/src/engine/interface.h
index 80d72abd..cb975fed 100644
--- a/src/engine/interface.h
+++ b/src/engine/interface.h
@@ -719,32 +719,6 @@ void modc_render();
 */
 void modc_statechange(int new_state, int old_state);
 
-/*
-    Group: Menu Callbacks
-*/
-/*
-    Function: modmenu_init
-        Called when the menu starts.
-    
-    Remarks:
-        The menu should load resources that are used during the entire
-        time of the menu use.
-*/
-void modmenu_init();
-
-/*
-    Function: modmenu_shutdown
-        Called when the menu closes down.
-*/
-void modmenu_shutdown();
-
-/*
-    Function: modmenu_render
-        Called every frame to let the menu render it self.
-*/
-int modmenu_render(int ingame);
-
-
 /* undocumented callbacks */
 void modc_connected();
 void modc_message(int msg);
diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp
index e1949611..3325de65 100644
--- a/src/game/client/game_client.cpp
+++ b/src/game/client/game_client.cpp
@@ -34,6 +34,8 @@ int gametype = GAMETYPE_DM;
 static int music_menu = -1;
 static int music_menu_id = -1;
 
+extern void modmenu_render();
+
 enum
 {
 	CHATMODE_NONE=0,
@@ -545,9 +547,6 @@ static void render_loading(float percent)
 
 extern "C" void modc_init()
 {
-	// init menu
-	modmenu_init();
-	
 	// setup sound channels
 	snd_set_channel(CHN_GUI, 1.0f, 0.0f);
 	snd_set_channel(CHN_MUSIC, 1.0f, 0.0f);
@@ -600,7 +599,6 @@ extern "C" void modc_entergame()
 extern "C" void modc_shutdown()
 {
 	// shutdown the menu
-	modmenu_shutdown();
 }
 
 static void process_events(int s)
@@ -2596,10 +2594,7 @@ void render_game()
 
 	if (menu_active)
 	{
-		if (modmenu_render(true))
-			menu_active = false;
-
-		//ingamemenu_render();
+		modmenu_render();
 		return;
 	}
 
@@ -2676,13 +2671,9 @@ extern "C" void modc_render()
 	else // if (client_state() != CLIENTSTATE_CONNECTING && client_state() != CLIENTSTATE_LOADING)
 	{
 		if (music_menu_id == -1)
-		{
 			music_menu_id = snd_play(CHN_MUSIC, music_menu, SNDFLAG_LOOP);
-		}
 
-		//netaddr4 server_address;
-		if(modmenu_render(false) == -1)
-			client_quit();
+		modmenu_render();
 	}
 
 	//
@@ -2701,9 +2692,9 @@ extern "C" void modc_statechange(int state, int old)
 	 	menu_do_disconnected();
 	 	menu_game_active = false;
 	}
-	if(state == CLIENTSTATE_CONNECTING)
+	else if(state == CLIENTSTATE_CONNECTING)
 		menu_do_connecting();
-	if (state == CLIENTSTATE_ONLINE)
+	else if (state == CLIENTSTATE_ONLINE)
 	{
 		menu_active = false;
 	 	menu_game_active = true;
diff --git a/src/game/client/menu.cpp b/src/game/client/menu.cpp
index f41e938e..10dafc39 100644
--- a/src/game/client/menu.cpp
+++ b/src/game/client/menu.cpp
@@ -1,4 +1,6 @@
 /* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
+#if 0
+
 #include <stdio.h>
 #include <math.h>
 #include <string.h>
@@ -1859,3 +1861,5 @@ extern "C" int modmenu_render(int ingame) // TODO: nastyness
 
 	return r;
 }
+
+#endif
diff --git a/src/game/client/menu2.cpp b/src/game/client/menu2.cpp
index 5909a7d3..028ea7b9 100644
--- a/src/game/client/menu2.cpp
+++ b/src/game/client/menu2.cpp
@@ -1536,3 +1536,54 @@ int menu2_render()
 }
 
 
+void menu_do_disconnected()
+{
+}
+
+void menu_do_connecting()
+{
+}
+
+void menu_do_connected()
+{
+}
+
+void modmenu_render()
+{
+	static int mouse_x = 0;
+	static int mouse_y = 0;
+
+    // handle mouse movement
+    float mx, my;
+    {
+        int rx, ry;
+        inp_mouse_relative(&rx, &ry);
+        mouse_x += rx;
+        mouse_y += ry;
+        if(mouse_x < 0) mouse_x = 0;
+        if(mouse_y < 0) mouse_y = 0;
+        if(mouse_x > gfx_screenwidth()) mouse_x = gfx_screenwidth();
+        if(mouse_y > gfx_screenheight()) mouse_y = gfx_screenheight();
+            
+        // update the ui
+        mx = (mouse_x/(float)gfx_screenwidth())*800.0f;
+        my = (mouse_y/(float)gfx_screenheight())*600.0f;
+            
+        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,mx*3.0f,my*3.0f,buttons);
+    }
+    
+	menu2_render();
+
+    gfx_texture_set(data->images[IMAGE_CURSOR].id);
+    gfx_quads_begin();
+    gfx_setcolor(1,1,1,1);
+    gfx_quads_drawTL(mx,my,24,24);
+    gfx_quads_end();
+
+	inp_clear();
+}