about summary refs log tree commit diff
path: root/src/game
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2009-10-27 14:38:53 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2009-10-27 14:38:53 +0000
commit878ede3080ab2cfb627aca505c397d9765052996 (patch)
tree98bff371070e1dca0295f0ca58d64ac4ee8042ce /src/game
parent9b99ec0e60b60134e46f2f71d707230948f7db03 (diff)
downloadzcatch-878ede3080ab2cfb627aca505c397d9765052996.tar.gz
zcatch-878ede3080ab2cfb627aca505c397d9765052996.zip
major update with stuff
Diffstat (limited to 'src/game')
-rw-r--r--src/game/client/clienthooks.cpp31
-rw-r--r--src/game/client/component.hpp8
-rw-r--r--src/game/client/components/broadcast.cpp5
-rw-r--r--src/game/client/components/chat.cpp3
-rw-r--r--src/game/client/components/console.cpp97
-rw-r--r--src/game/client/components/console.hpp8
-rw-r--r--src/game/client/components/damageind.cpp15
-rw-r--r--src/game/client/components/debughud.cpp17
-rw-r--r--src/game/client/components/emoticon.cpp37
-rw-r--r--src/game/client/components/flow.cpp9
-rw-r--r--src/game/client/components/hud.cpp109
-rw-r--r--src/game/client/components/hud.hpp2
-rw-r--r--src/game/client/components/items.cpp87
-rw-r--r--src/game/client/components/killmessages.cpp47
-rw-r--r--src/game/client/components/mapimages.cpp7
-rw-r--r--src/game/client/components/maplayers.cpp56
-rw-r--r--src/game/client/components/maplayers.hpp3
-rw-r--r--src/game/client/components/menus.cpp724
-rw-r--r--src/game/client/components/menus.hpp104
-rw-r--r--src/game/client/components/menus_browser.cpp338
-rw-r--r--src/game/client/components/menus_demo.cpp221
-rw-r--r--src/game/client/components/menus_ingame.cpp194
-rw-r--r--src/game/client/components/menus_settings.cpp460
-rw-r--r--src/game/client/components/motd.cpp17
-rw-r--r--src/game/client/components/particles.cpp20
-rw-r--r--src/game/client/components/players.cpp101
-rw-r--r--src/game/client/components/scoreboard.cpp67
-rw-r--r--src/game/client/components/skins.cpp12
-rw-r--r--src/game/client/components/voting.cpp24
-rw-r--r--src/game/client/components/voting.hpp8
-rw-r--r--src/game/client/gameclient.cpp41
-rw-r--r--src/game/client/gameclient.hpp20
-rw-r--r--src/game/client/render.cpp93
-rw-r--r--src/game/client/render.hpp51
-rw-r--r--src/game/client/render_map.cpp47
-rw-r--r--src/game/client/ui.cpp225
-rw-r--r--src/game/client/ui.hpp117
-rw-r--r--src/game/editor/ed_editor.cpp1708
-rw-r--r--src/game/editor/ed_editor.hpp155
-rw-r--r--src/game/editor/ed_io.cpp23
-rw-r--r--src/game/editor/ed_layer_game.cpp2
-rw-r--r--src/game/editor/ed_layer_quads.cpp45
-rw-r--r--src/game/editor/ed_layer_tiles.cpp60
-rw-r--r--src/game/editor/ed_popups.cpp235
-rw-r--r--src/game/localization.cpp2
-rw-r--r--src/game/server/hooks.cpp10
46 files changed, 3099 insertions, 2566 deletions
diff --git a/src/game/client/clienthooks.cpp b/src/game/client/clienthooks.cpp
index 88a7722a..76fa8dcd 100644
--- a/src/game/client/clienthooks.cpp
+++ b/src/game/client/clienthooks.cpp
@@ -7,22 +7,21 @@
 
 
 
-
 // clean hooks
-extern "C" void modc_entergame() {}
-extern "C" void modc_shutdown() {}
-extern "C" void modc_console_init() { gameclient.on_console_init(); }
-extern "C" void modc_save_config() { gameclient.on_save(); }
-extern "C" void modc_init() { gameclient.on_init(); }
-extern "C" void modc_connected() { gameclient.on_connected(); }
-extern "C" void modc_predict() { gameclient.on_predict(); }
-extern "C" void modc_newsnapshot() { gameclient.on_snapshot(); }
-extern "C" int modc_snap_input(int *data) { return gameclient.on_snapinput(data); }
-extern "C" void modc_statechange(int state, int old) { gameclient.on_statechange(state, old); }
-extern "C" void modc_render() { gameclient.on_render(); }
-extern "C" void modc_message(int msgtype) { gameclient.on_message(msgtype); }
-extern "C" void modc_rcon_line(const char *line) { gameclient.console->print_line(1, line); }
+void modc_entergame() {}
+void modc_shutdown() {}
+void modc_console_init() { gameclient.on_console_init(); }
+void modc_save_config() { gameclient.on_save(); }
+void modc_init() { gameclient.on_init(); }
+void modc_connected() { gameclient.on_connected(); }
+void modc_predict() { gameclient.on_predict(); }
+void modc_newsnapshot() { gameclient.on_snapshot(); }
+int modc_snap_input(int *data) { return gameclient.on_snapinput(data); }
+void modc_statechange(int state, int old) { gameclient.on_statechange(state, old); }
+void modc_render() { gameclient.on_render(); }
+void modc_message(int msgtype) { gameclient.on_message(msgtype); }
+void modc_rcon_line(const char *line) { gameclient.console->print_line(1, line); }
 
-extern "C" const char *modc_net_version() { return GAME_NETVERSION; }
-extern "C" const char *modc_getitemname(int type) { return netobj_get_name(type); }
+const char *modc_net_version() { return GAME_NETVERSION; }
+const char *modc_getitemname(int type) { return netobj_get_name(type); }
 
diff --git a/src/game/client/component.hpp b/src/game/client/component.hpp
index 3d5edb86..6534e56b 100644
--- a/src/game/client/component.hpp
+++ b/src/game/client/component.hpp
@@ -2,13 +2,21 @@
 #define GAME_CLIENT_GAMESYSTEM_H
 
 #include <engine/e_client_interface.h>
+#include "gameclient.hpp"
 
 class GAMECLIENT;
 
 class COMPONENT
 {
 protected:
+	friend class GAMECLIENT;
+
 	GAMECLIENT *client;
+	
+	// perhaps propagte pointers for these as well
+	class IGraphics *Graphics() const { return client->Graphics(); }
+	class CUI *UI() const { return client->UI(); }
+	class CRenderTools *RenderTools() const { return client->RenderTools(); }
 public:
 	virtual ~COMPONENT() {}
 	
diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp
index 960b004c..b86ed658 100644
--- a/src/game/client/components/broadcast.cpp
+++ b/src/game/client/components/broadcast.cpp
@@ -1,5 +1,6 @@
 #include <engine/e_client_interface.h>
 #include <engine/e_config.h>
+#include <engine/client/graphics.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 
@@ -14,12 +15,12 @@ void BROADCAST::on_reset()
 
 void BROADCAST::on_render()
 {
-	gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300);
+	Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300);
 		
 	if(time_get() < broadcast_time)
 	{
 		float w = gfx_text_width(0, 14, broadcast_text, -1);
-		gfx_text(0, 150*gfx_screenaspect()-w/2, 35, 14, broadcast_text, -1);
+		gfx_text(0, 150*Graphics()->ScreenAspect()-w/2, 35, 14, broadcast_text, -1);
 	}
 }
 
diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp
index 37015337..fdf1d21b 100644
--- a/src/game/client/components/chat.cpp
+++ b/src/game/client/components/chat.cpp
@@ -1,6 +1,7 @@
 #include <string.h> // strcmp
 
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 
@@ -133,7 +134,7 @@ void CHAT::add_line(int client_id, int team, const char *line)
 
 void CHAT::on_render()
 {
-	gfx_mapscreen(0,0,300*gfx_screenaspect(),300);
+	Graphics()->MapScreen(0,0,300*Graphics()->ScreenAspect(),300);
 	float x = 10.0f;
 	float y = 300.0f-20.0f;
 	if(mode != MODE_NONE)
diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp
index 7b806b36..382cb134 100644
--- a/src/game/client/components/console.cpp
+++ b/src/game/client/components/console.cpp
@@ -6,10 +6,9 @@
 #include <base/system.h>
 
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 
-extern "C" {
-	#include <engine/e_ringbuffer.h>
-}
+#include <engine/e_ringbuffer.h>
 
 #include <cstring>
 #include <cstdio>
@@ -34,8 +33,8 @@ enum
 CONSOLE::INSTANCE::INSTANCE(int t)
 {
 	// init ringbuffers
-	history = ringbuf_init(history_data, sizeof(history_data), RINGBUF_FLAG_RECYCLE);
-	backlog = ringbuf_init(backlog_data, sizeof(backlog_data), RINGBUF_FLAG_RECYCLE);
+	//history = ringbuf_init(history_data, sizeof(history_data), RINGBUF_FLAG_RECYCLE);
+	//backlog = ringbuf_init(backlog_data, sizeof(backlog_data), RINGBUF_FLAG_RECYCLE);
 	
 	history_entry = 0x0;
 	
@@ -83,7 +82,7 @@ void CONSOLE::INSTANCE::on_input(INPUT_EVENT e)
 		{
 			if(input.get_string()[0])
 			{
-				char *entry = (char *)ringbuf_allocate(history, input.get_length()+1);
+				char *entry = history.Allocate(input.get_length()+1);
 				mem_copy(entry, input.get_string(), input.get_length()+1);
 				
 				execute_line(input.get_string());
@@ -97,13 +96,13 @@ void CONSOLE::INSTANCE::on_input(INPUT_EVENT e)
 		{
 			if (history_entry)
 			{
-				char *test = (char *)ringbuf_prev(history, history_entry);
+				char *test = history.Prev(history_entry);
 
 				if (test)
 					history_entry = test;
 			}
 			else
-				history_entry = (char *)ringbuf_last(history);
+				history_entry = history.Last();
 
 			if (history_entry)
 			{
@@ -116,7 +115,7 @@ void CONSOLE::INSTANCE::on_input(INPUT_EVENT e)
 		else if (e.key == KEY_DOWN)
 		{
 			if (history_entry)
-				history_entry = (char *)ringbuf_next(history, history_entry);
+				history_entry = history.Next(history_entry);
 
 			if (history_entry)
 			{
@@ -173,7 +172,7 @@ void CONSOLE::INSTANCE::print_line(const char *line)
 	if (len > 255)
 		len = 255;
 
-	char *entry = (char *)ringbuf_allocate(backlog, len+1);
+	char *entry = backlog.Allocate(len+1);
 	mem_copy(entry, line, len+1);
 }
 
@@ -212,6 +211,7 @@ static float console_scale_func(float t)
 
 struct RENDERINFO
 {
+	CONSOLE *self;
 	TEXT_CURSOR cursor;
 	const char *current_cmd;
 	int wanted_completion;
@@ -225,11 +225,11 @@ void CONSOLE::possible_commands_render_callback(const char *str, void *user)
 	if(info->enum_count == info->wanted_completion)
 	{
 		float tw = gfx_text_width(info->cursor.font, info->cursor.font_size, str, -1);
-		gfx_texture_set(-1);
-		gfx_quads_begin();
-			gfx_setcolor(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,0.85f);
-			draw_round_rect(info->cursor.x-3, info->cursor.y, tw+5, info->cursor.font_size+4, info->cursor.font_size/3);
-		gfx_quads_end();
+		info->self->Graphics()->TextureSet(-1);
+		info->self->Graphics()->QuadsBegin();
+			info->self->Graphics()->SetColor(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,0.85f);
+			info->self->RenderTools()->draw_round_rect(info->cursor.x-3, info->cursor.y, tw+5, info->cursor.font_size+4, info->cursor.font_size/3);
+		info->self->Graphics()->QuadsEnd();
 		
 		gfx_text_color(0.05f, 0.05f, 0.05f,1);
 		gfx_text_ex(&info->cursor, str, -1);
@@ -260,7 +260,7 @@ void CONSOLE::possible_commands_render_callback(const char *str, void *user)
 
 void CONSOLE::on_render()
 {
-    RECT screen = *ui_screen();
+    CUIRect screen = *UI()->Screen();
 	float console_max_height = screen.h*3/5.0f;
 	float console_height;
 
@@ -296,45 +296,45 @@ void CONSOLE::on_render()
 
 	console_height = console_height_scale*console_max_height;
 
-	gfx_mapscreen(screen.x, screen.y, screen.w, screen.h);
+	Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);
 
 	// do console shadow
-	gfx_texture_set(-1);
-    gfx_quads_begin();
-    gfx_setcolorvertex(0, 0,0,0, 0.5f);
-    gfx_setcolorvertex(1, 0,0,0, 0.5f);
-    gfx_setcolorvertex(2, 0,0,0, 0.0f);
-    gfx_setcolorvertex(3, 0,0,0, 0.0f);
-    gfx_quads_drawTL(0,console_height,screen.w,10.0f);
-    gfx_quads_end();
+	Graphics()->TextureSet(-1);
+    Graphics()->QuadsBegin();
+    Graphics()->SetColorVertex(0, 0,0,0, 0.5f);
+    Graphics()->SetColorVertex(1, 0,0,0, 0.5f);
+    Graphics()->SetColorVertex(2, 0,0,0, 0.0f);
+    Graphics()->SetColorVertex(3, 0,0,0, 0.0f);
+    Graphics()->QuadsDrawTL(0,console_height,screen.w,10.0f);
+    Graphics()->QuadsEnd();
 
 	// do background
-	gfx_texture_set(data->images[IMAGE_CONSOLE_BG].id);
-    gfx_quads_begin();
-    gfx_setcolor(0.2f, 0.2f, 0.2f,0.9f);
+	Graphics()->TextureSet(data->images[IMAGE_CONSOLE_BG].id);
+    Graphics()->QuadsBegin();
+    Graphics()->SetColor(0.2f, 0.2f, 0.2f,0.9f);
     if(console_type != 0)
-	    gfx_setcolor(0.4f, 0.2f, 0.2f,0.9f);
-    gfx_quads_setsubset(0,-console_height*0.075f,screen.w*0.075f*0.5f,0);
-    gfx_quads_drawTL(0,0,screen.w,console_height);
-    gfx_quads_end();
+	    Graphics()->SetColor(0.4f, 0.2f, 0.2f,0.9f);
+    Graphics()->QuadsSetSubset(0,-console_height*0.075f,screen.w*0.075f*0.5f,0);
+    Graphics()->QuadsDrawTL(0,0,screen.w,console_height);
+    Graphics()->QuadsEnd();
 
 	// do small bar shadow
-	gfx_texture_set(-1);
-    gfx_quads_begin();
-    gfx_setcolorvertex(0, 0,0,0, 0.0f);
-    gfx_setcolorvertex(1, 0,0,0, 0.0f);
-    gfx_setcolorvertex(2, 0,0,0, 0.25f);
-    gfx_setcolorvertex(3, 0,0,0, 0.25f);
-    gfx_quads_drawTL(0,console_height-20,screen.w,10);
-    gfx_quads_end();
+	Graphics()->TextureSet(-1);
+    Graphics()->QuadsBegin();
+    Graphics()->SetColorVertex(0, 0,0,0, 0.0f);
+    Graphics()->SetColorVertex(1, 0,0,0, 0.0f);
+    Graphics()->SetColorVertex(2, 0,0,0, 0.25f);
+    Graphics()->SetColorVertex(3, 0,0,0, 0.25f);
+    Graphics()->QuadsDrawTL(0,console_height-20,screen.w,10);
+    Graphics()->QuadsEnd();
 
 	// do the lower bar
-	gfx_texture_set(data->images[IMAGE_CONSOLE_BAR].id);
-    gfx_quads_begin();
-    gfx_setcolor(1.0f, 1.0f, 1.0f, 0.9f);
-    gfx_quads_setsubset(0,0.1f,screen.w*0.015f,1-0.1f);
-    gfx_quads_drawTL(0,console_height-10.0f,screen.w,10.0f);
-    gfx_quads_end();
+	Graphics()->TextureSet(data->images[IMAGE_CONSOLE_BAR].id);
+    Graphics()->QuadsBegin();
+    Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.9f);
+    Graphics()->QuadsSetSubset(0,0.1f,screen.w*0.015f,1-0.1f);
+    Graphics()->QuadsDrawTL(0,console_height-10.0f,screen.w,10.0f);
+    Graphics()->QuadsEnd();
     
     console_height -= 22.0f;
     
@@ -351,6 +351,7 @@ void CONSOLE::on_render()
 		gfx_text_set_cursor(&cursor, x, y, font_size, TEXTFLAG_RENDER);
 
 		RENDERINFO info;
+		info.self = this;
 		info.wanted_completion = console->completion_chosen;
 		info.enum_count = 0;
 		info.current_cmd = console->completion_buffer;
@@ -407,13 +408,13 @@ void CONSOLE::on_render()
 
 		// render log
 		y -= row_height;
-		char *entry = (char *)ringbuf_last(console->backlog);
+		char *entry = console->backlog.Last();
 		while (y > 0.0f && entry)
 		{
 			gfx_text(0, x, y, font_size, entry, -1);
 			y -= row_height;
 
-			entry = (char *)ringbuf_prev(console->backlog, entry);
+			entry = console->backlog.Prev(entry);
 		}
 	}	
 }
diff --git a/src/game/client/components/console.hpp b/src/game/client/components/console.hpp
index 0a4adbda..78da98b8 100644
--- a/src/game/client/components/console.hpp
+++ b/src/game/client/components/console.hpp
@@ -1,4 +1,5 @@
 #include <engine/e_client_interface.h>
+#include <engine/e_ringbuffer.h>
 #include <game/client/component.hpp>
 #include <game/client/lineinput.hpp>
 
@@ -7,12 +8,9 @@ class CONSOLE : public COMPONENT
 	class INSTANCE
 	{
 	public:
-		char history_data[65536];
-		struct RINGBUFFER *history;
+		TStaticRingBuffer<char, 64*1024, CRingBufferBase::FLAG_RECYCLE> backlog;
+		TStaticRingBuffer<char, 64*1024, CRingBufferBase::FLAG_RECYCLE> history;
 		char *history_entry;
-		
-		char backlog_data[65536];
-		struct RINGBUFFER *backlog;
 
 		LINEINPUT input;
 		
diff --git a/src/game/client/components/damageind.cpp b/src/game/client/components/damageind.cpp
index f585e4d3..7f1991dc 100644
--- a/src/game/client/components/damageind.cpp
+++ b/src/game/client/components/damageind.cpp
@@ -1,4 +1,5 @@
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 
@@ -44,8 +45,8 @@ void DAMAGEIND::create(vec2 pos, vec2 dir)
 
 void DAMAGEIND::on_render()
 {
-	gfx_texture_set(data->images[IMAGE_GAME].id);
-	gfx_quads_begin();
+	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	Graphics()->QuadsBegin();
 	for(int i = 0; i < num_items;)
 	{
 		vec2 pos = mix(items[i].pos+items[i].dir*75.0f, items[i].pos, clamp((items[i].life-0.60f)/0.15f, 0.0f, 1.0f));
@@ -55,12 +56,12 @@ void DAMAGEIND::on_render()
 			destroy_i(&items[i]);
 		else
 		{
-			gfx_setcolor(1.0f,1.0f,1.0f, items[i].life/0.1f);
-			gfx_quads_setrotation(items[i].startangle + items[i].life * 2.0f);
-			select_sprite(SPRITE_STAR1);
-			draw_sprite(pos.x, pos.y, 48.0f);
+			Graphics()->SetColor(1.0f,1.0f,1.0f, items[i].life/0.1f);
+			Graphics()->QuadsSetRotation(items[i].startangle + items[i].life * 2.0f);
+			RenderTools()->select_sprite(SPRITE_STAR1);
+			RenderTools()->draw_sprite(pos.x, pos.y, 48.0f);
 			i++;
 		}
 	}
-	gfx_quads_end();
+	Graphics()->QuadsEnd();
 }
diff --git a/src/game/client/components/debughud.cpp b/src/game/client/components/debughud.cpp
index ada006ea..c7cc559b 100644
--- a/src/game/client/components/debughud.cpp
+++ b/src/game/client/components/debughud.cpp
@@ -5,6 +5,7 @@ extern "C" {
 }
 
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 
@@ -23,7 +24,7 @@ void DEBUGHUD::render_netcorrections()
 	if(!config.debug || !gameclient.snap.local_character || !gameclient.snap.local_prev_character)
 		return;
 
-	gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300);
+	Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300);
 	
 	/*float speed = distance(vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y),
 		vec2(netobjects.local_character->x, netobjects.local_character->y));*/
@@ -50,7 +51,7 @@ void DEBUGHUD::render_tuning()
 		
 	TUNING_PARAMS standard_tuning;
 		
-	gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300);
+	Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300);
 	
 	float y = 50.0f;
 	int count = 0;
@@ -87,9 +88,9 @@ void DEBUGHUD::render_tuning()
 	
 	y = y+count*6;
 	
-	gfx_texture_set(-1);
-	gfx_blend_normal();
-	gfx_lines_begin();
+	Graphics()->TextureSet(-1);
+	Graphics()->BlendNormal();
+	Graphics()->LinesBegin();
 	float height = 50.0f;
 	float pv = 1;
 	for(int i = 0; i < 100; i++)
@@ -97,11 +98,11 @@ void DEBUGHUD::render_tuning()
 		float speed = i/100.0f * 3000;
 		float ramp = velocity_ramp(speed, gameclient.tuning.velramp_start, gameclient.tuning.velramp_range, gameclient.tuning.velramp_curvature);
 		float rampedspeed = (speed * ramp)/1000.0f;
-		gfx_lines_draw((i-1)*2, y+height-pv*height, i*2, y+height-rampedspeed*height);
-		//gfx_lines_draw((i-1)*2, 200, i*2, 200);
+		Graphics()->LinesDraw((i-1)*2, y+height-pv*height, i*2, y+height-rampedspeed*height);
+		//Graphics()->LinesDraw((i-1)*2, 200, i*2, 200);
 		pv = rampedspeed;
 	}
-	gfx_lines_end();
+	Graphics()->LinesEnd();
 	gfx_text_color(1,1,1,1);
 }
 
diff --git a/src/game/client/components/emoticon.cpp b/src/game/client/components/emoticon.cpp
index 934b2fcf..8001a306 100644
--- a/src/game/client/components/emoticon.cpp
+++ b/src/game/client/components/emoticon.cpp
@@ -1,4 +1,5 @@
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 
@@ -70,7 +71,7 @@ void EMOTICON::draw_circle(float x, float y, float r, int segments)
 		float sa2 = sinf(a2);
 		float sa3 = sinf(a3);
 
-		gfx_quads_draw_freeform(
+		client->Graphics()->QuadsDrawFreeform(
 			x, y,
 			x+ca1*r, y+sa1*r,
 			x+ca3*r, y+sa3*r,
@@ -107,20 +108,20 @@ void EMOTICON::on_render()
 	if (length(selector_mouse) > 100)
 		selected_emote = (int)(selected_angle / (2*pi) * 12.0f);
 
-    RECT screen = *ui_screen();
+    CUIRect screen = *UI()->Screen();
 
-	gfx_mapscreen(screen.x, screen.y, screen.w, screen.h);
+	Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);
 
-	gfx_blend_normal();
+	Graphics()->BlendNormal();
 
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.3f);
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(0,0,0,0.3f);
 	draw_circle(screen.w/2, screen.h/2, 160, 64);
-	gfx_quads_end();
+	Graphics()->QuadsEnd();
 
-	gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
-	gfx_quads_begin();
+	Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id);
+	Graphics()->QuadsBegin();
 
 	for (int i = 0; i < 12; i++)
 	{
@@ -134,17 +135,17 @@ void EMOTICON::on_render()
 
 		float nudge_x = 120 * cos(angle);
 		float nudge_y = 120 * sin(angle);
-		select_sprite(SPRITE_OOP + i);
-		gfx_quads_draw(screen.w/2 + nudge_x, screen.h/2 + nudge_y, size, size);
+		RenderTools()->select_sprite(SPRITE_OOP + i);
+		Graphics()->QuadsDraw(screen.w/2 + nudge_x, screen.h/2 + nudge_y, size, size);
 	}
 
-	gfx_quads_end();
+	Graphics()->QuadsEnd();
 
-    gfx_texture_set(data->images[IMAGE_CURSOR].id);
-    gfx_quads_begin();
-    gfx_setcolor(1,1,1,1);
-    gfx_quads_drawTL(selector_mouse.x+screen.w/2,selector_mouse.y+screen.h/2,24,24);
-    gfx_quads_end();
+    Graphics()->TextureSet(data->images[IMAGE_CURSOR].id);
+    Graphics()->QuadsBegin();
+    Graphics()->SetColor(1,1,1,1);
+    Graphics()->QuadsDrawTL(selector_mouse.x+screen.w/2,selector_mouse.y+screen.h/2,24,24);
+    Graphics()->QuadsEnd();
 }
 
 void EMOTICON::emote(int emoticon)
diff --git a/src/game/client/components/flow.cpp b/src/game/client/components/flow.cpp
index b2f983e6..9ecd4b5c 100644
--- a/src/game/client/components/flow.cpp
+++ b/src/game/client/components/flow.cpp
@@ -1,3 +1,4 @@
+#include <engine/client/graphics.h>
 #include <game/mapitems.hpp>
 #include <game/layers.hpp>
 #include "flow.hpp"
@@ -15,17 +16,17 @@ void FLOW::dbg_render()
 	if(!cells)
 		return;
 
-	gfx_texture_set(-1);
-	gfx_lines_begin();
+	Graphics()->TextureSet(-1);
+	Graphics()->LinesBegin();
 	for(int y = 0; y < height; y++)
 		for(int x = 0; x < width; x++)
 		{
 			vec2 pos(x*spacing, y*spacing);
 			vec2 vel = cells[y*width+x].vel * 0.01f;
-			gfx_lines_draw(pos.x, pos.y, pos.x+vel.x, pos.y+vel.y);
+			Graphics()->LinesDraw(pos.x, pos.y, pos.x+vel.x, pos.y+vel.y);
 		}
 		
-	gfx_lines_end();
+	Graphics()->LinesEnd();
 }
 
 void FLOW::init()
diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp
index b1926ab4..837322fb 100644
--- a/src/game/client/components/hud.cpp
+++ b/src/game/client/components/hud.cpp
@@ -1,6 +1,7 @@
 #include <memory.h> // memcmp
 
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 
@@ -35,11 +36,11 @@ void HUD::render_goals()
 	
 	int gameflags = gameclient.snap.gameobj->flags;
 	
-	float whole = 300*gfx_screenaspect();
+	float whole = 300*Graphics()->ScreenAspect();
 	float half = whole/2.0f;
 
 
-	gfx_mapscreen(0,0,300*gfx_screenaspect(),300);
+	Graphics()->MapScreen(0,0,300*Graphics()->ScreenAspect(),300);
 	if(!gameclient.snap.gameobj->sudden_death)
 	{
 		char buf[32];
@@ -71,15 +72,15 @@ void HUD::render_goals()
 	{
 		for(int t = 0; t < 2; t++)
 		{
-			gfx_blend_normal();
-			gfx_texture_set(-1);
-			gfx_quads_begin();
+			Graphics()->BlendNormal();
+			Graphics()->TextureSet(-1);
+			Graphics()->QuadsBegin();
 			if(t == 0)
-				gfx_setcolor(1,0,0,0.25f);
+				Graphics()->SetColor(1,0,0,0.25f);
 			else
-				gfx_setcolor(0,0,1,0.25f);
-			draw_round_rect(whole-40, 300-40-15+t*20, 50, 18, 5.0f);
-			gfx_quads_end();
+				Graphics()->SetColor(0,0,1,0.25f);
+			RenderTools()->draw_round_rect(whole-40, 300-40-15+t*20, 50, 18, 5.0f);
+			Graphics()->QuadsEnd();
 
 			char buf[32];
 			str_format(buf, sizeof(buf), "%d", t?gameclient.snap.gameobj->teamscore_blue:gameclient.snap.gameobj->teamscore_red);
@@ -92,16 +93,16 @@ void HUD::render_goals()
 				{
 					if(gameclient.snap.flags[t]->carried_by == -2 || (gameclient.snap.flags[t]->carried_by == -1 && ((client_tick()/10)&1)))
 					{
-						gfx_blend_normal();
-						gfx_texture_set(data->images[IMAGE_GAME].id);
-						gfx_quads_begin();
+						Graphics()->BlendNormal();
+						Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+						Graphics()->QuadsBegin();
 
-						if(t == 0) select_sprite(SPRITE_FLAG_RED);
-						else select_sprite(SPRITE_FLAG_BLUE);
+						if(t == 0) RenderTools()->select_sprite(SPRITE_FLAG_RED);
+						else RenderTools()->select_sprite(SPRITE_FLAG_BLUE);
 						
 						float size = 16;					
-						gfx_quads_drawTL(whole-40+5, 300-40-15+t*20+1, size/2, size);
-						gfx_quads_end();
+						Graphics()->QuadsDrawTL(whole-40+5, 300-40-15+t*20+1, size/2, size);
+						Graphics()->QuadsEnd();
 					}
 					else if(gameclient.snap.flags[t]->carried_by >= 0)
 					{
@@ -112,7 +113,7 @@ void HUD::render_goals()
 						TEE_RENDER_INFO info = gameclient.clients[id].render_info;
 						info.size = 18.0f;
 						
-						render_tee(ANIMSTATE::get_idle(), &info, EMOTE_NORMAL, vec2(1,0),
+						RenderTools()->RenderTee(ANIMSTATE::get_idle(), &info, EMOTE_NORMAL, vec2(1,0),
 							vec2(whole-40+10, 300-40-15+9+t*20+1));
 					}
 				}
@@ -127,7 +128,7 @@ void HUD::render_goals()
 	{
 		char buf[256];
 		float w = gfx_text_width(0, 24, "Warmup", -1);
-		gfx_text(0, 150*gfx_screenaspect()+-w/2, 50, 24, "Warmup", -1);
+		gfx_text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, 24, "Warmup", -1);
 
 		int seconds = gameclient.snap.gameobj->warmup/SERVER_TICK_SPEED;
 		if(seconds < 5)
@@ -135,16 +136,16 @@ void HUD::render_goals()
 		else
 			str_format(buf, sizeof(buf), "%d", seconds);
 		w = gfx_text_width(0, 24, buf, -1);
-		gfx_text(0, 150*gfx_screenaspect()+-w/2, 75, 24, buf, -1);
+		gfx_text(0, 150*Graphics()->ScreenAspect()+-w/2, 75, 24, buf, -1);
 	}	
 }
 
-static void mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *group)
+void HUD::mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *group)
 {
 	float points[4];
-	mapscreen_to_world(center_x, center_y, group->parallax_x/100.0f, group->parallax_y/100.0f,
-		group->offset_x, group->offset_y, gfx_screenaspect(), 1.0f, points);
-	gfx_mapscreen(points[0], points[1], points[2], points[3]);
+	RenderTools()->mapscreen_to_world(center_x, center_y, group->parallax_x/100.0f, group->parallax_y/100.0f,
+		group->offset_x, group->offset_y, Graphics()->ScreenAspect(), 1.0f, points);
+	Graphics()->MapScreen(points[0], points[1], points[2], points[3]);
 }
 
 void HUD::render_fps()
@@ -163,7 +164,7 @@ void HUD::render_connectionwarning()
 	{
 		const char *text = "Connection Problems...";
 		float w = gfx_text_width(0, 24, text, -1);
-		gfx_text(0, 150*gfx_screenaspect()-w/2, 50, 24, text, -1);
+		gfx_text(0, 150*Graphics()->ScreenAspect()-w/2, 50, 24, text, -1);
 	}
 }
 
@@ -192,11 +193,11 @@ void HUD::render_voting()
 	if(!gameclient.voting->is_voting())
 		return;
 	
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.40f);
-	draw_round_rect(-10, 60-2, 100+10+4+5, 28, 5.0f);
-	gfx_quads_end();
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(0,0,0,0.40f);
+	RenderTools()->draw_round_rect(-10, 60-2, 100+10+4+5, 28, 5.0f);
+	Graphics()->QuadsEnd();
 
 	gfx_text_color(1,1,1,1);
 
@@ -208,17 +209,17 @@ void HUD::render_voting()
 	gfx_text(0x0, 5+100-tw, 60, 6, buf, -1);
 	
 
-	RECT base = {5, 70, 100, 4};
+	CUIRect base = {5, 70, 100, 4};
 	gameclient.voting->render_bars(base, false);
 	
 	const char *yes_key = gameclient.binds->get_key("vote yes");
 	const char *no_key = gameclient.binds->get_key("vote no");
 	str_format(buf, sizeof(buf), "%s - Vote Yes", yes_key);
 	base.y += base.h+1;
-	ui_do_label(&base, buf, 6.0f, -1);
+	UI()->DoLabel(&base, buf, 6.0f, -1);
 
 	str_format(buf, sizeof(buf), "Vote No - %s", no_key);
-	ui_do_label(&base, buf, 6.0f, 1);
+	UI()->DoLabel(&base, buf, 6.0f, 1);
 }
 
 void HUD::render_cursor()
@@ -227,14 +228,14 @@ void HUD::render_cursor()
 		return;
 		
 	mapscreen_to_group(gameclient.camera->center.x, gameclient.camera->center.y, layers_game_group());
-	gfx_texture_set(data->images[IMAGE_GAME].id);
-	gfx_quads_begin();
+	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	Graphics()->QuadsBegin();
 
 	// render cursor
-	select_sprite(data->weapons.id[gameclient.snap.local_character->weapon%NUM_WEAPONS].sprite_cursor);
+	RenderTools()->select_sprite(data->weapons.id[gameclient.snap.local_character->weapon%NUM_WEAPONS].sprite_cursor);
 	float cursorsize = 64;
-	draw_sprite(gameclient.controls->target_pos.x, gameclient.controls->target_pos.y, cursorsize);
-	gfx_quads_end();
+	RenderTools()->draw_sprite(gameclient.controls->target_pos.x, gameclient.controls->target_pos.y, cursorsize);
+	Graphics()->QuadsEnd();
 }
 
 void HUD::render_healthandammo()
@@ -247,40 +248,40 @@ void HUD::render_healthandammo()
 	// render ammo count
 	// render gui stuff
 
-	gfx_texture_set(data->images[IMAGE_GAME].id);
-	gfx_mapscreen(0,0,width,300);
+	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	Graphics()->MapScreen(0,0,width,300);
 	
-	gfx_quads_begin();
+	Graphics()->QuadsBegin();
 	
 	// if weaponstage is active, put a "glow" around the stage ammo
-	select_sprite(data->weapons.id[gameclient.snap.local_character->weapon%NUM_WEAPONS].sprite_proj);
+	RenderTools()->select_sprite(data->weapons.id[gameclient.snap.local_character->weapon%NUM_WEAPONS].sprite_proj);
 	for (int i = 0; i < min(gameclient.snap.local_character->ammocount, 10); i++)
-		gfx_quads_drawTL(x+i*12,y+24,10,10);
+		Graphics()->QuadsDrawTL(x+i*12,y+24,10,10);
 
-	gfx_quads_end();
+	Graphics()->QuadsEnd();
 
-	gfx_quads_begin();
+	Graphics()->QuadsBegin();
 	int h = 0;
 
 	// render health
-	select_sprite(SPRITE_HEALTH_FULL);
+	RenderTools()->select_sprite(SPRITE_HEALTH_FULL);
 	for(; h < gameclient.snap.local_character->health; h++)
-		gfx_quads_drawTL(x+h*12,y,10,10);
+		Graphics()->QuadsDrawTL(x+h*12,y,10,10);
 
-	select_sprite(SPRITE_HEALTH_EMPTY);
+	RenderTools()->select_sprite(SPRITE_HEALTH_EMPTY);
 	for(; h < 10; h++)
-		gfx_quads_drawTL(x+h*12,y,10,10);
+		Graphics()->QuadsDrawTL(x+h*12,y,10,10);
 
 	// render armor meter
 	h = 0;
-	select_sprite(SPRITE_ARMOR_FULL);
+	RenderTools()->select_sprite(SPRITE_ARMOR_FULL);
 	for(; h < gameclient.snap.local_character->armor; h++)
-		gfx_quads_drawTL(x+h*12,y+12,10,10);
+		Graphics()->QuadsDrawTL(x+h*12,y+12,10,10);
 
-	select_sprite(SPRITE_ARMOR_EMPTY);
+	RenderTools()->select_sprite(SPRITE_ARMOR_EMPTY);
 	for(; h < 10; h++)
-		gfx_quads_drawTL(x+h*12,y+12,10,10);
-	gfx_quads_end();
+		Graphics()->QuadsDrawTL(x+h*12,y+12,10,10);
+	Graphics()->QuadsEnd();
 }
 
 void HUD::on_render()
@@ -288,7 +289,7 @@ void HUD::on_render()
 	if(!gameclient.snap.gameobj)
 		return;
 		
-	width = 300*gfx_screenaspect();
+	width = 300*Graphics()->ScreenAspect();
 
 	bool spectate = false;
 	if(gameclient.snap.local_info && gameclient.snap.local_info->team == -1)
diff --git a/src/game/client/components/hud.hpp b/src/game/client/components/hud.hpp
index 41fa0ff2..92ff0122 100644
--- a/src/game/client/components/hud.hpp
+++ b/src/game/client/components/hud.hpp
@@ -13,6 +13,8 @@ class HUD : public COMPONENT
 	void render_healthandammo();
 	void render_goals();
 	
+	
+	void mapscreen_to_group(float center_x, float center_y, struct MAPITEM_GROUP *group);
 public:
 	HUD();
 	
diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp
index 1d579619..3c9e1b79 100644
--- a/src/game/client/components/items.cpp
+++ b/src/game/client/components/items.cpp
@@ -1,4 +1,5 @@
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 
@@ -44,10 +45,10 @@ void ITEMS::render_projectile(const NETOBJ_PROJECTILE *current, int itemid)
 	vec2 prevpos = calc_pos(startpos, startvel, curvature, speed, ct-0.001f);
 
 
-	gfx_texture_set(data->images[IMAGE_GAME].id);
-	gfx_quads_begin();
+	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	Graphics()->QuadsBegin();
 	
-	select_sprite(data->weapons.id[clamp(current->type, 0, NUM_WEAPONS-1)].sprite_proj);
+	RenderTools()->select_sprite(data->weapons.id[clamp(current->type, 0, NUM_WEAPONS-1)].sprite_proj);
 	vec2 vel = pos-prevpos;
 	//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
 	
@@ -57,7 +58,7 @@ void ITEMS::render_projectile(const NETOBJ_PROJECTILE *current, int itemid)
 	{
 		gameclient.effects->smoketrail(pos, vel*-1);
 		gameclient.flow->add(pos, vel*1000*client_frametime(), 10.0f);
-		gfx_quads_setrotation(client_localtime()*pi*2*2 + itemid);
+		Graphics()->QuadsSetRotation(client_localtime()*pi*2*2 + itemid);
 	}
 	else
 	{
@@ -65,28 +66,28 @@ void ITEMS::render_projectile(const NETOBJ_PROJECTILE *current, int itemid)
 		gameclient.flow->add(pos, vel*1000*client_frametime(), 10.0f);
 
 		if(length(vel) > 0.00001f)
-			gfx_quads_setrotation(get_angle(vel));
+			Graphics()->QuadsSetRotation(get_angle(vel));
 		else
-			gfx_quads_setrotation(0);
+			Graphics()->QuadsSetRotation(0);
 
 	}
 
-	gfx_quads_draw(pos.x, pos.y, 32, 32);
-	gfx_quads_setrotation(0);
-	gfx_quads_end();
+	Graphics()->QuadsDraw(pos.x, pos.y, 32, 32);
+	Graphics()->QuadsSetRotation(0);
+	Graphics()->QuadsEnd();
 }
 
 void ITEMS::render_pickup(const NETOBJ_PICKUP *prev, const NETOBJ_PICKUP *current)
 {
-	gfx_texture_set(data->images[IMAGE_GAME].id);
-	gfx_quads_begin();
+	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	Graphics()->QuadsBegin();
 	vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
 	float angle = 0.0f;
 	float size = 64.0f;
 	if (current->type == POWERUP_WEAPON)
 	{
 		angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
-		select_sprite(data->weapons.id[clamp(current->subtype, 0, NUM_WEAPONS-1)].sprite_body);
+		RenderTools()->select_sprite(data->weapons.id[clamp(current->subtype, 0, NUM_WEAPONS-1)].sprite_body);
 		size = data->weapons.id[clamp(current->subtype, 0, NUM_WEAPONS-1)].visual_size;
 	}
 	else
@@ -97,7 +98,7 @@ void ITEMS::render_pickup(const NETOBJ_PICKUP *prev, const NETOBJ_PICKUP *curren
 			SPRITE_PICKUP_WEAPON,
 			SPRITE_PICKUP_NINJA
 			};
-		select_sprite(c[current->type]);
+		RenderTools()->select_sprite(c[current->type]);
 
 		if(c[current->type] == SPRITE_PICKUP_NINJA)
 		{
@@ -107,13 +108,13 @@ void ITEMS::render_pickup(const NETOBJ_PICKUP *prev, const NETOBJ_PICKUP *curren
 		}
 	}
 
-	gfx_quads_setrotation(angle);
+	Graphics()->QuadsSetRotation(angle);
 
 	float offset = pos.y/32.0f + pos.x/32.0f;
 	pos.x += cosf(client_localtime()*2.0f+offset)*2.5f;
 	pos.y += sinf(client_localtime()*2.0f+offset)*2.5f;
-	draw_sprite(pos.x, pos.y, size);
-	gfx_quads_end();
+	RenderTools()->draw_sprite(pos.x, pos.y, size);
+	Graphics()->QuadsEnd();
 }
 
 void ITEMS::render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current)
@@ -121,16 +122,16 @@ void ITEMS::render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current)
 	float angle = 0.0f;
 	float size = 42.0f;
 
-	gfx_blend_normal();
-	gfx_texture_set(data->images[IMAGE_GAME].id);
-	gfx_quads_begin();
+	Graphics()->BlendNormal();
+	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	Graphics()->QuadsBegin();
 
 	if(current->team == 0) // red team
-		select_sprite(SPRITE_FLAG_RED);
+		RenderTools()->select_sprite(SPRITE_FLAG_RED);
 	else
-		select_sprite(SPRITE_FLAG_BLUE);
+		RenderTools()->select_sprite(SPRITE_FLAG_BLUE);
 
-	gfx_quads_setrotation(angle);
+	Graphics()->QuadsSetRotation(angle);
 
 	vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
 	
@@ -142,8 +143,8 @@ void ITEMS::render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current)
 	if(gameclient.snap.local_info && current->carried_by == gameclient.snap.local_info->cid)
 		pos = gameclient.local_character_pos;
 
-	gfx_quads_draw(pos.x, pos.y-size*0.75f, size, size*2);
-	gfx_quads_end();
+	Graphics()->QuadsDraw(pos.x, pos.y-size*0.75f, size, size*2);
+	Graphics()->QuadsEnd();
 }
 
 
@@ -161,19 +162,19 @@ void ITEMS::render_laser(const struct NETOBJ_LASER *current)
 	
 	vec2 out, border;
 	
-	gfx_blend_normal();
-	gfx_texture_set(-1);
-	gfx_quads_begin();
+	Graphics()->BlendNormal();
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
 	
 	//vec4 inner_color(0.15f,0.35f,0.75f,1.0f);
 	//vec4 outer_color(0.65f,0.85f,1.0f,1.0f);
 
 	// do outline
 	vec4 outer_color(0.075f,0.075f,0.25f,1.0f);
-	gfx_setcolor(outer_color.r,outer_color.g,outer_color.b,1.0f);
+	Graphics()->SetColor(outer_color.r,outer_color.g,outer_color.b,1.0f);
 	out = vec2(dir.y, -dir.x) * (7.0f*ia);
 
-	gfx_quads_draw_freeform(
+	Graphics()->QuadsDrawFreeform(
 			from.x-out.x, from.y-out.y,
 			from.x+out.x, from.y+out.y,
 			pos.x-out.x, pos.y-out.y,
@@ -183,34 +184,34 @@ void ITEMS::render_laser(const struct NETOBJ_LASER *current)
 	// do inner	
 	vec4 inner_color(0.5f,0.5f,1.0f,1.0f);
 	out = vec2(dir.y, -dir.x) * (5.0f*ia);
-	gfx_setcolor(inner_color.r, inner_color.g, inner_color.b, 1.0f); // center
+	Graphics()->SetColor(inner_color.r, inner_color.g, inner_color.b, 1.0f); // center
 	
-	gfx_quads_draw_freeform(
+	Graphics()->QuadsDrawFreeform(
 			from.x-out.x, from.y-out.y,
 			from.x+out.x, from.y+out.y,
 			pos.x-out.x, pos.y-out.y,
 			pos.x+out.x, pos.y+out.y
 		);
 		
-	gfx_quads_end();
+	Graphics()->QuadsEnd();
 	
 	// render head
 	{
-		gfx_blend_normal();
-		gfx_texture_set(data->images[IMAGE_PARTICLES].id);
-		gfx_quads_begin();
+		Graphics()->BlendNormal();
+		Graphics()->TextureSet(data->images[IMAGE_PARTICLES].id);
+		Graphics()->QuadsBegin();
 
 		int sprites[] = {SPRITE_PART_SPLAT01, SPRITE_PART_SPLAT02, SPRITE_PART_SPLAT03};
-		select_sprite(sprites[client_tick()%3]);
-		gfx_quads_setrotation(client_tick());
-		gfx_setcolor(outer_color.r,outer_color.g,outer_color.b,1.0f);
-		gfx_quads_draw(pos.x, pos.y, 24,24);
-		gfx_setcolor(inner_color.r, inner_color.g, inner_color.b, 1.0f);
-		gfx_quads_draw(pos.x, pos.y, 20,20);
-		gfx_quads_end();
+		RenderTools()->select_sprite(sprites[client_tick()%3]);
+		Graphics()->QuadsSetRotation(client_tick());
+		Graphics()->SetColor(outer_color.r,outer_color.g,outer_color.b,1.0f);
+		Graphics()->QuadsDraw(pos.x, pos.y, 24,24);
+		Graphics()->SetColor(inner_color.r, inner_color.g, inner_color.b, 1.0f);
+		Graphics()->QuadsDraw(pos.x, pos.y, 20,20);
+		Graphics()->QuadsEnd();
 	}
 	
-	gfx_blend_normal();	
+	Graphics()->BlendNormal();	
 }
 
 void ITEMS::on_render()
diff --git a/src/game/client/components/killmessages.cpp b/src/game/client/components/killmessages.cpp
index 410f2c3d..e6232b7d 100644
--- a/src/game/client/components/killmessages.cpp
+++ b/src/game/client/components/killmessages.cpp
@@ -1,4 +1,5 @@
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 
@@ -35,10 +36,10 @@ void KILLMESSAGES::on_message(int msgtype, void *rawmsg)
 
 void KILLMESSAGES::on_render()
 {
-	float width = 400*3.0f*gfx_screenaspect();
+	float width = 400*3.0f*Graphics()->ScreenAspect();
 	float height = 400*3.0f;
 
-	gfx_mapscreen(0, 0, width*1.5f, height*1.5f);
+	Graphics()->MapScreen(0, 0, width*1.5f, height*1.5f);
 	float startx = width*1.5f-10.0f;
 	float y = 20.0f;
 
@@ -66,31 +67,31 @@ void KILLMESSAGES::on_render()
 		{
 			if(killmsgs[r].mode_special&1)
 			{
-				gfx_blend_normal();
-				gfx_texture_set(data->images[IMAGE_GAME].id);
-				gfx_quads_begin();
+				Graphics()->BlendNormal();
+				Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+				Graphics()->QuadsBegin();
 
-				if(gameclient.clients[killmsgs[r].victim].team == 0) select_sprite(SPRITE_FLAG_BLUE);
-				else select_sprite(SPRITE_FLAG_RED);
+				if(gameclient.clients[killmsgs[r].victim].team == 0) RenderTools()->select_sprite(SPRITE_FLAG_BLUE);
+				else RenderTools()->select_sprite(SPRITE_FLAG_RED);
 				
 				float size = 56.0f;
-				gfx_quads_drawTL(x, y-16, size/2, size);
-				gfx_quads_end();					
+				Graphics()->QuadsDrawTL(x, y-16, size/2, size);
+				Graphics()->QuadsEnd();					
 			}
 		}
 		
-		render_tee(ANIMSTATE::get_idle(), &gameclient.clients[killmsgs[r].victim].render_info, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28));
+		RenderTools()->RenderTee(ANIMSTATE::get_idle(), &gameclient.clients[killmsgs[r].victim].render_info, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28));
 		x -= 32.0f;
 		
 		// render weapon
 		x -= 44.0f;
 		if (killmsgs[r].weapon >= 0)
 		{
-			gfx_texture_set(data->images[IMAGE_GAME].id);
-			gfx_quads_begin();
-			select_sprite(data->weapons.id[killmsgs[r].weapon].sprite_body);
-			draw_sprite(x, y+28, 96);
-			gfx_quads_end();
+			Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+			Graphics()->QuadsBegin();
+			RenderTools()->select_sprite(data->weapons.id[killmsgs[r].weapon].sprite_body);
+			RenderTools()->draw_sprite(x, y+28, 96);
+			Graphics()->QuadsEnd();
 		}
 		x -= 52.0f;
 
@@ -100,22 +101,22 @@ void KILLMESSAGES::on_render()
 			{
 				if(killmsgs[r].mode_special&2)
 				{
-					gfx_blend_normal();
-					gfx_texture_set(data->images[IMAGE_GAME].id);
-					gfx_quads_begin();
+					Graphics()->BlendNormal();
+					Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+					Graphics()->QuadsBegin();
 
-					if(gameclient.clients[killmsgs[r].killer].team == 0) select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
-					else select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
+					if(gameclient.clients[killmsgs[r].killer].team == 0) RenderTools()->select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
+					else RenderTools()->select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
 					
 					float size = 56.0f;
-					gfx_quads_drawTL(x-56, y-16, size/2, size);
-					gfx_quads_end();				
+					Graphics()->QuadsDrawTL(x-56, y-16, size/2, size);
+					Graphics()->QuadsEnd();				
 				}
 			}				
 			
 			// render killer tee
 			x -= 24.0f;
-			render_tee(ANIMSTATE::get_idle(), &gameclient.clients[killmsgs[r].killer].render_info, EMOTE_ANGRY, vec2(1,0), vec2(x, y+28));
+			RenderTools()->RenderTee(ANIMSTATE::get_idle(), &gameclient.clients[killmsgs[r].killer].render_info, EMOTE_ANGRY, vec2(1,0), vec2(x, y+28));
 			x -= 32.0f;
 
 			// render killer name
diff --git a/src/game/client/components/mapimages.cpp b/src/game/client/components/mapimages.cpp
index 7f839da0..51194853 100644
--- a/src/game/client/components/mapimages.cpp
+++ b/src/game/client/components/mapimages.cpp
@@ -1,3 +1,4 @@
+#include <engine/client/graphics.h>
 #include <game/client/component.hpp>
 #include <game/mapitems.hpp>
 
@@ -13,7 +14,7 @@ void MAPIMAGES::on_mapload()
 	// unload all textures
 	for(int i = 0; i < count; i++)
 	{
-		gfx_unload_texture(textures[i]);
+		Graphics()->UnloadTexture(textures[i]);
 		textures[i] = -1;
 	}
 	count = 0;
@@ -32,12 +33,12 @@ void MAPIMAGES::on_mapload()
 			char buf[256];
 			char *name = (char *)map_get_data(img->image_name);
 			str_format(buf, sizeof(buf), "mapres/%s.png", name);
-			textures[i] = gfx_load_texture(buf, IMG_AUTO, 0);
+			textures[i] = Graphics()->LoadTexture(buf, IMG_AUTO, 0);
 		}
 		else
 		{
 			void *data = map_get_data(img->image_data);
-			textures[i] = gfx_load_texture_raw(img->width, img->height, IMG_RGBA, data, IMG_RGBA, 0);
+			textures[i] = Graphics()->LoadTextureRaw(img->width, img->height, IMG_RGBA, data, IMG_RGBA, 0);
 			map_unload_data(img->image_data);
 		}
 	}
diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp
index 847350e6..75f91521 100644
--- a/src/game/client/components/maplayers.cpp
+++ b/src/game/client/components/maplayers.cpp
@@ -1,3 +1,5 @@
+#include <engine/client/graphics.h>
+
 #include <game/layers.hpp>
 #include <game/client/gameclient.hpp>
 #include <game/client/component.hpp>
@@ -6,6 +8,7 @@
 #include <game/client/components/camera.hpp>
 #include <game/client/components/mapimages.hpp>
 
+
 #include "maplayers.hpp"
 
 MAPLAYERS::MAPLAYERS(int t)
@@ -14,16 +17,17 @@ MAPLAYERS::MAPLAYERS(int t)
 }
 
 
-static void mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *group)
+void MAPLAYERS::mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *group)
 {
 	float points[4];
-	mapscreen_to_world(center_x, center_y, group->parallax_x/100.0f, group->parallax_y/100.0f,
-		group->offset_x, group->offset_y, gfx_screenaspect(), 1.0f, points);
-	gfx_mapscreen(points[0], points[1], points[2], points[3]);
+	RenderTools()->mapscreen_to_world(center_x, center_y, group->parallax_x/100.0f, group->parallax_y/100.0f,
+		group->offset_x, group->offset_y, Graphics()->ScreenAspect(), 1.0f, points);
+	Graphics()->MapScreen(points[0], points[1], points[2], points[3]);
 }
 
-static void envelope_eval(float time_offset, int env, float *channels)
+void MAPLAYERS::envelope_eval(float time_offset, int env, float *channels, void *user)
 {
+	MAPLAYERS *pThis = (MAPLAYERS *)user;
 	channels[0] = 0;
 	channels[1] = 0;
 	channels[2] = 0;
@@ -45,7 +49,7 @@ static void envelope_eval(float time_offset, int env, float *channels)
 		return;
 	
 	MAPITEM_ENVELOPE *item = (MAPITEM_ENVELOPE *)map_get_item(start+env, 0, 0);
-	render_eval_envelope(points+item->start_point, item->num_points, 4, client_localtime()+time_offset, channels);
+	pThis->RenderTools()->render_eval_envelope(points+item->start_point, item->num_points, 4, client_localtime()+time_offset, channels);
 }
 
 void MAPLAYERS::on_render()
@@ -53,8 +57,8 @@ void MAPLAYERS::on_render()
 	if(client_state() != CLIENTSTATE_ONLINE && client_state() != CLIENTSTATE_DEMOPLAYBACK)
 		return;
 	
-	RECT screen;
-	gfx_getscreen(&screen.x, &screen.y, &screen.w, &screen.h);
+	CUIRect screen;
+	Graphics()->GetScreen(&screen.x, &screen.y, &screen.w, &screen.h);
 	
 	vec2 center = gameclient.camera->center;
 	//float center_x = gameclient.camera->center.x;
@@ -71,14 +75,14 @@ void MAPLAYERS::on_render()
 			// set clipping
 			float points[4];
 			mapscreen_to_group(center.x, center.y, layers_game_group());
-			gfx_getscreen(&points[0], &points[1], &points[2], &points[3]);
+			Graphics()->GetScreen(&points[0], &points[1], &points[2], &points[3]);
 			float x0 = (group->clip_x - points[0]) / (points[2]-points[0]);
 			float y0 = (group->clip_y - points[1]) / (points[3]-points[1]);
 			float x1 = ((group->clip_x+group->clip_w) - points[0]) / (points[2]-points[0]);
 			float y1 = ((group->clip_y+group->clip_h) - points[1]) / (points[3]-points[1]);
 			
-			gfx_clip_enable((int)(x0*gfx_screenwidth()), (int)(y0*gfx_screenheight()),
-				(int)((x1-x0)*gfx_screenwidth()), (int)((y1-y0)*gfx_screenheight()));
+			Graphics()->ClipEnable((int)(x0*Graphics()->ScreenWidth()), (int)(y0*Graphics()->ScreenHeight()),
+				(int)((x1-x0)*Graphics()->ScreenWidth()), (int)((y1-y0)*Graphics()->ScreenHeight()));
 		}		
 		
 		mapscreen_to_group(center.x, center.y, group);
@@ -121,43 +125,43 @@ void MAPLAYERS::on_render()
 				{
 					MAPITEM_LAYER_TILEMAP *tmap = (MAPITEM_LAYER_TILEMAP *)layer;
 					if(tmap->image == -1)
-						gfx_texture_set(-1);
+						Graphics()->TextureSet(-1);
 					else
-						gfx_texture_set(gameclient.mapimages->get(tmap->image));
+						Graphics()->TextureSet(gameclient.mapimages->get(tmap->image));
 						
 					TILE *tiles = (TILE *)map_get_data(tmap->data);
-					gfx_blend_none();
-					render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE);
-					gfx_blend_normal();
-					render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT);
+					Graphics()->BlendNone();
+					RenderTools()->render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE);
+					Graphics()->BlendNormal();
+					RenderTools()->render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT);
 				}
 				else if(layer->type == LAYERTYPE_QUADS)
 				{
 					MAPITEM_LAYER_QUADS *qlayer = (MAPITEM_LAYER_QUADS *)layer;
 					if(qlayer->image == -1)
-						gfx_texture_set(-1);
+						Graphics()->TextureSet(-1);
 					else
-						gfx_texture_set(gameclient.mapimages->get(qlayer->image));
+						Graphics()->TextureSet(gameclient.mapimages->get(qlayer->image));
 
 					QUAD *quads = (QUAD *)map_get_data_swapped(qlayer->data);
 					
-					gfx_blend_none();
-					render_quads(quads, qlayer->num_quads, envelope_eval, LAYERRENDERFLAG_OPAQUE);
-					gfx_blend_normal();
-					render_quads(quads, qlayer->num_quads, envelope_eval, LAYERRENDERFLAG_TRANSPARENT);
+					Graphics()->BlendNone();
+					RenderTools()->render_quads(quads, qlayer->num_quads, LAYERRENDERFLAG_OPAQUE, envelope_eval, this);
+					Graphics()->BlendNormal();
+					RenderTools()->render_quads(quads, qlayer->num_quads, LAYERRENDERFLAG_TRANSPARENT, envelope_eval, this);
 				}
 				
 				//layershot_end();	
 			}
 		}
 		if(!config.gfx_noclip)
-			gfx_clip_disable();
+			Graphics()->ClipDisable();
 	}
 	
 	if(!config.gfx_noclip)
-		gfx_clip_disable();
+		Graphics()->ClipDisable();
 	
 	// reset the screen like it was before
-	gfx_mapscreen(screen.x, screen.y, screen.w, screen.h);
+	Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);
 }
 
diff --git a/src/game/client/components/maplayers.hpp b/src/game/client/components/maplayers.hpp
index c2919f08..c8b154b2 100644
--- a/src/game/client/components/maplayers.hpp
+++ b/src/game/client/components/maplayers.hpp
@@ -3,6 +3,9 @@
 class MAPLAYERS : public COMPONENT
 {	
 	int type;
+
+	void mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *group);
+	static void envelope_eval(float time_offset, int env, float *channels, void *user);
 public:
 	enum
 	{
diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp
index 168c514d..5f1bbf42 100644
--- a/src/game/client/components/menus.cpp
+++ b/src/game/client/components/menus.cpp
@@ -12,6 +12,7 @@
 #include "skins.hpp"
 
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 
 #include <game/version.hpp>
 #include <game/generated/g_protocol.hpp>
@@ -94,356 +95,366 @@ MENUS::MENUS()
 	last_input = time_get();
 }
 
-vec4 MENUS::button_color_mul(const void *id)
+vec4 MENUS::button_color_mul(const void *pID)
 {
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == pID)
 		return vec4(1,1,1,0.5f);
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == pID)
 		return vec4(1,1,1,1.5f);
 	return vec4(1,1,1,1);
 }
 
-void MENUS::ui_draw_browse_icon(int what, const RECT *r)
+int MENUS::DoButton_BrowseIcon(int What, const CUIRect *pRect)
 {
-	gfx_texture_set(data->images[IMAGE_BROWSEICONS].id);
-	gfx_quads_begin();
-	select_sprite(what);
-	gfx_quads_drawTL(r->x,r->y,r->w,r->h);
-	gfx_quads_end();
+	Graphics()->TextureSet(data->images[IMAGE_BROWSEICONS].id);
+	
+	Graphics()->QuadsBegin();
+	RenderTools()->select_sprite(What);
+	Graphics()->QuadsDrawTL(pRect->x, pRect->y, pRect->w, pRect->h);
+	Graphics()->QuadsEnd();
+	
+	return 0;
 }
 
 
-void MENUS::ui_draw_menu_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int MENUS::DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
-	ui_draw_rect(r, vec4(1,1,1,0.5f)*button_color_mul(id), CORNER_ALL, 5.0f);
-	ui_do_label(r, text, r->h*fontmod_height, 0);
+	RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f)*button_color_mul(pID), CUI::CORNER_ALL, 5.0f);
+	UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, 0);
+	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-void MENUS::ui_draw_keyselect_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int MENUS::DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
-	ui_draw_rect(r, vec4(1,1,1,0.5f)*button_color_mul(id), CORNER_ALL, 5.0f);
-	ui_do_label(r, text, r->h*fontmod_height, 0);
+	RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f)*button_color_mul(pID), CUI::CORNER_ALL, 5.0f);
+	UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, 0);
+	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-void MENUS::ui_draw_menu_tab_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int MENUS::DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners)
 {
-	int corners = CORNER_T;
-	vec4 colormod(1,1,1,1);
-	if(extra)
-		corners = *(int *)extra;
+	vec4 ColorMod(1,1,1,1);
 	
-	if(checked)
-		ui_draw_rect(r, color_tabbar_active, corners, 10.0f);
+	if(Checked)
+		RenderTools()->DrawUIRect(pRect, color_tabbar_active, Corners, 10.0f);
 	else
-		ui_draw_rect(r, color_tabbar_inactive, corners, 10.0f);
-	ui_do_label(r, text, r->h*fontmod_height, 0);
+		RenderTools()->DrawUIRect(pRect, color_tabbar_inactive, Corners, 10.0f);
+	UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, 0);
+	
+	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
 
-void MENUS::ui_draw_settings_tab_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int MENUS::DoButton_SettingsTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
-	if(checked)
-		ui_draw_rect(r, color_tabbar_active, CORNER_R, 10.0f);
+	if(Checked)
+		RenderTools()->DrawUIRect(pRect, color_tabbar_active, CUI::CORNER_R, 10.0f);
 	else
-		ui_draw_rect(r, color_tabbar_inactive, CORNER_R, 10.0f);
-	ui_do_label(r, text, r->h*fontmod_height, 0);
+		RenderTools()->DrawUIRect(pRect, color_tabbar_inactive, CUI::CORNER_R, 10.0f);
+	UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, 0);
+	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-void MENUS::ui_draw_grid_header(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int MENUS::DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
+//void MENUS::ui_draw_grid_header(const void *id, const char *text, int checked, const CUIRect *r, const void *extra)
 {
-	if(checked)
-		ui_draw_rect(r, vec4(1,1,1,0.5f), CORNER_T, 5.0f);
-	RECT t;
-	ui_vsplit_l(r, 5.0f, 0, &t);
-	ui_do_label(&t, text, r->h*fontmod_height, -1);
+	if(Checked)
+		RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f), CUI::CORNER_T, 5.0f);
+	CUIRect t;
+	pRect->VSplitLeft(5.0f, 0, &t);
+	UI()->DoLabel(&t, pText, pRect->h*fontmod_height, -1);
+	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-void MENUS::ui_draw_list_row(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int MENUS::DoButton_ListRow(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
-	if(checked)
+	if(Checked)
 	{
-		RECT sr = *r;
-		ui_margin(&sr, 1.5f, &sr);
-		ui_draw_rect(&sr, vec4(1,1,1,0.5f), CORNER_ALL, 4.0f);
+		CUIRect sr = *pRect;
+		sr.Margin(1.5f, &sr);
+		RenderTools()->DrawUIRect(&sr, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f);
 	}
-	ui_do_label(r, text, r->h*fontmod_height, -1);
+	UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, -1);
+	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-void MENUS::ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const RECT *r)
+int MENUS::DoButton_CheckBox_Common(const void *pID, const char *pText, const char *pBoxText, const CUIRect *pRect)
+//void MENUS::ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const CUIRect *r, const void *extra)
 {
-	RECT c = *r;
-	RECT t = *r;
+	CUIRect c = *pRect;
+	CUIRect t = *pRect;
 	c.w = c.h;
 	t.x += c.w;
 	t.w -= c.w;
-	ui_vsplit_l(&t, 5.0f, 0, &t);
+	t.VSplitLeft(5.0f, 0, &t);
 	
-	ui_margin(&c, 2.0f, &c);
-	ui_draw_rect(&c, vec4(1,1,1,0.25f)*button_color_mul(id), CORNER_ALL, 3.0f);
+	c.Margin(2.0f, &c);
+	RenderTools()->DrawUIRect(&c, vec4(1,1,1,0.25f)*button_color_mul(pID), CUI::CORNER_ALL, 3.0f);
 	c.y += 2;
-	ui_do_label(&c, boxtext, r->h*fontmod_height*0.6f, 0);
-	ui_do_label(&t, text, r->h*fontmod_height*0.8f, -1);
+	UI()->DoLabel(&c, pBoxText, pRect->h*fontmod_height*0.6f, 0);
+	UI()->DoLabel(&t, pText, pRect->h*fontmod_height*0.8f, -1);
+	return UI()->DoButtonLogic(pID, pText, 0, pRect);
 }
 
-void MENUS::ui_draw_checkbox(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int MENUS::DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
-	ui_draw_checkbox_common(id, text, checked?"X":"", r);
+	return DoButton_CheckBox_Common(pID, pText, Checked?"X":"", pRect);
 }
 
 
-void MENUS::ui_draw_checkbox_number(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int MENUS::DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
 	char buf[16];
-	str_format(buf, sizeof(buf), "%d", checked);
-	ui_draw_checkbox_common(id, text, buf, r);
+	str_format(buf, sizeof(buf), "%d", Checked);
+	return DoButton_CheckBox_Common(pID, pText, buf, pRect);
 }
 
-int MENUS::ui_do_edit_box(void *id, const RECT *rect, char *str, unsigned str_size, float font_size, bool hidden)
+int MENUS::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden)
 {
-    int inside = ui_mouse_inside(rect);
-	int r = 0;
-	static int at_index = 0;
+    int Inside = UI()->MouseInside(pRect);
+	int ReturnValue = 0;
+	static int AtIndex = 0;
 
-	if(ui_last_active_item() == id)
+	if(UI()->LastActiveItem() == pID)
 	{
-		int len = strlen(str);
+		int Len = strlen(pStr);
 			
-		if (inside && ui_mouse_button(0))
+		if(Inside && UI()->MouseButton(0))
 		{
-			int mx_rel = (int)(ui_mouse_x() - rect->x);
+			int mx_rel = (int)(UI()->MouseX() - pRect->x);
 
-			for (int i = 1; i <= len; i++)
+			for (int i = 1; i <= Len; i++)
 			{
-				if (gfx_text_width(0, font_size, str, i) + 10 > mx_rel)
+				if (gfx_text_width(0, FontSize, pStr, i) + 10 > mx_rel)
 				{
-					at_index = i - 1;
+					AtIndex = i - 1;
 					break;
 				}
 
-				if (i == len)
-					at_index = len;
+				if (i == Len)
+					AtIndex = Len;
 			}
 		}
 
 		for(int i = 0; i < num_inputevents; i++)
 		{
-			len = strlen(str);
-			LINEINPUT::manipulate(inputevents[i], str, str_size, &len, &at_index);
+			Len = strlen(pStr);
+			LINEINPUT::manipulate(inputevents[i], pStr, StrSize, &Len, &AtIndex);
 		}
 	}
 
-	bool just_got_active = false;
+	bool JustGotActive = false;
 	
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == pID)
 	{
-		if(!ui_mouse_button(0))
-			ui_set_active_item(0);
+		if(!UI()->MouseButton(0))
+			UI()->SetActiveItem(0);
 	}
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == pID)
 	{
-		if(ui_mouse_button(0))
+		if(UI()->MouseButton(0))
 		{
-			if (ui_last_active_item() != id)
-				just_got_active = true;
-			ui_set_active_item(id);
+			if (UI()->LastActiveItem() != pID)
+				JustGotActive = true;
+			UI()->SetActiveItem(pID);
 		}
 	}
 	
-	if(inside)
-		ui_set_hot_item(id);
+	if(Inside)
+		UI()->SetHotItem(pID);
 
-	RECT textbox = *rect;
-	ui_draw_rect(&textbox, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f);
-	ui_vmargin(&textbox, 5.0f, &textbox);
+	CUIRect Textbox = *pRect;
+	RenderTools()->DrawUIRect(&Textbox, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 5.0f);
+	Textbox.VMargin(5.0f, &Textbox);
 	
-	const char *display_str = str;
-	char stars[128];
+	const char *pDisplayStr = pStr;
+	char aStars[128];
 	
-	if(hidden)
+	if(Hidden)
 	{
-		unsigned s = strlen(str);
-		if(s >= sizeof(stars))
-			s = sizeof(stars)-1;
-		memset(stars, '*', s);
-		stars[s] = 0;
-		display_str = stars;
+		unsigned s = strlen(pStr);
+		if(s >= sizeof(aStars))
+			s = sizeof(aStars)-1;
+		memset(aStars, '*', s);
+		aStars[s] = 0;
+		pDisplayStr = aStars;
 	}
 
-	ui_do_label(&textbox, display_str, font_size, -1);
+	UI()->DoLabel(&Textbox, pDisplayStr, FontSize, -1);
 	
-	if (ui_last_active_item() == id && !just_got_active)
+	if (UI()->LastActiveItem() == pID && !JustGotActive)
 	{
-		float w = gfx_text_width(0, font_size, display_str, at_index);
-		textbox.x += w*ui_scale();
-		ui_do_label(&textbox, "_", font_size, -1);
+		float w = gfx_text_width(0, FontSize, pDisplayStr, AtIndex);
+		Textbox.x += w*UI()->Scale();
+		UI()->DoLabel(&Textbox, "_", FontSize, -1);
 	}
 
-	return r;
+	return ReturnValue;
 }
 
-float MENUS::ui_do_scrollbar_v(const void *id, const RECT *rect, float current)
+float MENUS::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current)
 {
-	RECT handle;
-	static float offset_y;
-	ui_hsplit_t(rect, 33, &handle, 0);
+	CUIRect Handle;
+	static float OffsetY;
+	pRect->HSplitTop(33, &Handle, 0);
 
-	handle.y += (rect->h-handle.h)*current;
+	Handle.y += (pRect->h-Handle.h)*Current;
 
 	/* logic */
-    float ret = current;
-    int inside = ui_mouse_inside(&handle);
+    float ReturnValue = Current;
+    int Inside = UI()->MouseInside(&Handle);
 
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == pID)
 	{
-		if(!ui_mouse_button(0))
-			ui_set_active_item(0);
+		if(!UI()->MouseButton(0))
+			UI()->SetActiveItem(0);
 		
-		float min = rect->y;
-		float max = rect->h-handle.h;
-		float cur = ui_mouse_y()-offset_y;
-		ret = (cur-min)/max;
-		if(ret < 0.0f) ret = 0.0f;
-		if(ret > 1.0f) ret = 1.0f;
+		float min = pRect->y;
+		float max = pRect->h-Handle.h;
+		float cur = UI()->MouseY()-OffsetY;
+		ReturnValue = (cur-min)/max;
+		if(ReturnValue < 0.0f) ReturnValue = 0.0f;
+		if(ReturnValue > 1.0f) ReturnValue = 1.0f;
 	}
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == pID)
 	{
-		if(ui_mouse_button(0))
+		if(UI()->MouseButton(0))
 		{
-			ui_set_active_item(id);
-			offset_y = ui_mouse_y()-handle.y;
+			UI()->SetActiveItem(pID);
+			OffsetY = UI()->MouseY()-Handle.y;
 		}
 	}
 	
-	if(inside)
-		ui_set_hot_item(id);
+	if(Inside)
+		UI()->SetHotItem(pID);
 
 	// render
-	RECT rail;
-	ui_vmargin(rect, 5.0f, &rail);
-	ui_draw_rect(&rail, vec4(1,1,1,0.25f), 0, 0.0f);
-
-	RECT slider = handle;
-	slider.w = rail.x-slider.x;
-	ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_L, 2.5f);
-	slider.x = rail.x+rail.w;
-	ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_R, 2.5f);
-
-	slider = handle;
-	ui_margin(&slider, 5.0f, &slider);
-	ui_draw_rect(&slider, vec4(1,1,1,0.25f)*button_color_mul(id), CORNER_ALL, 2.5f);
+	CUIRect Rail;
+	pRect->VMargin(5.0f, &Rail);
+	RenderTools()->DrawUIRect(&Rail, vec4(1,1,1,0.25f), 0, 0.0f);
+
+	CUIRect Slider = Handle;
+	Slider.w = Rail.x-Slider.x;
+	RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f), CUI::CORNER_L, 2.5f);
+	Slider.x = Rail.x+Rail.w;
+	RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f), CUI::CORNER_R, 2.5f);
+
+	Slider = Handle;
+	Slider.Margin(5.0f, &Slider);
+	RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*button_color_mul(pID), CUI::CORNER_ALL, 2.5f);
 	
-    return ret;
+    return ReturnValue;
 }
 
 
 
-float MENUS::ui_do_scrollbar_h(const void *id, const RECT *rect, float current)
+float MENUS::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current)
 {
-	RECT handle;
-	static float offset_x;
-	ui_vsplit_l(rect, 33, &handle, 0);
+	CUIRect Handle;
+	static float OffsetX;
+	pRect->VSplitLeft(33, &Handle, 0);
 
-	handle.x += (rect->w-handle.w)*current;
+	Handle.x += (pRect->w-Handle.w)*Current;
 
 	/* logic */
-    float ret = current;
-    int inside = ui_mouse_inside(&handle);
+    float ReturnValue = Current;
+    int Inside = UI()->MouseInside(&Handle);
 
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == pID)
 	{
-		if(!ui_mouse_button(0))
-			ui_set_active_item(0);
+		if(!UI()->MouseButton(0))
+			UI()->SetActiveItem(0);
 		
-		float min = rect->x;
-		float max = rect->w-handle.w;
-		float cur = ui_mouse_x()-offset_x;
-		ret = (cur-min)/max;
-		if(ret < 0.0f) ret = 0.0f;
-		if(ret > 1.0f) ret = 1.0f;
+		float min = pRect->x;
+		float max = pRect->w-Handle.w;
+		float cur = UI()->MouseX()-OffsetX;
+		ReturnValue = (cur-min)/max;
+		if(ReturnValue < 0.0f) ReturnValue = 0.0f;
+		if(ReturnValue > 1.0f) ReturnValue = 1.0f;
 	}
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == pID)
 	{
-		if(ui_mouse_button(0))
+		if(UI()->MouseButton(0))
 		{
-			ui_set_active_item(id);
-			offset_x = ui_mouse_x()-handle.x;
+			UI()->SetActiveItem(pID);
+			OffsetX = UI()->MouseX()-Handle.x;
 		}
 	}
 	
-	if(inside)
-		ui_set_hot_item(id);
+	if(Inside)
+		UI()->SetHotItem(pID);
 
 	// render
-	RECT rail;
-	ui_hmargin(rect, 5.0f, &rail);
-	ui_draw_rect(&rail, vec4(1,1,1,0.25f), 0, 0.0f);
-
-	RECT slider = handle;
-	slider.h = rail.y-slider.y;
-	ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_T, 2.5f);
-	slider.y = rail.y+rail.h;
-	ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_B, 2.5f);
-
-	slider = handle;
-	ui_margin(&slider, 5.0f, &slider);
-	ui_draw_rect(&slider, vec4(1,1,1,0.25f)*button_color_mul(id), CORNER_ALL, 2.5f);
+	CUIRect Rail;
+	pRect->HMargin(5.0f, &Rail);
+	RenderTools()->DrawUIRect(&Rail, vec4(1,1,1,0.25f), 0, 0.0f);
+
+	CUIRect Slider = Handle;
+	Slider.h = Rail.y-Slider.y;
+	RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f), CUI::CORNER_T, 2.5f);
+	Slider.y = Rail.y+Rail.h;
+	RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f), CUI::CORNER_B, 2.5f);
+
+	Slider = Handle;
+	Slider.Margin(5.0f, &Slider);
+	RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*button_color_mul(pID), CUI::CORNER_ALL, 2.5f);
 	
-    return ret;
+    return ReturnValue;
 }
 
-int MENUS::ui_do_key_reader(void *id, const RECT *rect, int key)
+int MENUS::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
 {
 	// process
-	static void *grabbed_id = 0;
-	static bool mouse_released = true;
-	int inside = ui_mouse_inside(rect);
-	int new_key = key;
+	static void *pGrabbedID = 0;
+	static bool MouseReleased = true;
+	int Inside = UI()->MouseInside(pRect);
+	int NewKey = Key;
 	
-	if(!ui_mouse_button(0) && grabbed_id == id)
-		mouse_released = true;
+	if(!UI()->MouseButton(0) && pGrabbedID == pID)
+		MouseReleased = true;
 
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == pID)
 	{
 		if(binder.got_key)
 		{
-			new_key = binder.key.key;
+			NewKey = binder.key.key;
 			binder.got_key = false;
-			ui_set_active_item(0);
-			mouse_released = false;
-			grabbed_id = id;
+			UI()->SetActiveItem(0);
+			MouseReleased = false;
+			pGrabbedID = pID;
 		}
 	}
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == pID)
 	{
-		if(ui_mouse_button(0) && mouse_released)
+		if(UI()->MouseButton(0) && MouseReleased)
 		{
 			binder.take_key = true;
 			binder.got_key = false;
-			ui_set_active_item(id);
+			UI()->SetActiveItem(pID);
 		}
 	}
 	
-	if(inside)
-		ui_set_hot_item(id);
+	if(Inside)
+		UI()->SetHotItem(pID);
 
 	// draw
-	if (ui_active_item() == id)
-		ui_draw_keyselect_button(id, "???", 0, rect, 0);
+	if (UI()->ActiveItem() == pID)
+		DoButton_KeySelect(pID, "???", 0, pRect);
 	else
 	{
-		if(key == 0)
-			ui_draw_keyselect_button(id, "", 0, rect, 0);
+		if(Key == 0)
+			DoButton_KeySelect(pID, "", 0, pRect);
 		else
-			ui_draw_keyselect_button(id, inp_key_name(key), 0, rect, 0);
+			DoButton_KeySelect(pID, inp_key_name(Key), 0, pRect);
 	}
-	return new_key;
+	return NewKey;
 }
 
 
-int MENUS::render_menubar(RECT r)
+int MENUS::render_menubar(CUIRect r)
 {
-	RECT box = r;
-	RECT button;
+	CUIRect box = r;
+	CUIRect button;
 	
 	int active_page = config.ui_page;
 	int new_page = -1;
@@ -456,46 +467,43 @@ int MENUS::render_menubar(RECT r)
 		/* offline menus */
 		if(0) // this is not done yet
 		{
-			ui_vsplit_l(&box, 90.0f, &button, &box);
+			box.VSplitLeft(90.0f, &button, &box);
 			static int news_button=0;
-			if (ui_do_button(&news_button, localize("News"), active_page==PAGE_NEWS, &button, ui_draw_menu_tab_button, 0))
+			if (DoButton_MenuTab(&news_button, localize("News"), active_page==PAGE_NEWS, &button, 0))
 				new_page = PAGE_NEWS;
-			ui_vsplit_l(&box, 30.0f, 0, &box); 
+			box.VSplitLeft(30.0f, 0, &box); 
 		}
 
-		ui_vsplit_l(&box, 100.0f, &button, &box);
+		box.VSplitLeft(100.0f, &button, &box);
 		static int internet_button=0;
-		int corners = CORNER_TL;
-		if (ui_do_button(&internet_button, localize("Internet"), active_page==PAGE_INTERNET, &button, ui_draw_menu_tab_button, &corners))
+		if(DoButton_MenuTab(&internet_button, localize("Internet"), active_page==PAGE_INTERNET, &button, CUI::CORNER_TL))
 		{
 			client_serverbrowse_refresh(BROWSETYPE_INTERNET);
 			new_page = PAGE_INTERNET;
 		}
 
-		//ui_vsplit_l(&box, 4.0f, 0, &box);
-		ui_vsplit_l(&box, 80.0f, &button, &box);
+		//box.VSplitLeft(4.0f, 0, &box);
+		box.VSplitLeft(80.0f, &button, &box);
 		static int lan_button=0;
-		corners = 0;
-		if (ui_do_button(&lan_button, localize("LAN"), active_page==PAGE_LAN, &button, ui_draw_menu_tab_button, &corners))
+		if(DoButton_MenuTab(&lan_button, localize("LAN"), active_page==PAGE_LAN, &button, 0))
 		{
 			client_serverbrowse_refresh(BROWSETYPE_LAN);
 			new_page = PAGE_LAN;
 		}
 
-		//ui_vsplit_l(&box, 4.0f, 0, &box);
-		ui_vsplit_l(&box, 110.0f, &button, &box);
+		//box.VSplitLeft(4.0f, 0, &box);
+		box.VSplitLeft(110.0f, &button, &box);
 		static int favorites_button=0;
-		corners = CORNER_TR;
-		if (ui_do_button(&favorites_button, localize("Favorites"), active_page==PAGE_FAVORITES, &button, ui_draw_menu_tab_button, &corners))
+		if(DoButton_MenuTab(&favorites_button, localize("Favorites"), active_page==PAGE_FAVORITES, &button, CUI::CORNER_TR))
 		{
 			client_serverbrowse_refresh(BROWSETYPE_FAVORITES);
 			new_page  = PAGE_FAVORITES;
 		}
 		
-		ui_vsplit_l(&box, 4.0f*5, 0, &box);
-		ui_vsplit_l(&box, 100.0f, &button, &box);
+		box.VSplitLeft(4.0f*5, 0, &box);
+		box.VSplitLeft(100.0f, &button, &box);
 		static int demos_button=0;
-		if (ui_do_button(&demos_button, localize("Demos"), active_page==PAGE_DEMOS, &button, ui_draw_menu_tab_button, 0))
+		if(DoButton_MenuTab(&demos_button, localize("Demos"), active_page==PAGE_DEMOS, &button, 0))
 		{
 			demolist_populate();
 			new_page  = PAGE_DEMOS;
@@ -504,44 +512,44 @@ int MENUS::render_menubar(RECT r)
 	else
 	{
 		/* online menus */
-		ui_vsplit_l(&box, 90.0f, &button, &box);
+		box.VSplitLeft(90.0f, &button, &box);
 		static int game_button=0;
-		if (ui_do_button(&game_button, localize("Game"), active_page==PAGE_GAME, &button, ui_draw_menu_tab_button, 0))
+		if(DoButton_MenuTab(&game_button, localize("Game"), active_page==PAGE_GAME, &button, 0))
 			new_page = PAGE_GAME;
 
-		ui_vsplit_l(&box, 4.0f, 0, &box);
-		ui_vsplit_l(&box, 140.0f, &button, &box);
+		box.VSplitLeft(4.0f, 0, &box);
+		box.VSplitLeft(140.0f, &button, &box);
 		static int server_info_button=0;
-		if (ui_do_button(&server_info_button, localize("Server info"), active_page==PAGE_SERVER_INFO, &button, ui_draw_menu_tab_button, 0))
+		if(DoButton_MenuTab(&server_info_button, localize("Server info"), active_page==PAGE_SERVER_INFO, &button, 0))
 			new_page = PAGE_SERVER_INFO;
 
-		ui_vsplit_l(&box, 4.0f, 0, &box);
-		ui_vsplit_l(&box, 140.0f, &button, &box);
+		box.VSplitLeft(4.0f, 0, &box);
+		box.VSplitLeft(140.0f, &button, &box);
 		static int callvote_button=0;
-		if (ui_do_button(&callvote_button, localize("Call vote"), active_page==PAGE_CALLVOTE, &button, ui_draw_menu_tab_button, 0))
+		if(DoButton_MenuTab(&callvote_button, localize("Call vote"), active_page==PAGE_CALLVOTE, &button, 0))
 			new_page = PAGE_CALLVOTE;
 			
-		ui_vsplit_l(&box, 30.0f, 0, &box);
+		box.VSplitLeft(30.0f, 0, &box);
 	}
 		
 	/*
-	ui_vsplit_r(&box, 110.0f, &box, &button);
+	box.VSplitRight(110.0f, &box, &button);
 	static int system_button=0;
-	if (ui_do_button(&system_button, "System", config.ui_page==PAGE_SYSTEM, &button, ui_draw_menu_tab_button, 0))
+	if (UI()->DoButton(&system_button, "System", config.ui_page==PAGE_SYSTEM, &button))
 		config.ui_page = PAGE_SYSTEM;
 		
-	ui_vsplit_r(&box, 30.0f, &box, 0);
+	box.VSplitRight(30.0f, &box, 0);
 	*/
 	
-	ui_vsplit_r(&box, 90.0f, &box, &button);
+	box.VSplitRight(90.0f, &box, &button);
 	static int quit_button=0;
-	if (ui_do_button(&quit_button, localize("Quit"), 0, &button, ui_draw_menu_tab_button, 0))
+	if(DoButton_MenuTab(&quit_button, localize("Quit"), 0, &button, 0))
 		popup = POPUP_QUIT;
 
-	ui_vsplit_r(&box, 10.0f, &box, &button);
-	ui_vsplit_r(&box, 130.0f, &box, &button);
+	box.VSplitRight(10.0f, &box, &button);
+	box.VSplitRight(130.0f, &box, &button);
 	static int settings_button=0;
-	if (ui_do_button(&settings_button, localize("Settings"), active_page==PAGE_SETTINGS, &button, ui_draw_menu_tab_button, 0))
+	if(DoButton_MenuTab(&settings_button, localize("Settings"), active_page==PAGE_SETTINGS, &button, 0))
 		new_page = PAGE_SETTINGS;
 	
 	if(new_page != -1)
@@ -570,8 +578,8 @@ void MENUS::render_loading(float percent)
 	vec3 rgb = hsl_to_rgb(vec3(config.ui_color_hue/255.0f, config.ui_color_sat/255.0f, config.ui_color_lht/255.0f));
 	gui_color = vec4(rgb.r, rgb.g, rgb.b, config.ui_color_alpha/255.0f);
 	
-    RECT screen = *ui_screen();
-	gfx_mapscreen(screen.x, screen.y, screen.w, screen.h);
+    CUIRect screen = *UI()->Screen();
+	Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);
 	
 	render_background();
 
@@ -582,37 +590,37 @@ void MENUS::render_loading(float percent)
 	float x = screen.w/2-w/2;
 	float y = screen.h/2-h/2;
 
-	gfx_blend_normal();
+	Graphics()->BlendNormal();
 
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.50f);
-	draw_round_rect(x, y, w, h, 40.0f);
-	gfx_quads_end();
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(0,0,0,0.50f);
+	RenderTools()->draw_round_rect(x, y, w, h, 40.0f);
+	Graphics()->QuadsEnd();
 
 
 	const char *caption = localize("Loading");
 
 	tw = gfx_text_width(0, 48.0f, caption, -1);
-	RECT r;
+	CUIRect r;
 	r.x = x;
 	r.y = y+20;
 	r.w = w;
 	r.h = h;
-	ui_do_label(&r, caption, 48.0f, 0, -1);
+	UI()->DoLabel(&r, caption, 48.0f, 0, -1);
 
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(1,1,1,0.75f);
-	draw_round_rect(x+40, y+h-75, (w-80)*percent, 25, 5.0f);
-	gfx_quads_end();
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(1,1,1,0.75f);
+	RenderTools()->draw_round_rect(x+40, y+h-75, (w-80)*percent, 25, 5.0f);
+	Graphics()->QuadsEnd();
 
 	gfx_swap();
 }
 
-void MENUS::render_news(RECT main_view)
+void MENUS::render_news(CUIRect main_view)
 {
-	ui_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f);
+	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
 }
 
 void MENUS::on_init()
@@ -677,8 +685,8 @@ void MENUS::popup_message(const char *topic, const char *body, const char *butto
 
 int MENUS::render()
 {
-    RECT screen = *ui_screen();
-	gfx_mapscreen(screen.x, screen.y, screen.w, screen.h);
+    CUIRect screen = *UI()->Screen();
+	Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);
 
 	static bool first = true;
 	if(first)
@@ -702,17 +710,17 @@ int MENUS::render()
 		color_tabbar_active = color_tabbar_active_outgame;
 	}
 	
-	RECT tab_bar;
-	RECT main_view;
+	CUIRect tab_bar;
+	CUIRect main_view;
 
 	// some margin around the screen
-	ui_margin(&screen, 10.0f, &screen);
+	screen.Margin(10.0f, &screen);
 	
 	if(popup == POPUP_NONE)
 	{
 		// do tab bar
-		ui_hsplit_t(&screen, 24.0f, &tab_bar, &main_view);
-		ui_vmargin(&tab_bar, 20.0f, &tab_bar);
+		screen.HSplitTop(24.0f, &tab_bar, &main_view);
+		tab_bar.VMargin(20.0f, &tab_bar);
 		render_menubar(tab_bar);
 		
 		// news is not implemented yet
@@ -750,8 +758,8 @@ int MENUS::render()
 	else
 	{
 		// make sure that other windows doesn't do anything funnay!
-		//ui_set_hot_item(0);
-		//ui_set_active_item(0);
+		//UI()->SetHotItem(0);
+		//UI()->SetActiveItem(0);
 		char buf[128];
 		const char *title = "";
 		const char *extra_text = "";
@@ -809,109 +817,109 @@ int MENUS::render()
 			extra_align = -1;
 		}
 		
-		RECT box, part;
+		CUIRect box, part;
 		box = screen;
-		ui_vmargin(&box, 150.0f, &box);
-		ui_hmargin(&box, 150.0f, &box);
+		box.VMargin(150.0f, &box);
+		box.HMargin(150.0f, &box);
 		
 		// render the box
-		ui_draw_rect(&box, vec4(0,0,0,0.5f), CORNER_ALL, 15.0f);
+		RenderTools()->DrawUIRect(&box, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 15.0f);
 		 
-		ui_hsplit_t(&box, 20.f, &part, &box);
-		ui_hsplit_t(&box, 24.f, &part, &box);
-		ui_do_label(&part, title, 24.f, 0);
-		ui_hsplit_t(&box, 20.f, &part, &box);
-		ui_hsplit_t(&box, 24.f, &part, &box);
-		ui_vmargin(&part, 20.f, &part);
+		box.HSplitTop(20.f, &part, &box);
+		box.HSplitTop(24.f, &part, &box);
+		UI()->DoLabel(&part, title, 24.f, 0);
+		box.HSplitTop(20.f, &part, &box);
+		box.HSplitTop(24.f, &part, &box);
+		part.VMargin(20.f, &part);
 		
 		if(extra_align == -1)
-			ui_do_label(&part, extra_text, 20.f, -1, (int)part.w);
+			UI()->DoLabel(&part, extra_text, 20.f, -1, (int)part.w);
 		else
-			ui_do_label(&part, extra_text, 20.f, 0, -1);
+			UI()->DoLabel(&part, extra_text, 20.f, 0, -1);
 
 		if(popup == POPUP_QUIT)
 		{
-			RECT yes, no;
-			ui_hsplit_b(&box, 20.f, &box, &part);
-			ui_hsplit_b(&box, 24.f, &box, &part);
-			ui_vmargin(&part, 80.0f, &part);
+			CUIRect yes, no;
+			box.HSplitBottom(20.f, &box, &part);
+			box.HSplitBottom(24.f, &box, &part);
+			part.VMargin(80.0f, &part);
 			
-			ui_vsplit_mid(&part, &no, &yes);
+			part.VSplitMid(&no, &yes);
 			
-			ui_vmargin(&yes, 20.0f, &yes);
-			ui_vmargin(&no, 20.0f, &no);
+			yes.VMargin(20.0f, &yes);
+			no.VMargin(20.0f, &no);
 
 			static int button_abort = 0;
-			if(ui_do_button(&button_abort, localize("No"), 0, &no, ui_draw_menu_button, 0) || escape_pressed)
+			if(DoButton_Menu(&button_abort, localize("No"), 0, &no) || escape_pressed)
 				popup = POPUP_NONE;
 
 			static int button_tryagain = 0;
-			if(ui_do_button(&button_tryagain, localize("Yes"), 0, &yes, ui_draw_menu_button, 0) || enter_pressed)
+			if(DoButton_Menu(&button_tryagain, localize("Yes"), 0, &yes) || enter_pressed)
 				client_quit();
 		}
 		else if(popup == POPUP_PASSWORD)
 		{
-			RECT label, textbox, tryagain, abort;
+			CUIRect label, textbox, tryagain, abort;
 			
-			ui_hsplit_b(&box, 20.f, &box, &part);
-			ui_hsplit_b(&box, 24.f, &box, &part);
-			ui_vmargin(&part, 80.0f, &part);
+			box.HSplitBottom(20.f, &box, &part);
+			box.HSplitBottom(24.f, &box, &part);
+			part.VMargin(80.0f, &part);
 			
-			ui_vsplit_mid(&part, &abort, &tryagain);
+			part.VSplitMid(&abort, &tryagain);
 			
-			ui_vmargin(&tryagain, 20.0f, &tryagain);
-			ui_vmargin(&abort, 20.0f, &abort);
+			tryagain.VMargin(20.0f, &tryagain);
+			abort.VMargin(20.0f, &abort);
 			
 			static int button_abort = 0;
-			if(ui_do_button(&button_abort, localize("Abort"), 0, &abort, ui_draw_menu_button, 0) || escape_pressed)
+			if(DoButton_Menu(&button_abort, localize("Abort"), 0, &abort) || escape_pressed)
 				popup = POPUP_NONE;
 
 			static int button_tryagain = 0;
-			if(ui_do_button(&button_tryagain, localize("Try again"), 0, &tryagain, ui_draw_menu_button, 0) || enter_pressed)
+			if(DoButton_Menu(&button_tryagain, localize("Try again"), 0, &tryagain) || enter_pressed)
 			{
 				client_connect(config.ui_server_address);
 			}
 			
-			ui_hsplit_b(&box, 60.f, &box, &part);
-			ui_hsplit_b(&box, 24.f, &box, &part);
+			box.HSplitBottom(60.f, &box, &part);
+			box.HSplitBottom(24.f, &box, &part);
 			
-			ui_vsplit_l(&part, 60.0f, 0, &label);
-			ui_vsplit_l(&label, 100.0f, 0, &textbox);
-			ui_vsplit_l(&textbox, 20.0f, 0, &textbox);
-			ui_vsplit_r(&textbox, 60.0f, &textbox, 0);
-			ui_do_label(&label, localize("Password"), 20, -1);
-			ui_do_edit_box(&config.password, &textbox, config.password, sizeof(config.password), 14.0f, true);
+			part.VSplitLeft(60.0f, 0, &label);
+			label.VSplitLeft(100.0f, 0, &textbox);
+			textbox.VSplitLeft(20.0f, 0, &textbox);
+			textbox.VSplitRight(60.0f, &textbox, 0);
+			UI()->DoLabel(&label, localize("Password"), 20, -1);
+			DoEditBox(&config.password, &textbox, config.password, sizeof(config.password), 14.0f, true);
 		}
 		else if(popup == POPUP_FIRST_LAUNCH)
 		{
-			RECT label, textbox;
+			CUIRect label, textbox;
 			
-			ui_hsplit_b(&box, 20.f, &box, &part);
-			ui_hsplit_b(&box, 24.f, &box, &part);
-			ui_vmargin(&part, 80.0f, &part);
+			box.HSplitBottom(20.f, &box, &part);
+			box.HSplitBottom(24.f, &box, &part);
+			part.VMargin(80.0f, &part);
 			
 			static int enter_button = 0;
-			if(ui_do_button(&enter_button, localize("Enter"), 0, &part, ui_draw_menu_button, 0) || enter_pressed)
+			if(DoButton_Menu(&enter_button, localize("Enter"), 0, &part) || enter_pressed)
 				popup = POPUP_NONE;
 			
-			ui_hsplit_b(&box, 40.f, &box, &part);
-			ui_hsplit_b(&box, 24.f, &box, &part);
+			box.HSplitBottom(40.f, &box, &part);
+			box.HSplitBottom(24.f, &box, &part);
 			
-			ui_vsplit_l(&part, 60.0f, 0, &label);
-			ui_vsplit_l(&label, 100.0f, 0, &textbox);
-			ui_vsplit_l(&textbox, 20.0f, 0, &textbox);
-			ui_vsplit_r(&textbox, 60.0f, &textbox, 0);
-			ui_do_label(&label, localize("Nickname"), 20, -1);
-			ui_do_edit_box(&config.player_name, &textbox, config.player_name, sizeof(config.player_name), 14.0f);
+			part.VSplitLeft(60.0f, 0, &label);
+			label.VSplitLeft(100.0f, 0, &textbox);
+			textbox.VSplitLeft(20.0f, 0, &textbox);
+			textbox.VSplitRight(60.0f, &textbox, 0);
+			UI()->DoLabel(&label, localize("Nickname"), 20, -1);
+			DoEditBox(&config.player_name, &textbox, config.player_name, sizeof(config.player_name), 14.0f);
 		}
 		else
 		{
-			ui_hsplit_b(&box, 20.f, &box, &part);
-			ui_hsplit_b(&box, 24.f, &box, &part);
-			ui_vmargin(&part, 120.0f, &part);
+			box.HSplitBottom(20.f, &box, &part);
+			box.HSplitBottom(24.f, &box, &part);
+			part.VMargin(120.0f, &part);
 
 			static int button = 0;
-			if(ui_do_button(&button, button_text, 0, &part, ui_draw_menu_button, 0) || escape_pressed || enter_pressed)
+			if(DoButton_Menu(&button, button_text, 0, &part) || escape_pressed || enter_pressed)
 			{
 				if(popup == POPUP_CONNECTING)
 					client_disconnect();
@@ -949,8 +957,8 @@ bool MENUS::on_mousemove(float x, float y)
 	mouse_pos.y += y;
 	if(mouse_pos.x < 0) mouse_pos.x = 0;
 	if(mouse_pos.y < 0) mouse_pos.y = 0;
-	if(mouse_pos.x > gfx_screenwidth()) mouse_pos.x = gfx_screenwidth();
-	if(mouse_pos.y > gfx_screenheight()) mouse_pos.y = gfx_screenheight();
+	if(mouse_pos.x > Graphics()->ScreenWidth()) mouse_pos.x = Graphics()->ScreenWidth();
+	if(mouse_pos.y > Graphics()->ScreenHeight()) mouse_pos.y = Graphics()->ScreenHeight();
 	
 	return true;
 }
@@ -993,8 +1001,8 @@ void MENUS::on_statechange(int new_state, int old_state)
 			if(strstr(client_error_string(), "password"))
 			{
 				popup = POPUP_PASSWORD;
-				ui_set_hot_item(&config.password);
-				ui_set_active_item(&config.password);
+				UI()->SetHotItem(&config.password);
+				UI()->SetActiveItem(&config.password);
 			}
 			else
 				popup = POPUP_DISCONNECTED;
@@ -1028,10 +1036,10 @@ void MENUS::on_render()
 	gfx_text_set_cursor(&cursor, 10, 30, 15, TEXTFLAG_RENDER);
 	gfx_text_ex(&cursor, "ようこそ - ガイド", -1);
 	
-	//gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_quads_drawTL(60, 60, 5000, 5000);
-	gfx_quads_end();
+	//Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
+	Graphics()->QuadsDrawTL(60, 60, 5000, 5000);
+	Graphics()->QuadsEnd();
 	return;*/
 	
 	if(client_state() != CLIENTSTATE_ONLINE && client_state() != CLIENTSTATE_DEMOPLAYBACK)
@@ -1039,8 +1047,8 @@ void MENUS::on_render()
 
 	if(client_state() == CLIENTSTATE_DEMOPLAYBACK)
 	{
-		RECT screen = *ui_screen();
-		gfx_mapscreen(screen.x, screen.y, screen.w, screen.h);
+		CUIRect screen = *UI()->Screen();
+		Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);
 		render_demoplayer(screen);
 	}
 	
@@ -1081,36 +1089,36 @@ void MENUS::on_render()
 		gui_color.a);
     
 	// update the ui
-	RECT *screen = ui_screen();
-	float mx = (mouse_pos.x/(float)gfx_screenwidth())*screen->w;
-	float my = (mouse_pos.y/(float)gfx_screenheight())*screen->h;
+	CUIRect *screen = UI()->Screen();
+	float mx = (mouse_pos.x/(float)Graphics()->ScreenWidth())*screen->w;
+	float my = (mouse_pos.y/(float)Graphics()->ScreenHeight())*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,mx*3.0f,my*3.0f,buttons);
+	UI()->Update(mx,my,mx*3.0f,my*3.0f,buttons);
     
 	// render
 	if(client_state() != CLIENTSTATE_DEMOPLAYBACK)
 		render();
 
 	// render cursor
-	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();
+	Graphics()->TextureSet(data->images[IMAGE_CURSOR].id);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(1,1,1,1);
+	Graphics()->QuadsDrawTL(mx,my,24,24);
+	Graphics()->QuadsEnd();
 
 	// render debug information
 	if(config.debug)
 	{
-		RECT screen = *ui_screen();
-		gfx_mapscreen(screen.x, screen.y, screen.w, screen.h);
+		CUIRect screen = *UI()->Screen();
+		Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);
 
 		char buf[512];
-		str_format(buf, sizeof(buf), "%p %p %p", ui_hot_item(), ui_active_item(), ui_last_active_item());
+		str_format(buf, sizeof(buf), "%p %p %p", UI()->HotItem(), UI()->ActiveItem(), UI()->LastActiveItem());
 		TEXT_CURSOR cursor;
 		gfx_text_set_cursor(&cursor, 10, 10, 10, TEXTFLAG_RENDER);
 		gfx_text_ex(&cursor, buf, -1);
@@ -1125,53 +1133,53 @@ static int texture_blob = -1;
 
 void MENUS::render_background()
 {
-	//gfx_clear(1,1,1);
+	//Graphics()->Clear(1,1,1);
 	//render_sunrays(0,0);
 	if(texture_blob == -1)
-		texture_blob = gfx_load_texture("blob.png", IMG_AUTO, 0);
+		texture_blob = Graphics()->LoadTexture("blob.png", IMG_AUTO, 0);
 
 
-	float sw = 300*gfx_screenaspect();
+	float sw = 300*Graphics()->ScreenAspect();
 	float sh = 300;
-	gfx_mapscreen(0, 0, sw, sh);
+	Graphics()->MapScreen(0, 0, sw, sh);
 
-	RECT s = *ui_screen();
+	CUIRect s = *UI()->Screen();
 
 	// render background color
-	gfx_texture_set(-1);
-	gfx_quads_begin();
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
 		//vec4 bottom(gui_color.r*0.3f, gui_color.g*0.3f, gui_color.b*0.3f, 1.0f);
 		//vec4 bottom(0, 0, 0, 1.0f);
 		vec4 bottom(gui_color.r, gui_color.g, gui_color.b, 1.0f);
 		vec4 top(gui_color.r, gui_color.g, gui_color.b, 1.0f);
-		gfx_setcolorvertex(0, top.r, top.g, top.b, top.a);
-		gfx_setcolorvertex(1, top.r, top.g, top.b, top.a);
-		gfx_setcolorvertex(2, bottom.r, bottom.g, bottom.b, bottom.a);
-		gfx_setcolorvertex(3, bottom.r, bottom.g, bottom.b, bottom.a);
-		gfx_quads_drawTL(0, 0, sw, sh);
-	gfx_quads_end();
+		Graphics()->SetColorVertex(0, top.r, top.g, top.b, top.a);
+		Graphics()->SetColorVertex(1, top.r, top.g, top.b, top.a);
+		Graphics()->SetColorVertex(2, bottom.r, bottom.g, bottom.b, bottom.a);
+		Graphics()->SetColorVertex(3, bottom.r, bottom.g, bottom.b, bottom.a);
+		Graphics()->QuadsDrawTL(0, 0, sw, sh);
+	Graphics()->QuadsEnd();
 	
 	// render the tiles
-	gfx_texture_set(-1);
-	gfx_quads_begin();
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
 		float size = 15.0f;
 		float offset_time = fmod(client_localtime()*0.15f, 2.0f);
 		for(int y = -2; y < (int)(sw/size); y++)
 			for(int x = -2; x < (int)(sh/size); x++)
 			{
-				gfx_setcolor(0,0,0,0.045f);
-				gfx_quads_drawTL((x-offset_time)*size*2+(y&1)*size, (y+offset_time)*size, size, size);
+				Graphics()->SetColor(0,0,0,0.045f);
+				Graphics()->QuadsDrawTL((x-offset_time)*size*2+(y&1)*size, (y+offset_time)*size, size, size);
 			}
-	gfx_quads_end();
+	Graphics()->QuadsEnd();
 
 	// render border fade
-	gfx_texture_set(texture_blob);
-	gfx_quads_begin();
-		gfx_setcolor(0,0,0,0.5f);
-		gfx_quads_drawTL(-100, -100, sw+200, sh+200);
-	gfx_quads_end();
+	Graphics()->TextureSet(texture_blob);
+	Graphics()->QuadsBegin();
+		Graphics()->SetColor(0,0,0,0.5f);
+		Graphics()->QuadsDrawTL(-100, -100, sw+200, sh+200);
+	Graphics()->QuadsEnd();
 
 	// restore screen	
-    {RECT screen = *ui_screen();
-	gfx_mapscreen(screen.x, screen.y, screen.w, screen.h);}	
+    {CUIRect screen = *UI()->Screen();
+	Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);}	
 }
diff --git a/src/game/client/components/menus.hpp b/src/game/client/components/menus.hpp
index 15369dbc..02759403 100644
--- a/src/game/client/components/menus.hpp
+++ b/src/game/client/components/menus.hpp
@@ -26,39 +26,58 @@ class MENUS : public COMPONENT
 	static vec4 color_tabbar_inactive;
 	static vec4 color_tabbar_active;
 	
-	static vec4 button_color_mul(const void *id);
+	vec4 button_color_mul(const void *pID);
 
 
-	static void ui_draw_demoplayer_button(const void *id, const char *text, int checked, const RECT *r, const void *extra);
+	int DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
+	int DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
+	int DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners);
+	int DoButton_SettingsTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
 
-	static void ui_draw_browse_icon(int what, const RECT *r);
-	static void ui_draw_menu_button(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-	static void ui_draw_keyselect_button(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-	static void ui_draw_menu_tab_button(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-	static void ui_draw_settings_tab_button(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-	static void ui_draw_grid_header(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-	static void ui_draw_list_row(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-	static void ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const RECT *r);
-	static void ui_draw_checkbox(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-	static void ui_draw_checkbox_number(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-	static int ui_do_edit_box(void *id, const RECT *rect, char *str, unsigned str_size, float font_size, bool hidden=false);
+	int DoButton_CheckBox_Common(const void *pID, const char *pText, const char *pBoxText, const CUIRect *pRect);
+	int DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
+	int DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
 
-	static float ui_do_scrollbar_v(const void *id, const RECT *rect, float current);
-	static float ui_do_scrollbar_h(const void *id, const RECT *rect, float current);
+	/*static void ui_draw_menu_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra);
+	static void ui_draw_keyselect_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra);
+	static void ui_draw_menu_tab_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra);
+	static void ui_draw_settings_tab_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra);
+	*/
 
-	static int ui_do_key_reader(void *id, const RECT *rect, int key);
-	static void ui_do_getbuttons(int start, int stop, RECT view);
+	int DoButton_BrowseIcon(int Checked, const CUIRect *pRect);
+	int DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
+	int DoButton_ListRow(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
+
+	//static void ui_draw_browse_icon(int what, const CUIRect *r);
+	//static void ui_draw_grid_header(const void *id, const char *text, int checked, const CUIRect *r, const void *extra);
+	
+	/*static void ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const CUIRect *r, const void *extra);
+	static void ui_draw_checkbox(const void *id, const char *text, int checked, const CUIRect *r, const void *extra);
+	static void ui_draw_checkbox_number(const void *id, const char *text, int checked, const CUIRect *r, const void *extra);
+	*/
+	int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden=false);
+	//static int ui_do_edit_box(void *id, const CUIRect *rect, char *str, unsigned str_size, float font_size, bool hidden=false);
+
+	float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current);
+	float DoScrollbarH(const void *pID, const CUIRect *pRect, float Current);
+	int DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
+	int DoKeyReader(void *pID, const CUIRect *pRect, int Key);
+
+	//static int ui_do_key_reader(void *id, const CUIRect *rect, int key);
+	void ui_do_getbuttons(int start, int stop, CUIRect view);
 
 	struct LISTBOXITEM
 	{
 		int visible;
 		int selected;
-		RECT rect;
+		CUIRect rect;
+		CUIRect hitrect;
 	};
 	
-	static void ui_do_listbox_start(void *id, const RECT *rect, float row_height, const char *title, int num_items, int selected_index);
-	static LISTBOXITEM ui_do_listbox_nextitem(void *id);
-	static int ui_do_listbox_end();
+	void ui_do_listbox_start(void *id, const CUIRect *rect, float row_height, const char *title, int num_items, int selected_index);
+	LISTBOXITEM ui_do_listbox_nextitem(void *id);
+	static LISTBOXITEM ui_do_listbox_nextrow();
+	int ui_do_listbox_end();
 	
 	//static void demolist_listdir_callback(const char *name, int is_dir, void *user);
 	//static void demolist_list_callback(const RECT *rect, int index, void *user);
@@ -143,39 +162,42 @@ class MENUS : public COMPONENT
 
 	// found in menus.cpp
 	int render();
-	void render_background();
+	//void render_background();
 	//void render_loading(float percent);
-	int render_menubar(RECT r);
-	void render_news(RECT main_view);
+	int render_menubar(CUIRect r);
+	void render_news(CUIRect main_view);
 	
 	// found in menus_demo.cpp
-	void render_demoplayer(RECT main_view);
-	void render_demolist(RECT main_view);
+	void render_demoplayer(CUIRect main_view);
+	void render_demolist(CUIRect main_view);
 	
 	// found in menus_ingame.cpp
-	void render_game(RECT main_view);
-	void render_serverinfo(RECT main_view);
-	void render_servercontrol(RECT main_view);
-	void render_servercontrol_kick(RECT main_view);
-	void render_servercontrol_server(RECT main_view);
+	void render_game(CUIRect main_view);
+	void render_serverinfo(CUIRect main_view);
+	void render_servercontrol(CUIRect main_view);
+	void render_servercontrol_kick(CUIRect main_view);
+	void render_servercontrol_server(CUIRect main_view);
 	
 	// found in menus_browser.cpp
 	int selected_index;
-	void render_serverbrowser_serverlist(RECT view);
-	void render_serverbrowser_serverdetail(RECT view);
-	void render_serverbrowser_filters(RECT view);
-	void render_serverbrowser(RECT main_view);
+	void render_serverbrowser_serverlist(CUIRect view);
+	void render_serverbrowser_serverdetail(CUIRect view);
+	void render_serverbrowser_filters(CUIRect view);
+	void render_serverbrowser(CUIRect main_view);
 	
 	// found in menus_settings.cpp
-	void render_settings_general(RECT main_view);
-	void render_settings_player(RECT main_view);
-	void render_settings_controls(RECT main_view);
-	void render_settings_graphics(RECT main_view);
-	void render_settings_sound(RECT main_view);
-	void render_settings(RECT main_view);
+	void render_settings_general(CUIRect main_view);
+	void render_settings_player(CUIRect main_view);
+	void render_settings_controls(CUIRect main_view);
+	void render_settings_graphics(CUIRect main_view);
+	void render_settings_sound(CUIRect main_view);
+	void render_settings(CUIRect main_view);
 	
 	void set_active(bool active);
 public:
+	void render_background();
+
+
 	static MENUS_KEYBINDER binder;
 	
 	MENUS();
diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp
index a7f21084..dcf68f8d 100644
--- a/src/game/client/components/menus_browser.cpp
+++ b/src/game/client/components/menus_browser.cpp
@@ -12,17 +12,17 @@
 #include <game/localization.hpp>
 #include <game/version.hpp>
 
-void MENUS::render_serverbrowser_serverlist(RECT view)
+void MENUS::render_serverbrowser_serverlist(CUIRect view)
 {
-	RECT headers;
-	RECT status;
+	CUIRect headers;
+	CUIRect status;
 	
-	ui_hsplit_t(&view, listheader_height, &headers, &view);
-	ui_hsplit_b(&view, 28.0f, &view, &status);
+	view.HSplitTop(listheader_height, &headers, &view);
+	view.HSplitBottom(28.0f, &view, &status);
 	
 	// split of the scrollbar
-	ui_draw_rect(&headers, vec4(1,1,1,0.25f), CORNER_T, 5.0f);
-	ui_vsplit_r(&headers, 20.0f, &headers, 0);
+	RenderTools()->DrawUIRect(&headers, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f);
+	headers.VSplitRight(20.0f, &headers, 0);
 	
 	struct column
 	{
@@ -32,8 +32,8 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 		int direction;
 		float width;
 		int flags;
-		RECT rect;
-		RECT spacer;
+		CUIRect rect;
+		CUIRect spacer;
 	};
 	
 	enum
@@ -72,12 +72,12 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 	{
 		if(cols[i].direction == -1)
 		{
-			ui_vsplit_l(&headers, cols[i].width, &cols[i].rect, &headers);
+			headers.VSplitLeft(cols[i].width, &cols[i].rect, &headers);
 			
 			if(i+1 < num_cols)
 			{
 				//cols[i].flags |= SPACER;
-				ui_vsplit_l(&headers, 2, &cols[i].spacer, &headers);
+				headers.VSplitLeft(2, &cols[i].spacer, &headers);
 			}
 		}
 	}
@@ -86,8 +86,8 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 	{
 		if(cols[i].direction == 1)
 		{
-			ui_vsplit_r(&headers, cols[i].width, &headers, &cols[i].rect);
-			ui_vsplit_r(&headers, 2, &headers, &cols[i].spacer);
+			headers.VSplitRight(cols[i].width, &headers, &cols[i].rect);
+			headers.VSplitRight(2, &headers, &cols[i].spacer);
 		}
 	}
 	
@@ -100,7 +100,7 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 	// do headers
 	for(int i = 0; i < num_cols; i++)
 	{
-		if(ui_do_button(cols[i].caption, cols[i].caption, config.b_sort == cols[i].sort, &cols[i].rect, ui_draw_grid_header, 0))
+		if(DoButton_GridHeader(cols[i].caption, cols[i].caption, config.b_sort == cols[i].sort, &cols[i].rect))
 		{
 			if(cols[i].sort != -1)
 			{
@@ -113,33 +113,33 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 		}
 	}
 	
-	ui_draw_rect(&view, vec4(0,0,0,0.15f), 0, 0);
+	RenderTools()->DrawUIRect(&view, vec4(0,0,0,0.15f), 0, 0);
 	
-	RECT scroll;
-	ui_vsplit_r(&view, 15, &view, &scroll);
+	CUIRect scroll;
+	view.VSplitRight(15, &view, &scroll);
 	
 	int num_servers = client_serverbrowse_sorted_num();
 	
 	// display important messages in the middle of the screen so no
 	// users misses it
 	{
-		RECT msgbox = view;
+		CUIRect msgbox = view;
 		msgbox.y += view.h/3;
 		
 		if(active_page == PAGE_INTERNET && client_serverbrowse_refreshingmasters())
-			ui_do_label(&msgbox, localize("Refreshing master servers"), 16.0f, 0);
+			UI()->DoLabel(&msgbox, localize("Refreshing master servers"), 16.0f, 0);
 		else if(!client_serverbrowse_num())
-			ui_do_label(&msgbox, localize("No servers found"), 16.0f, 0);
+			UI()->DoLabel(&msgbox, localize("No servers found"), 16.0f, 0);
 		else if(client_serverbrowse_num() && !num_servers)
-			ui_do_label(&msgbox, localize("No servers match your filter criteria"), 16.0f, 0);
+			UI()->DoLabel(&msgbox, localize("No servers match your filter criteria"), 16.0f, 0);
 	}
 
 	int num = (int)(view.h/cols[0].rect.h);
 	static int scrollbar = 0;
 	static float scrollvalue = 0;
 	//static int selected_index = -1;
-	ui_hmargin(&scroll, 5.0f, &scroll);
-	scrollvalue = ui_do_scrollbar_v(&scrollbar, &scroll, scrollvalue);
+	scroll.HMargin(5.0f, &scroll);
+	scrollvalue = DoScrollbarV(&scrollbar, &scroll, scrollvalue);
 	
 	int scrollnum = num_servers-num+10;
 	if(scrollnum > 0)
@@ -156,13 +156,13 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 		scrollnum = 0;
 
 	// set clipping
-	ui_clip_enable(&view);
+	UI()->ClipEnable(&view);
 	
 	int start = (int)(scrollnum*scrollvalue);
 	if(start < 0)
 		start = 0;
 	
-	RECT original_view = view;
+	CUIRect original_view = view;
 	view.y -= scrollvalue*scrollnum*cols[0].rect.h;
 	
 	int new_selected = -1;
@@ -180,20 +180,20 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 	{
 		int item_index = i;
 		SERVER_INFO *item = client_serverbrowse_sorted_get(item_index);
-		RECT row;
-        RECT select_hit_box;
+		CUIRect row;
+        CUIRect select_hit_box;
 		
 		int selected = strcmp(item->address, config.ui_server_address) == 0; //selected_index==item_index;
 		
-		ui_hsplit_t(&view, 17.0f, &row, &view);
+		view.HSplitTop(17.0f, &row, &view);
 		select_hit_box = row;
 		
 		if(selected)
 		{
 			selected_index = i;
-			RECT r = row;
-			ui_margin(&r, 1.5f, &r);
-			ui_draw_rect(&r, vec4(1,1,1,0.5f), CORNER_ALL, 4.0f);
+			CUIRect r = row;
+			r.Margin(1.5f, &r);
+			RenderTools()->DrawUIRect(&r, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f);
 		}
 
 
@@ -206,7 +206,7 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 				select_hit_box.y = original_view.y;
 			}
 			
-			if(ui_do_button(item, "", selected, &select_hit_box, 0, 0))
+			if(UI()->DoButtonLogic(item, "", selected, &select_hit_box))
 			{
 				new_selected = item_index;
 			}
@@ -218,7 +218,7 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 
 		for(int c = 0; c < num_cols; c++)
 		{
-			RECT button;
+			CUIRect button;
 			char temp[64];
 			button.x = cols[c].rect.x;
 			button.y = row.y;
@@ -228,12 +228,12 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 			//int s = 0;
 			int id = cols[c].id;
 
-			//s = ui_do_button(item, "L", l, &button, ui_draw_browse_icon, 0);
+			//s = UI()->DoButton(item, "L", l, &button, ui_draw_browse_icon, 0);
 			
 			if(id == COL_FLAG_LOCK)
 			{
 				if(item->flags & SRVFLAG_PASSWORD)
-					ui_draw_browse_icon(SPRITE_BROWSE_LOCK, &button);
+					DoButton_BrowseIcon(SPRITE_BROWSE_LOCK, &button);
 			}
 			else if(id == COL_FLAG_PURE)
 			{
@@ -244,13 +244,13 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 				else
 				{
 					// unpure
-					ui_draw_browse_icon(SPRITE_BROWSE_UNPURE, &button);
+					DoButton_BrowseIcon(SPRITE_BROWSE_UNPURE, &button);
 				}
 			}
 			else if(id == COL_FLAG_FAV)
 			{
 				if(item->favorite)
-					ui_draw_browse_icon(SPRITE_BROWSE_HEART, &button);
+					DoButton_BrowseIcon(SPRITE_BROWSE_HEART, &button);
 			}
 			else if(id == COL_NAME)
 			{
@@ -277,36 +277,36 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 					gfx_text_ex(&cursor, item->name, -1);
 			}
 			else if(id == COL_MAP)
-				ui_do_label(&button, item->map, 12.0f, -1);
+				UI()->DoLabel(&button, item->map, 12.0f, -1);
 			else if(id == COL_PLAYERS)
 			{
 				str_format(temp, sizeof(temp), "%i/%i", item->num_players, item->max_players);
 				if(config.b_filter_string[0] && (item->quicksearch_hit&BROWSEQUICK_PLAYERNAME))
 					gfx_text_color(0.4f,0.4f,1.0f,1);
-				ui_do_label(&button, temp, 12.0f, 1);
+				UI()->DoLabel(&button, temp, 12.0f, 1);
 				gfx_text_color(1,1,1,1);
 			}
 			else if(id == COL_PING)
 			{
 				str_format(temp, sizeof(temp), "%i", item->latency);
-				ui_do_label(&button, temp, 12.0f, 1);
+				UI()->DoLabel(&button, temp, 12.0f, 1);
 			}
 			else if(id == COL_VERSION)
 			{
 				const char *version = item->version;
 				if(strcmp(version, "0.3 e2d7973c6647a13c") == 0) // TODO: remove me later on
 					version = "0.3.0";
-				ui_do_label(&button, version, 12.0f, 1);
+				UI()->DoLabel(&button, version, 12.0f, 1);
 			}			
 			else if(id == COL_GAMETYPE)
 			{
-				ui_do_label(&button, item->gametype, 12.0f, 0);
+				UI()->DoLabel(&button, item->gametype, 12.0f, 0);
 			}
 
 		}
 	}
 
-	ui_clip_disable();
+	UI()->ClipDisable();
 	
 	if(new_selected != -1)
 	{
@@ -317,84 +317,84 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 			client_connect(config.ui_server_address);
 	}
 
-	ui_draw_rect(&status, vec4(1,1,1,0.25f), CORNER_B, 5.0f);
-	ui_margin(&status, 5.0f, &status);
+	RenderTools()->DrawUIRect(&status, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f);
+	status.Margin(5.0f, &status);
 	
 	// render quick search
-	RECT quicksearch;
-	ui_vsplit_l(&status, 250.0f, &quicksearch, &status);
+	CUIRect quicksearch;
+	status.VSplitLeft(250.0f, &quicksearch, &status);
 	const char *label = localize("Quick search");
-	ui_do_label(&quicksearch, label, 14.0f, -1);
-	ui_vsplit_l(&quicksearch, gfx_text_width(0, 14.0f, label, -1), 0, &quicksearch);
-	ui_vsplit_l(&quicksearch, 5, 0, &quicksearch);
-	ui_do_edit_box(&config.b_filter_string, &quicksearch, config.b_filter_string, sizeof(config.b_filter_string), 14.0f);
+	UI()->DoLabel(&quicksearch, label, 14.0f, -1);
+	quicksearch.VSplitLeft(gfx_text_width(0, 14.0f, label, -1), 0, &quicksearch);
+	quicksearch.VSplitLeft(5, 0, &quicksearch);
+	DoEditBox(&config.b_filter_string, &quicksearch, config.b_filter_string, sizeof(config.b_filter_string), 14.0f);
 	
 	// render status
 	char buf[128];
 	str_format(buf, sizeof(buf), localize("%d of %d servers, %d players"), client_serverbrowse_sorted_num(), client_serverbrowse_num(), num_players);
-	ui_vsplit_r(&status, gfx_text_width(0, 14.0f, buf, -1), 0, &status);
-	ui_do_label(&status, buf, 14.0f, -1);
+	status.VSplitRight(gfx_text_width(0, 14.0f, buf, -1), 0, &status);
+	UI()->DoLabel(&status, buf, 14.0f, -1);
 }
 
-void MENUS::render_serverbrowser_filters(RECT view)
+void MENUS::render_serverbrowser_filters(CUIRect view)
 {
 	// filters
-	RECT button;
+	CUIRect button;
 
-	ui_hsplit_t(&view, 5.0f, 0, &view);
-	ui_vsplit_l(&view, 5.0f, 0, &view);
-	ui_vsplit_r(&view, 5.0f, &view, 0);
-	ui_hsplit_b(&view, 5.0f, &view, 0);
+	view.HSplitTop(5.0f, 0, &view);
+	view.VSplitLeft(5.0f, 0, &view);
+	view.VSplitRight(5.0f, &view, 0);
+	view.HSplitBottom(5.0f, &view, 0);
 
 	// render filters
-	ui_hsplit_t(&view, 20.0f, &button, &view);
-	if (ui_do_button(&config.b_filter_empty, localize("Has people playing"), config.b_filter_empty, &button, ui_draw_checkbox, 0))
+	view.HSplitTop(20.0f, &button, &view);
+	if (DoButton_CheckBox(&config.b_filter_empty, localize("Has people playing"), config.b_filter_empty, &button))
 		config.b_filter_empty ^= 1;
 
-	ui_hsplit_t(&view, 20.0f, &button, &view);
-	if (ui_do_button(&config.b_filter_full, localize("Server not full"), config.b_filter_full, &button, ui_draw_checkbox, 0))
+	view.HSplitTop(20.0f, &button, &view);
+	if (DoButton_CheckBox(&config.b_filter_full, localize("Server not full"), config.b_filter_full, &button))
 		config.b_filter_full ^= 1;
 
-	ui_hsplit_t(&view, 20.0f, &button, &view);
-	if (ui_do_button(&config.b_filter_pw, localize("No password"), config.b_filter_pw, &button, ui_draw_checkbox, 0))
+	view.HSplitTop(20.0f, &button, &view);
+	if (DoButton_CheckBox(&config.b_filter_pw, localize("No password"), config.b_filter_pw, &button))
 		config.b_filter_pw ^= 1;
 
-	ui_hsplit_t(&view, 20.0f, &button, &view);
-	if (ui_do_button((char *)&config.b_filter_compatversion, localize("Compatible version"), config.b_filter_compatversion, &button, ui_draw_checkbox, 0))
+	view.HSplitTop(20.0f, &button, &view);
+	if (DoButton_CheckBox((char *)&config.b_filter_compatversion, localize("Compatible version"), config.b_filter_compatversion, &button))
 		config.b_filter_compatversion ^= 1;
 	
-	ui_hsplit_t(&view, 20.0f, &button, &view);
-	if (ui_do_button((char *)&config.b_filter_pure, localize("Standard gametype"), config.b_filter_pure, &button, ui_draw_checkbox, 0))
+	view.HSplitTop(20.0f, &button, &view);
+	if (DoButton_CheckBox((char *)&config.b_filter_pure, localize("Standard gametype"), config.b_filter_pure, &button))
 		config.b_filter_pure ^= 1;
 
-	ui_hsplit_t(&view, 20.0f, &button, &view);
-	/*ui_vsplit_l(&button, 20.0f, 0, &button);*/
-	if (ui_do_button((char *)&config.b_filter_pure_map, localize("Standard map"), config.b_filter_pure_map, &button, ui_draw_checkbox, 0))
+	view.HSplitTop(20.0f, &button, &view);
+	/*button.VSplitLeft(20.0f, 0, &button);*/
+	if (DoButton_CheckBox((char *)&config.b_filter_pure_map, localize("Standard map"), config.b_filter_pure_map, &button))
 		config.b_filter_pure_map ^= 1;
 		
-	ui_hsplit_t(&view, 20.0f, &button, &view);
-	ui_do_label(&button, localize("Game types"), 14.0f, -1);
-	ui_vsplit_l(&button, 95.0f, 0, &button);
-	ui_margin(&button, 1.0f, &button);
-	ui_do_edit_box(&config.b_filter_gametype, &button, config.b_filter_gametype, sizeof(config.b_filter_gametype), 14.0f);
+	view.HSplitTop(20.0f, &button, &view);
+	UI()->DoLabel(&button, localize("Game types"), 14.0f, -1);
+	button.VSplitLeft(95.0f, 0, &button);
+	button.Margin(1.0f, &button);
+	DoEditBox(&config.b_filter_gametype, &button, config.b_filter_gametype, sizeof(config.b_filter_gametype), 14.0f);
 
 	{
-		ui_hsplit_t(&view, 20.0f, &button, &view);
-		RECT editbox;
-		ui_vsplit_l(&button, 40.0f, &editbox, &button);
-		ui_vsplit_l(&button, 5.0f, &button, &button);
+		view.HSplitTop(20.0f, &button, &view);
+		CUIRect editbox;
+		button.VSplitLeft(40.0f, &editbox, &button);
+		button.VSplitLeft(5.0f, &button, &button);
 		
 		char buf[8];
 		str_format(buf, sizeof(buf), "%d", config.b_filter_ping);
-		ui_do_edit_box(&config.b_filter_ping, &editbox, buf, sizeof(buf), 14.0f);
+		DoEditBox(&config.b_filter_ping, &editbox, buf, sizeof(buf), 14.0f);
 		config.b_filter_ping = atoi(buf);
 		
-		ui_do_label(&button, localize("Maximum ping"), 14.0f, -1);
+		UI()->DoLabel(&button, localize("Maximum ping"), 14.0f, -1);
 	}
 	
-	ui_hsplit_b(&view, button_height, &view, &button);
+	view.HSplitBottom(button_height, &view, &button);
 	static int clear_button = 0;
-	if(ui_do_button(&clear_button, localize("Reset filter"), 0, &button, ui_draw_menu_button, 0))
+	if(DoButton_Menu(&clear_button, localize("Reset filter"), 0, &button))
 	{
 		config.b_filter_full = 0;
 		config.b_filter_empty = 0;
@@ -407,48 +407,48 @@ void MENUS::render_serverbrowser_filters(RECT view)
 	}
 }
 
-void MENUS::render_serverbrowser_serverdetail(RECT view)
+void MENUS::render_serverbrowser_serverdetail(CUIRect view)
 {
-	RECT server_details = view;
-	RECT server_scoreboard, server_header;
+	CUIRect server_details = view;
+	CUIRect server_scoreboard, server_header;
 	
 	SERVER_INFO *selected_server = client_serverbrowse_sorted_get(selected_index);
 	
-	//ui_vsplit_l(&server_details, 10.0f, 0x0, &server_details);
+	//server_details.VSplitLeft(10.0f, 0x0, &server_details);
 
 	// split off a piece to use for scoreboard
-	ui_hsplit_t(&server_details, 140.0f, &server_details, &server_scoreboard);
-	ui_hsplit_b(&server_details, 10.0f, &server_details, 0x0);
+	server_details.HSplitTop(140.0f, &server_details, &server_scoreboard);
+	server_details.HSplitBottom(10.0f, &server_details, 0x0);
 
 	// server details
 	const float font_size = 12.0f;
-	ui_hsplit_t(&server_details, 20.0f, &server_header, &server_details);
-	ui_draw_rect(&server_header, vec4(1,1,1,0.25f), CORNER_T, 4.0f);
-	ui_draw_rect(&server_details, vec4(0,0,0,0.15f), CORNER_B, 4.0f);
-	ui_vsplit_l(&server_header, 8.0f, 0x0, &server_header);
-	ui_do_label(&server_header, localize("Server details"), font_size+2.0f, -1);
+	server_details.HSplitTop(20.0f, &server_header, &server_details);
+	RenderTools()->DrawUIRect(&server_header, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f);
+	RenderTools()->DrawUIRect(&server_details, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f);
+	server_header.VSplitLeft(8.0f, 0x0, &server_header);
+	UI()->DoLabel(&server_header, localize("Server details"), font_size+2.0f, -1);
 
-	ui_vsplit_l(&server_details, 5.0f, 0x0, &server_details);
+	server_details.VSplitLeft(5.0f, 0x0, &server_details);
 
-	ui_margin(&server_details, 3.0f, &server_details);
+	server_details.Margin(3.0f, &server_details);
 
 	if (selected_server)
 	{
-		RECT row;
+		CUIRect row;
 		static LOC_CONSTSTRING labels[] = {
 			localize("Version"),
 			localize("Game type"),
 			localize("Ping")};
 
-		RECT left_column;
-		RECT right_column;
+		CUIRect left_column;
+		CUIRect right_column;
 
 		// 
 		{
-			RECT button;
-			ui_hsplit_b(&server_details, 20.0f, &server_details, &button);
+			CUIRect button;
+			server_details.HSplitBottom(20.0f, &server_details, &button);
 			static int add_fav_button = 0;
-			if (ui_do_button(&add_fav_button, localize("Favorite"), selected_server->favorite, &button, ui_draw_checkbox, 0))
+			if(DoButton_CheckBox(&add_fav_button, localize("Favorite"), selected_server->favorite, &button))
 			{
 				if(selected_server->favorite)
 					client_serverbrowse_removefavorite(selected_server->netaddr);
@@ -456,55 +456,55 @@ void MENUS::render_serverbrowser_serverdetail(RECT view)
 					client_serverbrowse_addfavorite(selected_server->netaddr);
 			}
 		}
-		//ui_do_label(&row, temp, font_size, -1);		
+		//UI()->DoLabel(&row, temp, font_size, -1);		
 
-		ui_vsplit_l(&server_details, 5.0f, 0x0, &server_details);
-		ui_vsplit_l(&server_details, 80.0f, &left_column, &right_column);
+		server_details.VSplitLeft(5.0f, 0x0, &server_details);
+		server_details.VSplitLeft(80.0f, &left_column, &right_column);
 
 		for (unsigned int i = 0; i < sizeof(labels) / sizeof(labels[0]); i++)
 		{
-			ui_hsplit_t(&left_column, 15.0f, &row, &left_column);
-			ui_do_label(&row, labels[i], font_size, -1);
+			left_column.HSplitTop(15.0f, &row, &left_column);
+			UI()->DoLabel(&row, labels[i], font_size, -1);
 		}
 
-		ui_hsplit_t(&right_column, 15.0f, &row, &right_column);
-		ui_do_label(&row, selected_server->version, font_size, -1);
+		right_column.HSplitTop(15.0f, &row, &right_column);
+		UI()->DoLabel(&row, selected_server->version, font_size, -1);
 
-		ui_hsplit_t(&right_column, 15.0f, &row, &right_column);
-		ui_do_label(&row, selected_server->gametype, font_size, -1);
+		right_column.HSplitTop(15.0f, &row, &right_column);
+		UI()->DoLabel(&row, selected_server->gametype, font_size, -1);
 
 		char temp[16];
 		str_format(temp, sizeof(temp), "%d", selected_server->latency);
-		ui_hsplit_t(&right_column, 15.0f, &row, &right_column);
-		ui_do_label(&row, temp, font_size, -1);
+		right_column.HSplitTop(15.0f, &row, &right_column);
+		UI()->DoLabel(&row, temp, font_size, -1);
 
 	}
 	
 	// server scoreboard
 	
-	ui_hsplit_b(&server_scoreboard, 10.0f, &server_scoreboard, 0x0);
-	ui_hsplit_t(&server_scoreboard, 20.0f, &server_header, &server_scoreboard);
-	ui_draw_rect(&server_header, vec4(1,1,1,0.25f), CORNER_T, 4.0f);
-	ui_draw_rect(&server_scoreboard, vec4(0,0,0,0.15f), CORNER_B, 4.0f);
-	ui_vsplit_l(&server_header, 8.0f, 0x0, &server_header);
-	ui_do_label(&server_header, localize("Scoreboard"), font_size+2.0f, -1);
+	server_scoreboard.HSplitBottom(10.0f, &server_scoreboard, 0x0);
+	server_scoreboard.HSplitTop(20.0f, &server_header, &server_scoreboard);
+	RenderTools()->DrawUIRect(&server_header, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f);
+	RenderTools()->DrawUIRect(&server_scoreboard, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f);
+	server_header.VSplitLeft(8.0f, 0x0, &server_header);
+	UI()->DoLabel(&server_header, localize("Scoreboard"), font_size+2.0f, -1);
 
-	ui_vsplit_l(&server_scoreboard, 5.0f, 0x0, &server_scoreboard);
+	server_scoreboard.VSplitLeft(5.0f, 0x0, &server_scoreboard);
 
-	ui_margin(&server_scoreboard, 3.0f, &server_scoreboard);
+	server_scoreboard.Margin(3.0f, &server_scoreboard);
 
 	if (selected_server)
 	{
 		for (int i = 0; i < selected_server->num_players; i++)
 		{
-			RECT row;
+			CUIRect row;
 			char temp[16];
-			ui_hsplit_t(&server_scoreboard, 16.0f, &row, &server_scoreboard);
+			server_scoreboard.HSplitTop(16.0f, &row, &server_scoreboard);
 
 			str_format(temp, sizeof(temp), "%d", selected_server->players[i].score);
-			ui_do_label(&row, temp, font_size, -1);
+			UI()->DoLabel(&row, temp, font_size, -1);
 
-			ui_vsplit_l(&row, 25.0f, 0x0, &row);
+			row.VSplitLeft(25.0f, 0x0, &row);
 		
 			TEXT_CURSOR cursor;
 			gfx_text_set_cursor(&cursor, row.x, row.y, 12.0f, TEXTFLAG_RENDER);
@@ -532,12 +532,12 @@ void MENUS::render_serverbrowser_serverdetail(RECT view)
 	}
 }
 
-void MENUS::render_serverbrowser(RECT main_view)
+void MENUS::render_serverbrowser(CUIRect main_view)
 {
-	ui_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f);
+	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
 	
-	RECT view;
-	ui_margin(&main_view, 10.0f, &view);
+	CUIRect view;
+	main_view.Margin(10.0f, &view);
 	
 	/*
 		+-----------------+ +------+
@@ -551,44 +551,44 @@ void MENUS::render_serverbrowser(RECT main_view)
 	*/
 	
 	
-	//RECT filters;
-	RECT status_toolbar;
-	RECT toolbox;
-	RECT button_box;
+	//CUIRect filters;
+	CUIRect status_toolbar;
+	CUIRect toolbox;
+	CUIRect button_box;
 
 	// split off a piece for filters, details and scoreboard
-	ui_vsplit_r(&view, 200.0f, &view, &toolbox);
-	ui_hsplit_b(&toolbox, 80.0f, &toolbox, &button_box);
-	ui_hsplit_b(&view, button_height+5.0f, &view, &status_toolbar);
+	view.VSplitRight(200.0f, &view, &toolbox);
+	toolbox.HSplitBottom(80.0f, &toolbox, &button_box);
+	view.HSplitBottom(button_height+5.0f, &view, &status_toolbar);
 
 	render_serverbrowser_serverlist(view);
 	
 	static int toolbox_page = 0;
 	
-	ui_vsplit_l(&toolbox, 5.0f, 0, &toolbox);
+	toolbox.VSplitLeft(5.0f, 0, &toolbox);
 
 	// do tabbar
 	{
-		RECT tab_bar;
-		RECT tabbutton0, tabbutton1;
-		ui_hsplit_t(&toolbox, 22.0f, &tab_bar, &toolbox);
+		CUIRect tab_bar;
+		CUIRect tabbutton0, tabbutton1;
+		toolbox.HSplitTop(22.0f, &tab_bar, &toolbox);
 	
-		ui_vsplit_mid(&tab_bar, &tabbutton0, &tabbutton1);
-		ui_vsplit_r(&tabbutton0, 5.0f, &tabbutton0, 0);
-		ui_vsplit_l(&tabbutton1, 5.0f, 0, &tabbutton1);
+		tab_bar.VSplitMid(&tabbutton0, &tabbutton1);
+		tabbutton0.VSplitRight(5.0f, &tabbutton0, 0);
+		tabbutton1.VSplitLeft(5.0f, 0, &tabbutton1);
 		
 		static int filters_tab = 0;
-		if (ui_do_button(&filters_tab, localize("Filter"), toolbox_page==0, &tabbutton0, ui_draw_menu_tab_button, 0))
+		if (DoButton_MenuTab(&filters_tab, localize("Filter"), toolbox_page==0, &tabbutton0, 0))
 			toolbox_page = 0;
 			
 		static int info_tab = 0;
-		if (ui_do_button(&info_tab, localize("Info"), toolbox_page==1, &tabbutton1, ui_draw_menu_tab_button, 0))
+		if (DoButton_MenuTab(&info_tab, localize("Info"), toolbox_page==1, &tabbutton1, 0))
 			toolbox_page = 1;
 	}
 
-	ui_draw_rect(&toolbox, vec4(0,0,0,0.15f), 0, 0);
+	RenderTools()->DrawUIRect(&toolbox, vec4(0,0,0,0.15f), 0, 0);
 	
-	ui_hsplit_t(&toolbox, 5.0f, 0, &toolbox);
+	toolbox.HSplitTop(5.0f, 0, &toolbox);
 	
 	if(toolbox_page == 0)
 		render_serverbrowser_filters(toolbox);
@@ -596,14 +596,14 @@ void MENUS::render_serverbrowser(RECT main_view)
 		render_serverbrowser_serverdetail(toolbox);
 
 	{
-		ui_hsplit_t(&status_toolbar, 5.0f, 0, &status_toolbar);
+		status_toolbar.HSplitTop(5.0f, 0, &status_toolbar);
 		
-		RECT button;
-		//ui_vsplit_r(&buttons, 20.0f, &buttons, &button);
-		ui_vsplit_r(&status_toolbar, 110.0f, &status_toolbar, &button);
-		ui_vmargin(&button, 2.0f, &button);
+		CUIRect button;
+		//buttons.VSplitRight(20.0f, &buttons, &button);
+		status_toolbar.VSplitRight(110.0f, &status_toolbar, &button);
+		button.VMargin(2.0f, &button);
 		static int refresh_button = 0;
-		if(ui_do_button(&refresh_button, localize("Refresh"), 0, &button, ui_draw_menu_button, 0))
+		if(DoButton_Menu(&refresh_button, localize("Refresh"), 0, &button))
 		{
 			if(config.ui_page == PAGE_INTERNET)
 				client_serverbrowse_refresh(BROWSETYPE_INTERNET);
@@ -618,31 +618,31 @@ void MENUS::render_serverbrowser(RECT main_view)
 			str_format(buf, sizeof(buf), localize("Teeworlds %s is out! Download it at www.teeworlds.com!"), client_latestversion());
 		else
 			str_format(buf, sizeof(buf), localize("Current version: %s"), GAME_VERSION);
-		ui_do_label(&status_toolbar, buf, 14.0f, -1);
+		UI()->DoLabel(&status_toolbar, buf, 14.0f, -1);
 	}
 	
 	// do the button box
 	{
 		
-		ui_vsplit_l(&button_box, 5.0f, 0, &button_box);
-		ui_vsplit_r(&button_box, 5.0f, &button_box, 0);
+		button_box.VSplitLeft(5.0f, 0, &button_box);
+		button_box.VSplitRight(5.0f, &button_box, 0);
 		
-		RECT button;
-		ui_hsplit_b(&button_box, button_height, &button_box, &button);
-		ui_vsplit_r(&button, 120.0f, 0, &button);
-		ui_vmargin(&button, 2.0f, &button);
-		//ui_vmargin(&button, 2.0f, &button);
+		CUIRect button;
+		button_box.HSplitBottom(button_height, &button_box, &button);
+		button.VSplitRight(120.0f, 0, &button);
+		button.VMargin(2.0f, &button);
+		//button.VMargin(2.0f, &button);
 		static int join_button = 0;
-		if(ui_do_button(&join_button, localize("Connect"), 0, &button, ui_draw_menu_button, 0) || enter_pressed)
+		if(DoButton_Menu(&join_button, localize("Connect"), 0, &button) || enter_pressed)
 		{
 			client_connect(config.ui_server_address);
 			enter_pressed = false;
 		}
 					
-		ui_hsplit_b(&button_box, 5.0f, &button_box, &button);
-		ui_hsplit_b(&button_box, 20.0f, &button_box, &button);
-		ui_do_edit_box(&config.ui_server_address, &button, config.ui_server_address, sizeof(config.ui_server_address), 14.0f);
-		ui_hsplit_b(&button_box, 20.0f, &button_box, &button);
-		ui_do_label(&button, localize("Host address"), 14.0f, -1);
+		button_box.HSplitBottom(5.0f, &button_box, &button);
+		button_box.HSplitBottom(20.0f, &button_box, &button);
+		DoEditBox(&config.ui_server_address, &button, config.ui_server_address, sizeof(config.ui_server_address), 14.0f);
+		button_box.HSplitBottom(20.0f, &button_box, &button);
+		UI()->DoLabel(&button, localize("Host address"), 14.0f, -1);
 	}
 }
diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp
index 594ee3df..07019d46 100644
--- a/src/game/client/components/menus_demo.cpp
+++ b/src/game/client/components/menus_demo.cpp
@@ -17,13 +17,14 @@
 
 #include "menus.hpp"
 
-void MENUS::ui_draw_demoplayer_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int MENUS::DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
-	ui_draw_rect(r, vec4(1,1,1, checked ? 0.10f : 0.5f)*button_color_mul(id), CORNER_ALL, 5.0f);
-	ui_do_label(r, text, 14.0f, 0);
+	RenderTools()->DrawUIRect(pRect, vec4(1,1,1, Checked ? 0.10f : 0.5f)*button_color_mul(pID), CUI::CORNER_ALL, 5.0f);
+	UI()->DoLabel(pRect, pText, 14.0f, 0);
+	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-void MENUS::render_demoplayer(RECT main_view)
+void MENUS::render_demoplayer(CUIRect main_view)
 {
 	const DEMOPLAYBACK_INFO *info = client_demoplayer_getinfo();
 	
@@ -37,20 +38,20 @@ void MENUS::render_demoplayer(RECT main_view)
 	else
 		total_height = seekbar_height+margins*2;
 	
-	ui_hsplit_b(&main_view, total_height, 0, &main_view);
-	ui_vsplit_l(&main_view, 250.0f, 0, &main_view);
-	ui_vsplit_r(&main_view, 250.0f, &main_view, 0);
+	main_view.HSplitBottom(total_height, 0, &main_view);
+	main_view.VSplitLeft(250.0f, 0, &main_view);
+	main_view.VSplitRight(250.0f, &main_view, 0);
 	
-	ui_draw_rect(&main_view, color_tabbar_active, CORNER_T, 10.0f);
+	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_T, 10.0f);
 		
-	ui_margin(&main_view, 5.0f, &main_view);
+	main_view.Margin(5.0f, &main_view);
 	
-	RECT seekbar, buttonbar;
+	CUIRect seekbar, buttonbar;
 	
 	if(menu_active)
 	{
-		ui_hsplit_t(&main_view, seekbar_height, &seekbar, &buttonbar);
-		ui_hsplit_t(&buttonbar, margins, 0, &buttonbar);
+		main_view.HSplitTop(seekbar_height, &seekbar, &buttonbar);
+		buttonbar.HSplitTop(margins, 0, &buttonbar);
 	}
 	else
 		seekbar = main_view;
@@ -61,33 +62,33 @@ void MENUS::render_demoplayer(RECT main_view)
 		void *id = &seekbar_id;
 		char buffer[128];
 		
-		ui_draw_rect(&seekbar, vec4(0,0,0,0.5f), CORNER_ALL, 5.0f);
+		RenderTools()->DrawUIRect(&seekbar, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 5.0f);
 		
 		int current_tick = info->current_tick - info->first_tick;
 		int total_ticks = info->last_tick - info->first_tick;
 		
 		float amount = current_tick/(float)total_ticks;
 		
-		RECT filledbar = seekbar;
+		CUIRect filledbar = seekbar;
 		filledbar.w = 10.0f + (filledbar.w-10.0f)*amount;
 		
-		ui_draw_rect(&filledbar, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f);
+		RenderTools()->DrawUIRect(&filledbar, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 5.0f);
 		
 		str_format(buffer, sizeof(buffer), "%d:%02d / %d:%02d",
 			current_tick/SERVER_TICK_SPEED/60, (current_tick/SERVER_TICK_SPEED)%60,
 			total_ticks/SERVER_TICK_SPEED/60, (total_ticks/SERVER_TICK_SPEED)%60);
-		ui_do_label(&seekbar, buffer, seekbar.h*0.70f, 0);
+		UI()->DoLabel(&seekbar, buffer, seekbar.h*0.70f, 0);
 
 		// do the logic
-	    int inside = ui_mouse_inside(&seekbar);
+	    int inside = UI()->MouseInside(&seekbar);
 			
-		if(ui_active_item() == id)
+		if(UI()->ActiveItem() == id)
 		{
-			if(!ui_mouse_button(0))
-				ui_set_active_item(0);
+			if(!UI()->MouseButton(0))
+				UI()->SetActiveItem(0);
 			else
 			{
-				float amount = (ui_mouse_x()-seekbar.x)/(float)seekbar.w;
+				float amount = (UI()->MouseX()-seekbar.x)/(float)seekbar.w;
 				if(amount > 0 && amount < 1.0f)
 				{
 					gameclient.on_reset();
@@ -97,43 +98,43 @@ void MENUS::render_demoplayer(RECT main_view)
 				}
 			}
 		}
-		else if(ui_hot_item() == id)
+		else if(UI()->HotItem() == id)
 		{
-			if(ui_mouse_button(0))
-				ui_set_active_item(id);
+			if(UI()->MouseButton(0))
+				UI()->SetActiveItem(id);
 		}		
 		
 		if(inside)
-			ui_set_hot_item(id);
+			UI()->SetHotItem(id);
 	}	
 	
 
 	if(menu_active)
 	{
 		// do buttons
-		RECT button;
+		CUIRect button;
 
 		// pause button
-		ui_vsplit_l(&buttonbar, buttonbar_height, &button, &buttonbar);
+		buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar);
 		static int pause_button = 0;
-		if(ui_do_button(&pause_button, "| |", info->paused, &button, ui_draw_demoplayer_button, 0))
+		if(DoButton_DemoPlayer(&pause_button, "| |", info->paused, &button))
 			client_demoplayer_setpause(!info->paused);
 		
 		// play button
-		ui_vsplit_l(&buttonbar, margins, 0, &buttonbar);
-		ui_vsplit_l(&buttonbar, buttonbar_height, &button, &buttonbar);
+		buttonbar.VSplitLeft(margins, 0, &buttonbar);
+		buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar);
 		static int play_button = 0;
-		if(ui_do_button(&play_button, ">", !info->paused, &button, ui_draw_demoplayer_button, 0))
+		if(DoButton_DemoPlayer(&play_button, ">", !info->paused, &button))
 		{
 			client_demoplayer_setpause(0);
 			client_demoplayer_setspeed(1.0f);
 		}
 
 		// slowdown
-		ui_vsplit_l(&buttonbar, margins, 0, &buttonbar);
-		ui_vsplit_l(&buttonbar, buttonbar_height, &button, &buttonbar);
+		buttonbar.VSplitLeft(margins, 0, &buttonbar);
+		buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar);
 		static int slowdown_button = 0;
-		if(ui_do_button(&slowdown_button, "<<", 0, &button, ui_draw_demoplayer_button, 0))
+		if(DoButton_DemoPlayer(&slowdown_button, "<<", 0, &button))
 		{
 			if(info->speed > 4.0f) client_demoplayer_setspeed(4.0f);
 			else if(info->speed > 2.0f) client_demoplayer_setspeed(2.0f);
@@ -143,10 +144,10 @@ void MENUS::render_demoplayer(RECT main_view)
 		}
 		
 		// fastforward
-		ui_vsplit_l(&buttonbar, margins, 0, &buttonbar);
-		ui_vsplit_l(&buttonbar, buttonbar_height, &button, &buttonbar);
+		buttonbar.VSplitLeft(margins, 0, &buttonbar);
+		buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar);
 		static int fastforward_button = 0;
-		if(ui_do_button(&fastforward_button, ">>", 0, &button, ui_draw_demoplayer_button, 0))
+		if(DoButton_DemoPlayer(&fastforward_button, ">>", 0, &button))
 		{
 			if(info->speed < 0.5f) client_demoplayer_setspeed(0.5f);
 			else if(info->speed < 1.0f) client_demoplayer_setspeed(1.0f);
@@ -156,24 +157,24 @@ void MENUS::render_demoplayer(RECT main_view)
 		}
 
 		// speed meter
-		ui_vsplit_l(&buttonbar, margins*3, 0, &buttonbar);
+		buttonbar.VSplitLeft(margins*3, 0, &buttonbar);
 		char buffer[64];
 		if(info->speed >= 1.0f)
 			str_format(buffer, sizeof(buffer), "x%.0f", info->speed);
 		else
 			str_format(buffer, sizeof(buffer), "x%.1f", info->speed);
-		ui_do_label(&buttonbar, buffer, button.h*0.7f, -1);
+		UI()->DoLabel(&buttonbar, buffer, button.h*0.7f, -1);
 
 		// close button
-		ui_vsplit_r(&buttonbar, buttonbar_height*3, &buttonbar, &button);
+		buttonbar.VSplitRight(buttonbar_height*3, &buttonbar, &button);
 		static int exit_button = 0;
-		if(ui_do_button(&exit_button, localize("Close"), 0, &button, ui_draw_demoplayer_button, 0))
+		if(DoButton_DemoPlayer(&exit_button, localize("Close"), 0, &button))
 			client_disconnect();
 	}
 }
 
-static RECT listbox_originalview;
-static RECT listbox_view;
+static CUIRect listbox_originalview;
+static CUIRect listbox_view;
 static float listbox_rowheight;
 static int listbox_itemindex;
 static int listbox_selected_index;
@@ -181,27 +182,27 @@ static int listbox_new_selected;
 static int listbox_doneevents;
 static int listbox_numitems;
 
-void MENUS::ui_do_listbox_start(void *id, const RECT *rect, float row_height, const char *title, int num_items, int selected_index)
+void MENUS::ui_do_listbox_start(void *id, const CUIRect *rect, float row_height, const char *title, int num_items, int selected_index)
 {
-	RECT scroll, row;
-	RECT view = *rect;
-	RECT header, footer;
+	CUIRect scroll, row;
+	CUIRect view = *rect;
+	CUIRect header, footer;
 	
 	// draw header
-	ui_hsplit_t(&view, listheader_height, &header, &view);
-	ui_draw_rect(&header, vec4(1,1,1,0.25f), CORNER_T, 5.0f); 
-	ui_do_label(&header, title, header.h*fontmod_height, 0);
+	view.HSplitTop(listheader_height, &header, &view);
+	RenderTools()->DrawUIRect(&header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); 
+	UI()->DoLabel(&header, title, header.h*fontmod_height, 0);
 
 	// draw footers
-	ui_hsplit_b(&view, listheader_height, &view, &footer);
-	ui_draw_rect(&footer, vec4(1,1,1,0.25f), CORNER_B, 5.0f); 
-	ui_vsplit_l(&footer, 10.0f, 0, &footer);
+	view.HSplitBottom(listheader_height, &view, &footer);
+	RenderTools()->DrawUIRect(&footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); 
+	footer.VSplitLeft(10.0f, 0, &footer);
 
 	// background
-	ui_draw_rect(&view, vec4(0,0,0,0.15f), 0, 0);
+	RenderTools()->DrawUIRect(&view, vec4(0,0,0,0.15f), 0, 0);
 
 	// prepare the scroll
-	ui_vsplit_r(&view, 15, &view, &scroll);
+	view.VSplitRight(15, &view, &scroll);
 
 	// setup the variables	
 	listbox_originalview = view;
@@ -215,7 +216,7 @@ void MENUS::ui_do_listbox_start(void *id, const RECT *rect, float row_height, co
 
 
 	// do the scrollbar
-	ui_hsplit_t(&view, listbox_rowheight, &row, 0);
+	view.HSplitTop(listbox_rowheight, &row, 0);
 	
 	int num_viewable = (int)(listbox_originalview.h/row.h) + 1;
 	int num = num_items-num_viewable+1;
@@ -223,8 +224,8 @@ void MENUS::ui_do_listbox_start(void *id, const RECT *rect, float row_height, co
 		num = 0;
 		
 	static float scrollvalue = 0;
-	ui_hmargin(&scroll, 5.0f, &scroll);
-	scrollvalue = ui_do_scrollbar_v(id, &scroll, scrollvalue);
+	scroll.HMargin(5.0f, &scroll);
+	scrollvalue = DoScrollbarV(id, &scroll, scrollvalue);
 
 	int start = (int)(num*scrollvalue);
 	if(start < 0)
@@ -232,19 +233,62 @@ void MENUS::ui_do_listbox_start(void *id, const RECT *rect, float row_height, co
 	
 	// the list
 	listbox_view = listbox_originalview;
-	ui_vmargin(&listbox_view, 5.0f, &listbox_view);
-	ui_clip_enable(&listbox_view);
+	listbox_view.VMargin(5.0f, &listbox_view);
+	UI()->ClipEnable(&listbox_view);
 	listbox_view.y -= scrollvalue*num*row.h;	
 }
 
-MENUS::LISTBOXITEM MENUS::ui_do_listbox_nextitem(void *id)
+MENUS::LISTBOXITEM MENUS::ui_do_listbox_nextrow()
 {
-	RECT row;
 	LISTBOXITEM item = {0};
-	ui_hsplit_t(&listbox_view, listbox_rowheight /*-2.0f*/, &row, &listbox_view);
-	//ui_hsplit_t(&listbox_view, 2.0f, 0, &listbox_view);
+	listbox_view.HSplitTop(listbox_rowheight /*-2.0f*/, &item.rect, &listbox_view);
+	item.visible = 1;
+	//item.rect = row;
+	
+	item.hitrect = item.rect;
+	
+	//CUIRect select_hit_box = item.rect;
+
+	if(listbox_selected_index == listbox_itemindex)
+		item.selected = 1;
+	
+	// make sure that only those in view can be selected
+	if(item.rect.y+item.rect.h > listbox_originalview.y)
+	{
+		
+		if(item.hitrect.y < item.hitrect.y) // clip the selection
+		{
+			item.hitrect.h -= listbox_originalview.y-item.hitrect.y;
+			item.hitrect.y = listbox_originalview.y;
+		}
+		
+	}
+	else
+		item.visible = 0;
 
-	RECT select_hit_box = row;
+	// check if we need to do more
+	if(item.rect.y > listbox_originalview.y+listbox_originalview.h)
+		item.visible = 0;
+		
+	listbox_itemindex++;
+	return item;
+}
+
+MENUS::LISTBOXITEM MENUS::ui_do_listbox_nextitem(void *id)
+{
+	int this_itemindex = listbox_itemindex;
+	
+	LISTBOXITEM item = ui_do_listbox_nextrow();
+
+	if(UI()->DoButtonLogic(id, "", listbox_selected_index == listbox_itemindex, &item.hitrect))
+		listbox_new_selected = listbox_itemindex;
+	
+	//CUIRect row;
+	//LISTBOXITEM item = {0};
+	//listbox_view.HSplitTop(listbox_rowheight /*-2.0f*/, &row, &listbox_view);
+	//listbox_view.HSplitTop(2.0f, 0, &listbox_view);
+	/*
+	CUIRect select_hit_box = row;
 
 	item.visible = 1;
 	if(listbox_selected_index == listbox_itemindex)
@@ -260,19 +304,17 @@ MENUS::LISTBOXITEM MENUS::ui_do_listbox_nextitem(void *id)
 			select_hit_box.y = listbox_originalview.y;
 		}
 		
-		if(ui_do_button(id, "", listbox_selected_index==listbox_itemindex, &select_hit_box, 0, 0))
+		if(UI()->DoButton(id, "", listbox_selected_index==listbox_itemindex, &select_hit_box, 0, 0))
 			listbox_new_selected = listbox_itemindex;
 	}
 	else
 		item.visible = 0;
 	
 	item.rect = row;
+	*/
 	
-	// check if we need to do more
-	if(row.y > listbox_originalview.y+listbox_originalview.h)
-		item.visible = 0;
 
-	if(listbox_selected_index==listbox_itemindex)
+	if(listbox_selected_index == this_itemindex)
 	{
 		if(!listbox_doneevents)
 		{
@@ -294,21 +336,18 @@ MENUS::LISTBOXITEM MENUS::ui_do_listbox_nextitem(void *id)
 		}
 		
 		//selected_index = i;
-		RECT r = row;
-		ui_margin(&r, 1.5f, &r);
-		ui_draw_rect(&r, vec4(1,1,1,0.5f), CORNER_ALL, 4.0f);
+		CUIRect r = item.rect;
+		r.Margin(1.5f, &r);
+		RenderTools()->DrawUIRect(&r, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f);
 	}	
 
-	listbox_itemindex++;
-
-	ui_vmargin(&item.rect, 5.0f, &item.rect);
-
+	//listbox_itemindex++;
 	return item;
 }
 
 int MENUS::ui_do_listbox_end()
 {
-	ui_clip_disable();
+	UI()->ClipDisable();
 	return listbox_new_selected;
 }
 
@@ -346,7 +385,7 @@ void MENUS::demolist_populate()
 }
 
 
-void MENUS::render_demolist(RECT main_view)
+void MENUS::render_demolist(CUIRect main_view)
 {
 	static int inited = 0;
 	if(!inited)
@@ -354,12 +393,12 @@ void MENUS::render_demolist(RECT main_view)
 	inited = 1;
 	
 	// render background
-	ui_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f);
-	ui_margin(&main_view, 10.0f, &main_view);
+	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
+	main_view.Margin(10.0f, &main_view);
 	
-	RECT buttonbar;
-	ui_hsplit_b(&main_view, button_height+5.0f, &main_view, &buttonbar);
-	ui_hsplit_t(&buttonbar, 5.0f, 0, &buttonbar);
+	CUIRect buttonbar;
+	main_view.HSplitBottom(button_height+5.0f, &main_view, &buttonbar);
+	buttonbar.HSplitTop(5.0f, 0, &buttonbar);
 	
 	static int selected_item = -1;
 	static int demolist_id = 0;
@@ -370,23 +409,23 @@ void MENUS::render_demolist(RECT main_view)
 	{
 		LISTBOXITEM item = ui_do_listbox_nextitem((void*)(&r.front()));
 		if(item.visible)
-			ui_do_label(&item.rect, r.front().name, item.rect.h*fontmod_height, -1);
+			UI()->DoLabel(&item.rect, r.front().name, item.rect.h*fontmod_height, -1);
 	}
 	selected_item = ui_do_listbox_end();
 	
-	RECT refresh_rect, play_rect;
-	ui_vsplit_r(&buttonbar, 250.0f, &buttonbar, &refresh_rect);
-	ui_vsplit_r(&refresh_rect, 130.0f, &refresh_rect, &play_rect);
-	ui_vsplit_r(&play_rect, 120.0f, 0x0, &play_rect);
+	CUIRect refresh_rect, play_rect;
+	buttonbar.VSplitRight(250.0f, &buttonbar, &refresh_rect);
+	refresh_rect.VSplitRight(130.0f, &refresh_rect, &play_rect);
+	play_rect.VSplitRight(120.0f, 0x0, &play_rect);
 	
 	static int refresh_button = 0;
-	if(ui_do_button(&refresh_button, localize("Refresh"), 0, &refresh_rect, ui_draw_menu_button, 0))
+	if(DoButton_Menu(&refresh_button, localize("Refresh"), 0, &refresh_rect))
 	{
 		demolist_populate();
 	}	
 	
 	static int play_button = 0;
-	if(ui_do_button(&play_button, localize("Play"), 0, &play_rect, ui_draw_menu_button, 0))
+	if(DoButton_Menu(&play_button, localize("Play"), 0, &play_rect))
 	{
 		if(selected_item >= 0 && selected_item < demos.size())
 		{
diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp
index 83673631..d31a15bd 100644
--- a/src/game/client/components/menus_ingame.cpp
+++ b/src/game/client/components/menus_ingame.cpp
@@ -17,30 +17,30 @@
 #include "motd.hpp"
 #include "voting.hpp"
 
-void MENUS::render_game(RECT main_view)
+void MENUS::render_game(CUIRect main_view)
 {
-	RECT button;
-	//RECT votearea;
-	ui_hsplit_t(&main_view, 45.0f, &main_view, 0);
-	ui_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f);
-
-	ui_hsplit_t(&main_view, 10.0f, 0, &main_view);
-	ui_hsplit_t(&main_view, 25.0f, &main_view, 0);
-	ui_vmargin(&main_view, 10.0f, &main_view);
+	CUIRect button;
+	//CUIRect votearea;
+	main_view.HSplitTop(45.0f, &main_view, 0);
+	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
+
+	main_view.HSplitTop(10.0f, 0, &main_view);
+	main_view.HSplitTop(25.0f, &main_view, 0);
+	main_view.VMargin(10.0f, &main_view);
 	
-	ui_vsplit_r(&main_view, 120.0f, &main_view, &button);
+	main_view.VSplitRight(120.0f, &main_view, &button);
 	static int disconnect_button = 0;
-	if(ui_do_button(&disconnect_button, localize("Disconnect"), 0, &button, ui_draw_menu_button, 0))
+	if(DoButton_Menu(&disconnect_button, localize("Disconnect"), 0, &button))
 		client_disconnect();
 
 	if(gameclient.snap.local_info && gameclient.snap.gameobj)
 	{
 		if(gameclient.snap.local_info->team != -1)
 		{
-			ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
-			ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
+			main_view.VSplitLeft(10.0f, &button, &main_view);
+			main_view.VSplitLeft(120.0f, &button, &main_view);
 			static int spectate_button = 0;
-			if(ui_do_button(&spectate_button, localize("Spectate"), 0, &button, ui_draw_menu_button, 0))
+			if(DoButton_Menu(&spectate_button, localize("Spectate"), 0, &button))
 			{
 				gameclient.send_switch_team(-1);
 				set_active(false);
@@ -51,10 +51,10 @@ void MENUS::render_game(RECT main_view)
 		{
 			if(gameclient.snap.local_info->team != 0)
 			{
-				ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
-				ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
+				main_view.VSplitLeft(10.0f, &button, &main_view);
+				main_view.VSplitLeft(120.0f, &button, &main_view);
 				static int spectate_button = 0;
-				if(ui_do_button(&spectate_button, localize("Join red"), 0, &button, ui_draw_menu_button, 0))
+				if(DoButton_Menu(&spectate_button, localize("Join red"), 0, &button))
 				{
 					gameclient.send_switch_team(0);
 					set_active(false);
@@ -63,10 +63,10 @@ void MENUS::render_game(RECT main_view)
 
 			if(gameclient.snap.local_info->team != 1)
 			{
-				ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
-				ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
+				main_view.VSplitLeft(10.0f, &button, &main_view);
+				main_view.VSplitLeft(120.0f, &button, &main_view);
 				static int spectate_button = 0;
-				if(ui_do_button(&spectate_button, localize("Join blue"), 0, &button, ui_draw_menu_button, 0))
+				if(DoButton_Menu(&spectate_button, localize("Join blue"), 0, &button))
 				{
 					gameclient.send_switch_team(1);
 					set_active(false);
@@ -77,10 +77,10 @@ void MENUS::render_game(RECT main_view)
 		{
 			if(gameclient.snap.local_info->team != 0)
 			{
-				ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
-				ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
+				main_view.VSplitLeft(10.0f, &button, &main_view);
+				main_view.VSplitLeft(120.0f, &button, &main_view);
 				static int spectate_button = 0;
-				if(ui_do_button(&spectate_button, localize("Join game"), 0, &button, ui_draw_menu_button, 0))
+				if(DoButton_Menu(&spectate_button, localize("Join game"), 0, &button))
 				{
 					gameclient.send_switch_team(0);
 					set_active(false);
@@ -90,58 +90,58 @@ void MENUS::render_game(RECT main_view)
 	}
 	
 	/*
-	RECT bars;
-	ui_hsplit_t(&votearea, 10.0f, 0, &votearea);
-	ui_hsplit_t(&votearea, 25.0f + 10.0f*3 + 25.0f, &votearea, &bars);
+	CUIRect bars;
+	votearea.HSplitTop(10.0f, 0, &votearea);
+	votearea.HSplitTop(25.0f + 10.0f*3 + 25.0f, &votearea, &bars);
 
-	ui_draw_rect(&votearea, color_tabbar_active, CORNER_ALL, 10.0f);
+	RenderTools()->DrawUIRect(&votearea, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
 
-	ui_vmargin(&votearea, 20.0f, &votearea);
-	ui_hmargin(&votearea, 10.0f, &votearea);
+	votearea.VMargin(20.0f, &votearea);
+	votearea.HMargin(10.0f, &votearea);
 
-	ui_hsplit_b(&votearea, 35.0f, &votearea, &bars);
+	votearea.HSplitBottom(35.0f, &votearea, &bars);
 
 	if(gameclient.voting->is_voting())
 	{
 		// do yes button
-		ui_vsplit_l(&votearea, 50.0f, &button, &votearea);
+		votearea.VSplitLeft(50.0f, &button, &votearea);
 		static int yes_button = 0;
-		if(ui_do_button(&yes_button, "Yes", 0, &button, ui_draw_menu_button, 0))
+		if(UI()->DoButton(&yes_button, "Yes", 0, &button, ui_draw_menu_button, 0))
 			gameclient.voting->vote(1);
 
 		// do no button
-		ui_vsplit_l(&votearea, 5.0f, 0, &votearea);
-		ui_vsplit_l(&votearea, 50.0f, &button, &votearea);
+		votearea.VSplitLeft(5.0f, 0, &votearea);
+		votearea.VSplitLeft(50.0f, &button, &votearea);
 		static int no_button = 0;
-		if(ui_do_button(&no_button, "No", 0, &button, ui_draw_menu_button, 0))
+		if(UI()->DoButton(&no_button, "No", 0, &button, ui_draw_menu_button, 0))
 			gameclient.voting->vote(-1);
 		
 		// do time left
-		ui_vsplit_r(&votearea, 50.0f, &votearea, &button);
+		votearea.VSplitRight(50.0f, &votearea, &button);
 		char buf[256];
 		str_format(buf, sizeof(buf), "%d", gameclient.voting->seconds_left());
-		ui_do_label(&button, buf, 24.0f, 0);
+		UI()->DoLabel(&button, buf, 24.0f, 0);
 
 		// do description and command
-		ui_vsplit_l(&votearea, 5.0f, 0, &votearea);
-		ui_do_label(&votearea, gameclient.voting->vote_description(), 14.0f, -1);
-		ui_hsplit_t(&votearea, 16.0f, 0, &votearea);
-		ui_do_label(&votearea, gameclient.voting->vote_command(), 10.0f, -1);
+		votearea.VSplitLeft(5.0f, 0, &votearea);
+		UI()->DoLabel(&votearea, gameclient.voting->vote_description(), 14.0f, -1);
+		votearea.HSplitTop(16.0f, 0, &votearea);
+		UI()->DoLabel(&votearea, gameclient.voting->vote_command(), 10.0f, -1);
 
 		// do bars
-		ui_hsplit_t(&bars, 10.0f, 0, &bars);
-		ui_hmargin(&bars, 5.0f, &bars);
+		bars.HSplitTop(10.0f, 0, &bars);
+		bars.HMargin(5.0f, &bars);
 		
 		gameclient.voting->render_bars(bars, true);
 
 	}		
 	else
 	{
-		ui_do_label(&votearea, "No vote in progress", 18.0f, -1);
+		UI()->DoLabel(&votearea, "No vote in progress", 18.0f, -1);
 	}*/
 }
 
-void MENUS::render_serverinfo(RECT main_view)
+void MENUS::render_serverinfo(CUIRect main_view)
 {
 	// fetch server info
 	SERVER_INFO current_server_info;
@@ -164,9 +164,9 @@ void MENUS::render_serverinfo(RECT main_view)
 	}
 
 	// render background
-	ui_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f);
+	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
 	
-	RECT view, serverinfo, gameinfo, motd;
+	CUIRect view, serverinfo, gameinfo, motd;
 	
 	float x = 0.0f;
 	float y = 0.0f;
@@ -174,14 +174,14 @@ void MENUS::render_serverinfo(RECT main_view)
 	char buf[1024];
 	
 	// set view to use for all sub-modules
-	ui_margin(&main_view, 10.0f, &view);
+	main_view.Margin(10.0f, &view);
 	
 	/* serverinfo */
-	ui_hsplit_t(&view, view.h/2-5.0f, &serverinfo, &motd);
-	ui_vsplit_l(&serverinfo, view.w/2-5.0f, &serverinfo, &gameinfo);
-	ui_draw_rect(&serverinfo, vec4(1,1,1,0.25f), CORNER_ALL, 10.0f);
+	view.HSplitTop(view.h/2-5.0f, &serverinfo, &motd);
+	serverinfo.VSplitLeft(view.w/2-5.0f, &serverinfo, &gameinfo);
+	RenderTools()->DrawUIRect(&serverinfo, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
 	
-	ui_margin(&serverinfo, 5.0f, &serverinfo);
+	serverinfo.Margin(5.0f, &serverinfo);
 	
 	x = 5.0f;
 	y = 0.0f;
@@ -208,11 +208,11 @@ void MENUS::render_serverinfo(RECT main_view)
 	gfx_text(0, serverinfo.x+x, serverinfo.y+y, 20, buf, 250);
 	
 	{
-		RECT button;
+		CUIRect button;
 		int is_favorite = client_serverbrowse_isfavorite(current_server_info.netaddr);
-		ui_hsplit_b(&serverinfo, 20.0f, &serverinfo, &button);
+		serverinfo.HSplitBottom(20.0f, &serverinfo, &button);
 		static int add_fav_button = 0;
-		if (ui_do_button(&add_fav_button, localize("Favorite"), is_favorite, &button, ui_draw_checkbox, 0))
+		if(DoButton_CheckBox(&add_fav_button, localize("Favorite"), is_favorite, &button))
 		{
 			if(is_favorite)
 				client_serverbrowse_removefavorite(current_server_info.netaddr);
@@ -222,10 +222,10 @@ void MENUS::render_serverinfo(RECT main_view)
 	}
 	
 	/* gameinfo */
-	ui_vsplit_l(&gameinfo, 10.0f, 0x0, &gameinfo);
-	ui_draw_rect(&gameinfo, vec4(1,1,1,0.25f), CORNER_ALL, 10.0f);
+	gameinfo.VSplitLeft(10.0f, 0x0, &gameinfo);
+	RenderTools()->DrawUIRect(&gameinfo, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
 	
-	ui_margin(&gameinfo, 5.0f, &gameinfo);
+	gameinfo.Margin(5.0f, &gameinfo);
 	
 	x = 5.0f;
 	y = 0.0f;
@@ -253,9 +253,9 @@ void MENUS::render_serverinfo(RECT main_view)
 	gfx_text(0, gameinfo.x+x, gameinfo.y+y, 20, buf, 250);
 	
 	/* motd */
-	ui_hsplit_t(&motd, 10.0f, 0, &motd);
-	ui_draw_rect(&motd, vec4(1,1,1,0.25f), CORNER_ALL, 10.0f);
-	ui_margin(&motd, 5.0f, &motd);
+	motd.HSplitTop(10.0f, 0, &motd);
+	RenderTools()->DrawUIRect(&motd, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+	motd.Margin(5.0f, &motd);
 	y = 0.0f;
 	x = 5.0f;
 	gfx_text(0, motd.x+x, motd.y+y, 32, localize("MOTD"), -1);
@@ -268,14 +268,14 @@ static const char *format_command(const char *cmd)
 	return cmd;
 }
 
-void MENUS::render_servercontrol_server(RECT main_view)
+void MENUS::render_servercontrol_server(CUIRect main_view)
 {
 	int num_options = 0;
 	for(VOTING::VOTEOPTION *option = gameclient.voting->first; option; option = option->next)
 		num_options++;
 
 	static int votelist = 0;
-	RECT list = main_view;
+	CUIRect list = main_view;
 	ui_do_listbox_start(&votelist, &list, 24.0f, localize("Settings"), num_options, callvote_selectedoption);
 	
 	for(VOTING::VOTEOPTION *option = gameclient.voting->first; option; option = option->next)
@@ -283,62 +283,62 @@ void MENUS::render_servercontrol_server(RECT main_view)
 		LISTBOXITEM item = ui_do_listbox_nextitem(option);
 		
 		if(item.visible)
-			ui_do_label(&item.rect, format_command(option->command), 16.0f, -1);
+			UI()->DoLabel(&item.rect, format_command(option->command), 16.0f, -1);
 	}
 	
 	callvote_selectedoption = ui_do_listbox_end();
 }
 
-void MENUS::render_servercontrol_kick(RECT main_view)
+void MENUS::render_servercontrol_kick(CUIRect main_view)
 {
 	// draw header
-	RECT header, footer;
-	ui_hsplit_t(&main_view, 20, &header, &main_view);
-	ui_draw_rect(&header, vec4(1,1,1,0.25f), CORNER_T, 5.0f); 
-	ui_do_label(&header, localize("Players"), 18.0f, 0);
+	CUIRect header, footer;
+	main_view.HSplitTop(20, &header, &main_view);
+	RenderTools()->DrawUIRect(&header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); 
+	UI()->DoLabel(&header, localize("Players"), 18.0f, 0);
 
 	// draw footers	
-	ui_hsplit_b(&main_view, 20, &main_view, &footer);
-	ui_draw_rect(&footer, vec4(1,1,1,0.25f), CORNER_B, 5.0f); 
-	ui_vsplit_l(&footer, 10.0f, 0, &footer);
+	main_view.HSplitBottom(20, &main_view, &footer);
+	RenderTools()->DrawUIRect(&footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); 
+	footer.VSplitLeft(10.0f, 0, &footer);
 
 	// players
-	ui_draw_rect(&main_view, vec4(0,0,0,0.15f), 0, 0);
-	RECT list = main_view;
+	RenderTools()->DrawUIRect(&main_view, vec4(0,0,0,0.15f), 0, 0);
+	CUIRect list = main_view;
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
 		if(!gameclient.snap.player_infos[i])
 			continue;
 
-		RECT button;
-		ui_hsplit_t(&list, button_height, &button, &list);
+		CUIRect button;
+		list.HSplitTop(button_height, &button, &list);
 		
-		if(ui_do_button((char *)&gameclient.snap+i, "", callvote_selectedplayer == i, &button, ui_draw_list_row, 0))
+		if(DoButton_ListRow((char *)&gameclient.snap+i, "", callvote_selectedplayer == i, &button))
 			callvote_selectedplayer = i;
 
 		TEE_RENDER_INFO info = gameclient.clients[i].render_info;
 		info.size = button.h;
-		render_tee(ANIMSTATE::get_idle(), &info, EMOTE_NORMAL, vec2(1,0), vec2(button.x+button.h/2, button.y+button.h/2));
+		RenderTools()->RenderTee(ANIMSTATE::get_idle(), &info, EMOTE_NORMAL, vec2(1,0), vec2(button.x+button.h/2, button.y+button.h/2));
 
 		button.x += button.h;
-		ui_do_label(&button, gameclient.clients[i].name, 18.0f, -1);
+		UI()->DoLabel(&button, gameclient.clients[i].name, 18.0f, -1);
 	}
 }
 
-void MENUS::render_servercontrol(RECT main_view)
+void MENUS::render_servercontrol(CUIRect main_view)
 {
 	static int control_page = 0;
 	
 	// render background
-	RECT temp, tabbar;
-	ui_vsplit_r(&main_view, 120.0f, &main_view, &tabbar);
-	ui_draw_rect(&main_view, color_tabbar_active, CORNER_B|CORNER_TL, 10.0f);
-	ui_hsplit_t(&tabbar, 50.0f, &temp, &tabbar);
-	ui_draw_rect(&temp, color_tabbar_active, CORNER_R, 10.0f);
+	CUIRect temp, tabbar;
+	main_view.VSplitRight(120.0f, &main_view, &tabbar);
+	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_B|CUI::CORNER_TL, 10.0f);
+	tabbar.HSplitTop(50.0f, &temp, &tabbar);
+	RenderTools()->DrawUIRect(&temp, color_tabbar_active, CUI::CORNER_R, 10.0f);
 	
-	ui_hsplit_t(&main_view, 10.0f, 0, &main_view);
+	main_view.HSplitTop(10.0f, 0, &main_view);
 	
-	RECT button;
+	CUIRect button;
 	
 	const char *tabs[] = {
 		localize("Settings"),
@@ -347,9 +347,9 @@ void MENUS::render_servercontrol(RECT main_view)
 	
 	for(int i = 0; i < num_tabs; i++)
 	{
-		ui_hsplit_t(&tabbar, 10, &button, &tabbar);
-		ui_hsplit_t(&tabbar, 26, &button, &tabbar);
-		if(ui_do_button(tabs[i], tabs[i], control_page == i, &button, ui_draw_settings_tab_button, 0))
+		tabbar.HSplitTop(10, &button, &tabbar);
+		tabbar.HSplitTop(26, &button, &tabbar);
+		if(DoButton_SettingsTab(tabs[i], tabs[i], control_page == i, &button))
 		{
 			control_page = i;
 			callvote_selectedplayer = -1;
@@ -357,10 +357,10 @@ void MENUS::render_servercontrol(RECT main_view)
 		}
 	}
 		
-	ui_margin(&main_view, 10.0f, &main_view);
-	RECT bottom;
-	ui_hsplit_b(&main_view, button_height + 5*2, &main_view, &bottom);
-	ui_hmargin(&bottom, 5.0f, &bottom);
+	main_view.Margin(10.0f, &main_view);
+	CUIRect bottom;
+	main_view.HSplitBottom(button_height + 5*2, &main_view, &bottom);
+	bottom.HMargin(5.0f, &bottom);
 	
 	// render page		
 	if(control_page == 0)
@@ -370,11 +370,11 @@ void MENUS::render_servercontrol(RECT main_view)
 		
 
 	{
-		RECT button;
-		ui_vsplit_r(&bottom, 120.0f, &bottom, &button);
+		CUIRect button;
+		bottom.VSplitRight(120.0f, &bottom, &button);
 		
 		static int callvote_button = 0;
-		if(ui_do_button(&callvote_button, localize("Call vote"), 0, &button, ui_draw_menu_button, 0))
+		if(DoButton_Menu(&callvote_button, localize("Call vote"), 0, &button))
 		{
 			if(control_page == 0)
 			{
diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp
index 86325ab9..05b4d047 100644
--- a/src/game/client/components/menus_settings.cpp
+++ b/src/game/client/components/menus_settings.cpp
@@ -5,6 +5,7 @@
 #include <stdlib.h> // atoi
 
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
@@ -43,33 +44,31 @@ bool MENUS_KEYBINDER::on_input(INPUT_EVENT e)
 	return false;
 }
 
-void MENUS::render_settings_player(RECT main_view)
+void MENUS::render_settings_player(CUIRect main_view)
 {
-	RECT button;
-	RECT skinselection;
-	ui_vsplit_l(&main_view, 300.0f, &main_view, &skinselection);
-
-
-	ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
+	CUIRect button;
+	CUIRect othersection;
+	main_view.VSplitLeft(300.0f, &main_view, &othersection);
+	main_view.HSplitTop(20.0f, &button, &main_view);
 
 	// render settings
 	{	
 		char buf[128];
 		
-		ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
+		main_view.HSplitTop(20.0f, &button, &main_view);
 		str_format(buf, sizeof(buf), "%s:", localize("Name"));
-		ui_do_label(&button, buf, 14.0, -1);
-		ui_vsplit_l(&button, 80.0f, 0, &button);
-		ui_vsplit_l(&button, 180.0f, &button, 0);
-		if(ui_do_edit_box(config.player_name, &button, config.player_name, sizeof(config.player_name), 14.0f))
+		UI()->DoLabel(&button, buf, 14.0, -1);
+		button.VSplitLeft(80.0f, 0, &button);
+		button.VSplitLeft(180.0f, &button, 0);
+		if(DoEditBox(config.player_name, &button, config.player_name, sizeof(config.player_name), 14.0f))
 			need_sendinfo = true;
 
 		// extra spacing
-		ui_hsplit_t(&main_view, 10.0f, 0, &main_view);
+		main_view.HSplitTop(10.0f, 0, &main_view);
 
 		static int dynamic_camera_button = 0;
-		ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-		if(ui_do_button(&dynamic_camera_button, localize("Dynamic Camera"), config.cl_mouse_deadzone != 0, &button, ui_draw_checkbox, 0))
+		main_view.HSplitTop(20.0f, &button, &main_view);
+		if(DoButton_CheckBox(&dynamic_camera_button, localize("Dynamic Camera"), config.cl_mouse_deadzone != 0, &button))
 		{
 			
 			if(config.cl_mouse_deadzone)
@@ -86,26 +85,26 @@ void MENUS::render_settings_player(RECT main_view)
 			}
 		}
 
-		ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-		if (ui_do_button(&config.cl_autoswitch_weapons, localize("Switch weapon on pickup"), config.cl_autoswitch_weapons, &button, ui_draw_checkbox, 0))
+		main_view.HSplitTop(20.0f, &button, &main_view);
+		if(DoButton_CheckBox(&config.cl_autoswitch_weapons, localize("Switch weapon on pickup"), config.cl_autoswitch_weapons, &button))
 			config.cl_autoswitch_weapons ^= 1;
 			
-		ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-		if (ui_do_button(&config.cl_nameplates, localize("Show name plates"), config.cl_nameplates, &button, ui_draw_checkbox, 0))
+		main_view.HSplitTop(20.0f, &button, &main_view);
+		if(DoButton_CheckBox(&config.cl_nameplates, localize("Show name plates"), config.cl_nameplates, &button))
 			config.cl_nameplates ^= 1;
 
 		//if(config.cl_nameplates)
 		{
-			ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-			ui_vsplit_l(&button, 15.0f, 0, &button);
-			if (ui_do_button(&config.cl_nameplates_always, localize("Always show name plates"), config.cl_nameplates_always, &button, ui_draw_checkbox, 0))
+			main_view.HSplitTop(20.0f, &button, &main_view);
+			button.VSplitLeft(15.0f, 0, &button);
+			if(DoButton_CheckBox(&config.cl_nameplates_always, localize("Always show name plates"), config.cl_nameplates_always, &button))
 				config.cl_nameplates_always ^= 1;
 		}
 			
-		ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
+		main_view.HSplitTop(20.0f, &button, &main_view);
 		
-		ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-		if (ui_do_button(&config.player_color_body, localize("Custom colors"), config.player_use_custom_color, &button, ui_draw_checkbox, 0))
+		main_view.HSplitTop(20.0f, &button, &main_view);
+		if(DoButton_CheckBox(&config.player_color_body, localize("Custom colors"), config.player_use_custom_color, &button))
 		{
 			config.player_use_custom_color = config.player_use_custom_color?0:1;
 			need_sendinfo = true;
@@ -129,27 +128,27 @@ void MENUS::render_settings_player(RECT main_view)
 				
 			for(int i = 0; i < 2; i++)
 			{
-				RECT text;
-				ui_hsplit_t(&main_view, 20.0f, &text, &main_view);
-				ui_vsplit_l(&text, 15.0f, 0, &text);
-				ui_do_label(&text, parts[i], 14.0f, -1);
+				CUIRect text;
+				main_view.HSplitTop(20.0f, &text, &main_view);
+				text.VSplitLeft(15.0f, 0, &text);
+				UI()->DoLabel(&text, parts[i], 14.0f, -1);
 				
 				int prevcolor = *colors[i];
 				int color = 0;
 				for(int s = 0; s < 3; s++)
 				{
-					RECT text;
-					ui_hsplit_t(&main_view, 19.0f, &button, &main_view);
-					ui_vsplit_l(&button, 30.0f, 0, &button);
-					ui_vsplit_l(&button, 70.0f, &text, &button);
-					ui_vsplit_r(&button, 5.0f, &button, 0);
-					ui_hsplit_t(&button, 4.0f, 0, &button);
+					CUIRect text;
+					main_view.HSplitTop(19.0f, &button, &main_view);
+					button.VSplitLeft(30.0f, 0, &button);
+					button.VSplitLeft(70.0f, &text, &button);
+					button.VSplitRight(5.0f, &button, 0);
+					button.HSplitTop(4.0f, 0, &button);
 					
 					float k = ((prevcolor>>((2-s)*8))&0xff)  / 255.0f;
-					k = ui_do_scrollbar_h(&color_slider[i][s], &button, k);
+					k = DoScrollbarH(&color_slider[i][s], &button, k);
 					color <<= 8;
 					color += clamp((int)(k*255), 0, 255);
-					ui_do_label(&text, labels[s], 15.0f, -1);
+					UI()->DoLabel(&text, labels[s], 15.0f, -1);
 					 
 				}
 		
@@ -157,35 +156,103 @@ void MENUS::render_settings_player(RECT main_view)
 					need_sendinfo = true;
 					
 				*colors[i] = color;
-				ui_hsplit_t(&main_view, 5.0f, 0, &main_view);
+				main_view.HSplitTop(5.0f, 0, &main_view);
 			}
 		}
+		
+		// render skinselector
+		static int skinselector_id = 0;		
+		ui_do_listbox_start(&skinselector_id, &main_view, 50, localize("Skins"), (gameclient.skins->num()+3)/4, 0);
+
+		for(int skin_id = 0; skin_id < gameclient.skins->num(); )
+		{
+			LISTBOXITEM item = ui_do_listbox_nextrow();
+			CUIRect boxes[4];
+			CUIRect first_half, second_half;
+			item.rect.VSplitMid(&first_half, &second_half);
+			first_half.VSplitMid(&boxes[0], &boxes[1]);
+			second_half.VSplitMid(&boxes[2], &boxes[3]);
+			
+			for(int i = 0; i < 4 && skin_id < gameclient.skins->num(); i++, skin_id++)
+			{
+				//CUIRect r = item.
+				const SKINS::SKIN *s = gameclient.skins->get(skin_id);
+
+				TEE_RENDER_INFO info;
+				info.texture = s->org_texture;
+				info.color_body = vec4(1,1,1,1);
+				info.color_feet = vec4(1,1,1,1);
+				if(config.player_use_custom_color)
+				{
+					info.color_body = gameclient.skins->get_color(config.player_color_body);
+					info.color_feet = gameclient.skins->get_color(config.player_color_feet);
+					info.texture = s->color_texture;
+				}
+					
+				info.size = UI()->Scale()*50.0f;
+				
+				CUIRect icon = boxes[i]; //item.rect;
+				//button.VSplitLeft(50.0f, &icon, &text);
+				
+				/*if(UI()->DoButton(s, "", selected, &button, ui_draw_list_row, 0))
+				{
+					config_set_player_skin(&config, s->name);
+					need_sendinfo = true;
+				}*/
+
+				//text.HSplitTop(12.0f, 0, &text); // some margin from the top
+				//UI()->DoLabel(&text, buf, 18.0f, 0);
+				
+				icon.HSplitTop(5.0f, 0, &icon); // some margin from the top
+				RenderTools()->RenderTee(ANIMSTATE::get_idle(), &info, 0, vec2(1, 0), vec2(icon.x+icon.w/2, icon.y+icon.h/2));
+				
+				if(config.debug)
+				{
+					Graphics()->TextureSet(-1);
+					Graphics()->QuadsBegin();
+					Graphics()->SetColor(s->blood_color.r, s->blood_color.g, s->blood_color.b, 1.0f);
+					Graphics()->QuadsDrawTL(icon.x, icon.y, 12, 12);
+					Graphics()->QuadsEnd();
+				}
+			}
+		}
+		
+		int new_selection = ui_do_listbox_end();
+		(void)new_selection;
+		//main_view
+	}
+	
+	// render skinselector
+	/*
+	{
+		
+		//othersection
 	}
 		
 	// draw header
-	RECT header, footer;
-	ui_hsplit_t(&skinselection, 20, &header, &skinselection);
-	ui_draw_rect(&header, vec4(1,1,1,0.25f), CORNER_T, 5.0f); 
-	ui_do_label(&header, localize("Skins"), 18.0f, 0);
+	CUIRect header, footer;
+	skinselection.HSplitTop(20, &header, &skinselection);
+	RenderTools()->DrawUIRect(&header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); 
+	UI()->DoLabel(&header, localize("Skins"), 18.0f, 0);
 
 	// draw footers	
-	ui_hsplit_b(&skinselection, 20, &skinselection, &footer);
-	ui_draw_rect(&footer, vec4(1,1,1,0.25f), CORNER_B, 5.0f); 
-	ui_vsplit_l(&footer, 10.0f, 0, &footer);
+	skinselection.HSplitBottom(20, &skinselection, &footer);
+	RenderTools()->DrawUIRect(&footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); 
+	footer.VSplitLeft(10.0f, 0, &footer);
 
 	// modes
-	ui_draw_rect(&skinselection, vec4(0,0,0,0.15f), 0, 0);
+	RenderTools()->DrawUIRect(&skinselection, vec4(0,0,0,0.15f), 0, 0);
 
-	RECT scroll;
-	ui_vsplit_r(&skinselection, 15, &skinselection, &scroll);
+	CUIRect scroll;
+	skinselection.VSplitRight(15, &skinselection, &scroll);
 
-	RECT list = skinselection;
-	ui_hsplit_t(&list, 50, &button, &list);
+	CUIRect list = skinselection;
+	list.HSplitTop(50, &button, &list);
 	
 	int num = (int)(skinselection.h/button.h);
 	static float scrollvalue = 0;
 	static int scrollbar = 0;
-	ui_hmargin(&scroll, 5.0f, &scroll);
+	scroll.HMargin(5.0f, &scroll);
 	scrollvalue = ui_do_scrollbar_v(&scrollbar, &scroll, scrollvalue);
 
 	int start = (int)((gameclient.skins->num()-num)*scrollvalue);
@@ -220,35 +287,35 @@ void MENUS::render_settings_player(RECT main_view)
 			info.texture = s->color_texture;
 		}
 			
-		info.size = ui_scale()*50.0f;
+		info.size = UI()->Scale()*50.0f;
 		
-		RECT icon;
-		RECT text;
-		ui_vsplit_l(&button, 50.0f, &icon, &text);
+		CUIRect icon;
+		CUIRect text;
+		button.VSplitLeft(50.0f, &icon, &text);
 		
-		if(ui_do_button(s, "", selected, &button, ui_draw_list_row, 0))
+		if(UI()->DoButton(s, "", selected, &button, ui_draw_list_row, 0))
 		{
 			config_set_player_skin(&config, s->name);
 			need_sendinfo = true;
 		}
 
-		ui_hsplit_t(&text, 12.0f, 0, &text); // some margin from the top
-		ui_do_label(&text, buf, 18.0f, 0);
+		text.HSplitTop(12.0f, 0, &text); // some margin from the top
+		UI()->DoLabel(&text, buf, 18.0f, 0);
 		
-		ui_hsplit_t(&icon, 5.0f, 0, &icon); // some margin from the top
-		render_tee(ANIMSTATE::get_idle(), &info, 0, vec2(1, 0), vec2(icon.x+icon.w/2, icon.y+icon.h/2));
+		icon.HSplitTop(5.0f, 0, &icon); // some margin from the top
+		RenderTools()->RenderTee(ANIMSTATE::get_idle(), &info, 0, vec2(1, 0), vec2(icon.x+icon.w/2, icon.y+icon.h/2));
 		
 		if(config.debug)
 		{
-			gfx_texture_set(-1);
-			gfx_quads_begin();
-			gfx_setcolor(s->blood_color.r, s->blood_color.g, s->blood_color.b, 1.0f);
-			gfx_quads_drawTL(icon.x, icon.y, 12, 12);
-			gfx_quads_end();
+			Graphics()->TextureSet(-1);
+			Graphics()->QuadsBegin();
+			Graphics()->SetColor(s->blood_color.r, s->blood_color.g, s->blood_color.b, 1.0f);
+			Graphics()->QuadsDrawTL(icon.x, icon.y, 12, 12);
+			Graphics()->QuadsEnd();
 		}
 		
-		ui_hsplit_t(&list, 50, &button, &list);
-	}
+		list.HSplitTop(50, &button, &list);
+	}*/
 }
 
 typedef void (*assign_func_callback)(CONFIGURATION *config, int value);
@@ -288,31 +355,31 @@ static KEYINFO keys[] =
 
 const int key_count = sizeof(keys) / sizeof(KEYINFO);
 
-void MENUS::ui_do_getbuttons(int start, int stop, RECT view)
+void MENUS::ui_do_getbuttons(int start, int stop, CUIRect view)
 {
 	for (int i = start; i < stop; i++)
 	{
 		KEYINFO &key = keys[i];
-		RECT button, label;
-		ui_hsplit_t(&view, 20.0f, &button, &view);
-		ui_vsplit_l(&button, 130.0f, &label, &button);
+		CUIRect button, label;
+		view.HSplitTop(20.0f, &button, &view);
+		button.VSplitLeft(130.0f, &label, &button);
 	
 		char buf[64];
 		str_format(buf, sizeof(buf), "%s:", (const char *)key.name);
 		
-		ui_do_label(&label, key.name, 14.0f, -1);
+		UI()->DoLabel(&label, key.name, 14.0f, -1);
 		int oldid = key.keyid;
-		int newid = ui_do_key_reader((void *)&keys[i].name, &button, oldid);
+		int newid = DoKeyReader((void *)&keys[i].name, &button, oldid);
 		if(newid != oldid)
 		{
 			gameclient.binds->bind(oldid, "");
 			gameclient.binds->bind(newid, keys[i].command);
 		}
-		ui_hsplit_t(&view, 5.0f, 0, &view);
+		view.HSplitTop(5.0f, 0, &view);
 	}
 }
 
-void MENUS::render_settings_controls(RECT main_view)
+void MENUS::render_settings_controls(CUIRect main_view)
 {
 	// this is kinda slow, but whatever
 	for(int i = 0; i < key_count; i++)
@@ -332,28 +399,28 @@ void MENUS::render_settings_controls(RECT main_view)
 			}
 	}
 
-	RECT movement_settings, weapon_settings, voting_settings, chat_settings, misc_settings, reset_button;
-	ui_vsplit_l(&main_view, main_view.w/2-5.0f, &movement_settings, &voting_settings);
+	CUIRect movement_settings, weapon_settings, voting_settings, chat_settings, misc_settings, reset_button;
+	main_view.VSplitLeft(main_view.w/2-5.0f, &movement_settings, &voting_settings);
 	
 	/* movement settings */
 	{
-		ui_hsplit_t(&movement_settings, main_view.h/2-5.0f, &movement_settings, &weapon_settings);
-		ui_draw_rect(&movement_settings, vec4(1,1,1,0.25f), CORNER_ALL, 10.0f);
-		ui_margin(&movement_settings, 10.0f, &movement_settings);
+		movement_settings.HSplitTop(main_view.h/2-5.0f, &movement_settings, &weapon_settings);
+		RenderTools()->DrawUIRect(&movement_settings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+		movement_settings.Margin(10.0f, &movement_settings);
 		
 		gfx_text(0, movement_settings.x, movement_settings.y, 14, localize("Movement"), -1);
 		
-		ui_hsplit_t(&movement_settings, 14.0f+5.0f+10.0f, 0, &movement_settings);
+		movement_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &movement_settings);
 		
 		{
-			RECT button, label;
-			ui_hsplit_t(&movement_settings, 20.0f, &button, &movement_settings);
-			ui_vsplit_l(&button, 130.0f, &label, &button);
-			ui_do_label(&label, localize("Mouse sens."), 14.0f, -1);
-			ui_hmargin(&button, 2.0f, &button);
-			config.inp_mousesens = (int)(ui_do_scrollbar_h(&config.inp_mousesens, &button, (config.inp_mousesens-5)/500.0f)*500.0f)+5;
+			CUIRect button, label;
+			movement_settings.HSplitTop(20.0f, &button, &movement_settings);
+			button.VSplitLeft(130.0f, &label, &button);
+			UI()->DoLabel(&label, localize("Mouse sens."), 14.0f, -1);
+			button.HMargin(2.0f, &button);
+			config.inp_mousesens = (int)(DoScrollbarV(&config.inp_mousesens, &button, (config.inp_mousesens-5)/500.0f)*500.0f)+5;
 			//*key.key = ui_do_key_reader(key.key, &button, *key.key);
-			ui_hsplit_t(&movement_settings, 20.0f, 0, &movement_settings);
+			movement_settings.HSplitTop(20.0f, 0, &movement_settings);
 		}
 		
 		ui_do_getbuttons(0, 5, movement_settings);
@@ -362,65 +429,65 @@ void MENUS::render_settings_controls(RECT main_view)
 	
 	/* weapon settings */
 	{
-		ui_hsplit_t(&weapon_settings, 10.0f, 0, &weapon_settings);
-		ui_draw_rect(&weapon_settings, vec4(1,1,1,0.25f), CORNER_ALL, 10.0f);
-		ui_margin(&weapon_settings, 10.0f, &weapon_settings);
+		weapon_settings.HSplitTop(10.0f, 0, &weapon_settings);
+		RenderTools()->DrawUIRect(&weapon_settings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+		weapon_settings.Margin(10.0f, &weapon_settings);
 
 		gfx_text(0, weapon_settings.x, weapon_settings.y, 14, localize("Weapon"), -1);
 		
-		ui_hsplit_t(&weapon_settings, 14.0f+5.0f+10.0f, 0, &weapon_settings);
+		weapon_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &weapon_settings);
 		ui_do_getbuttons(5, 12, weapon_settings);
 	}
 	
 	/* voting settings */
 	{
-		ui_vsplit_l(&voting_settings, 10.0f, 0, &voting_settings);
-		ui_hsplit_t(&voting_settings, main_view.h/4-5.0f, &voting_settings, &chat_settings);
-		ui_draw_rect(&voting_settings, vec4(1,1,1,0.25f), CORNER_ALL, 10.0f);
-		ui_margin(&voting_settings, 10.0f, &voting_settings);
+		voting_settings.VSplitLeft(10.0f, 0, &voting_settings);
+		voting_settings.HSplitTop(main_view.h/4-5.0f, &voting_settings, &chat_settings);
+		RenderTools()->DrawUIRect(&voting_settings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+		voting_settings.Margin(10.0f, &voting_settings);
 	
 		gfx_text(0, voting_settings.x, voting_settings.y, 14, localize("Voting"), -1);
 		
-		ui_hsplit_t(&voting_settings, 14.0f+5.0f+10.0f, 0, &voting_settings);
+		voting_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &voting_settings);
 		ui_do_getbuttons(12, 14, voting_settings);
 	}
 	
 	/* chat settings */
 	{
-		ui_hsplit_t(&chat_settings, 10.0f, 0, &chat_settings);
-		ui_hsplit_t(&chat_settings, main_view.h/4-10.0f, &chat_settings, &misc_settings);
-		ui_draw_rect(&chat_settings, vec4(1,1,1,0.25f), CORNER_ALL, 10.0f);
-		ui_margin(&chat_settings, 10.0f, &chat_settings);
+		chat_settings.HSplitTop(10.0f, 0, &chat_settings);
+		chat_settings.HSplitTop(main_view.h/4-10.0f, &chat_settings, &misc_settings);
+		RenderTools()->DrawUIRect(&chat_settings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+		chat_settings.Margin(10.0f, &chat_settings);
 	
 		gfx_text(0, chat_settings.x, chat_settings.y, 14, localize("Chat"), -1);
 		
-		ui_hsplit_t(&chat_settings, 14.0f+5.0f+10.0f, 0, &chat_settings);
+		chat_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &chat_settings);
 		ui_do_getbuttons(14, 16, chat_settings);
 	}
 	
 	/* misc settings */
 	{
-		ui_hsplit_t(&misc_settings, 10.0f, 0, &misc_settings);
-		ui_hsplit_t(&misc_settings, main_view.h/2-5.0f-45.0f, &misc_settings, &reset_button);
-		ui_draw_rect(&misc_settings, vec4(1,1,1,0.25f), CORNER_ALL, 10.0f);
-		ui_margin(&misc_settings, 10.0f, &misc_settings);
+		misc_settings.HSplitTop(10.0f, 0, &misc_settings);
+		misc_settings.HSplitTop(main_view.h/2-5.0f-45.0f, &misc_settings, &reset_button);
+		RenderTools()->DrawUIRect(&misc_settings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+		misc_settings.Margin(10.0f, &misc_settings);
 	
 		gfx_text(0, misc_settings.x, misc_settings.y, 14, localize("Miscellaneous"), -1);
 		
-		ui_hsplit_t(&misc_settings, 14.0f+5.0f+10.0f, 0, &misc_settings);
+		misc_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &misc_settings);
 		ui_do_getbuttons(16, 21, misc_settings);
 	}
 	
 	// defaults
-	ui_hsplit_t(&reset_button, 10.0f, 0, &reset_button);
+	reset_button.HSplitTop(10.0f, 0, &reset_button);
 	static int default_button = 0;
-	if (ui_do_button((void*)&default_button, localize("Reset to defaults"), 0, &reset_button, ui_draw_menu_button, 0))
+	if(DoButton_Menu((void*)&default_button, localize("Reset to defaults"), 0, &reset_button))
 		gameclient.binds->set_defaults();
 }
 
-void MENUS::render_settings_graphics(RECT main_view)
+void MENUS::render_settings_graphics(CUIRect main_view)
 {
-	RECT button;
+	CUIRect button;
 	char buf[128];
 	
 	static const int MAX_RESOLUTIONS = 256;
@@ -430,44 +497,44 @@ void MENUS::render_settings_graphics(RECT main_view)
 	if(num_modes == -1)
 		num_modes = gfx_get_video_modes(modes, MAX_RESOLUTIONS);
 	
-	RECT modelist;
-	ui_vsplit_l(&main_view, 300.0f, &main_view, &modelist);
+	CUIRect modelist;
+	main_view.VSplitLeft(300.0f, &main_view, &modelist);
 	
 	// draw allmodes switch
-	RECT header, footer;
-	ui_hsplit_t(&modelist, 20, &button, &modelist);
-	if (ui_do_button(&config.gfx_display_all_modes, localize("Show only supported"), config.gfx_display_all_modes^1, &button, ui_draw_checkbox, 0))
+	CUIRect header, footer;
+	modelist.HSplitTop(20, &button, &modelist);
+	if(DoButton_CheckBox(&config.gfx_display_all_modes, localize("Show only supported"), config.gfx_display_all_modes^1, &button))
 	{
 		config.gfx_display_all_modes ^= 1;
 		num_modes = gfx_get_video_modes(modes, MAX_RESOLUTIONS);
 	}
 	
 	// draw header
-	ui_hsplit_t(&modelist, 20, &header, &modelist);
-	ui_draw_rect(&header, vec4(1,1,1,0.25f), CORNER_T, 5.0f); 
-	ui_do_label(&header, localize("Display Modes"), 14.0f, 0);
+	modelist.HSplitTop(20, &header, &modelist);
+	RenderTools()->DrawUIRect(&header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); 
+	UI()->DoLabel(&header, localize("Display Modes"), 14.0f, 0);
 
 	// draw footers	
-	ui_hsplit_b(&modelist, 20, &modelist, &footer);
+	modelist.HSplitBottom(20, &modelist, &footer);
 	str_format(buf, sizeof(buf), "%s: %dx%d %d bit", localize("Current"), config.gfx_screen_width, config.gfx_screen_height, config.gfx_color_depth);
-	ui_draw_rect(&footer, vec4(1,1,1,0.25f), CORNER_B, 5.0f); 
-	ui_vsplit_l(&footer, 10.0f, 0, &footer);
-	ui_do_label(&footer, buf, 14.0f, -1);
+	RenderTools()->DrawUIRect(&footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); 
+	footer.VSplitLeft(10.0f, 0, &footer);
+	UI()->DoLabel(&footer, buf, 14.0f, -1);
 
 	// modes
-	ui_draw_rect(&modelist, vec4(0,0,0,0.15f), 0, 0);
+	RenderTools()->DrawUIRect(&modelist, vec4(0,0,0,0.15f), 0, 0);
 
-	RECT scroll;
-	ui_vsplit_r(&modelist, 15, &modelist, &scroll);
+	CUIRect scroll;
+	modelist.VSplitRight(15, &modelist, &scroll);
 
-	RECT list = modelist;
-	ui_hsplit_t(&list, 20, &button, &list);
+	CUIRect list = modelist;
+	list.HSplitTop(20, &button, &list);
 	
 	int num = (int)(modelist.h/button.h);
 	static float scrollvalue = 0;
 	static int scrollbar = 0;
-	ui_hmargin(&scroll, 5.0f, &scroll);
-	scrollvalue = ui_do_scrollbar_v(&scrollbar, &scroll, scrollvalue);
+	scroll.HMargin(5.0f, &scroll);
+	scrollvalue = DoScrollbarV(&scrollbar, &scroll, scrollvalue);
 
 	int start = (int)((num_modes-num)*scrollvalue);
 	if(start < 0)
@@ -490,7 +557,7 @@ void MENUS::render_settings_graphics(RECT main_view)
 		}
 		
 		str_format(buf, sizeof(buf), "  %dx%d %d bit", modes[i].width, modes[i].height, depth);
-		if(ui_do_button(&modes[i], buf, selected, &button, ui_draw_list_row, 0))
+		if(DoButton_ListRow(&modes[i], buf, selected, &button))
 		{
 			config.gfx_color_depth = depth;
 			config.gfx_screen_width = modes[i].width;
@@ -499,58 +566,58 @@ void MENUS::render_settings_graphics(RECT main_view)
 				need_restart = true;
 		}
 		
-		ui_hsplit_t(&list, 20, &button, &list);
+		list.HSplitTop(20, &button, &list);
 	}
 	
 	
 	// switches
-	ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-	if (ui_do_button(&config.gfx_fullscreen, localize("Fullscreen"), config.gfx_fullscreen, &button, ui_draw_checkbox, 0))
+	main_view.HSplitTop(20.0f, &button, &main_view);
+	if(DoButton_CheckBox(&config.gfx_fullscreen, localize("Fullscreen"), config.gfx_fullscreen, &button))
 	{
 		config.gfx_fullscreen ^= 1;
 		need_restart = true;
 	}
 
-	ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-	if (ui_do_button(&config.gfx_vsync, localize("V-Sync"), config.gfx_vsync, &button, ui_draw_checkbox, 0))
+	main_view.HSplitTop(20.0f, &button, &main_view);
+	if(DoButton_CheckBox(&config.gfx_vsync, localize("V-Sync"), config.gfx_vsync, &button))
 	{
 		config.gfx_vsync ^= 1;
 		need_restart = true;
 	}
 
-	ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-	if (ui_do_button(&config.gfx_fsaa_samples, localize("FSAA samples"), config.gfx_fsaa_samples, &button, ui_draw_checkbox_number, 0))
+	main_view.HSplitTop(20.0f, &button, &main_view);
+	if(DoButton_CheckBox_Number(&config.gfx_fsaa_samples, localize("FSAA samples"), config.gfx_fsaa_samples, &button))
 	{
 		config.gfx_fsaa_samples = (config.gfx_fsaa_samples+1)%17;
 		need_restart = true;
 	}
 		
-	ui_hsplit_t(&main_view, 40.0f, &button, &main_view);
-	ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-	if (ui_do_button(&config.gfx_texture_quality, localize("Quality Textures"), config.gfx_texture_quality, &button, ui_draw_checkbox, 0))
+	main_view.HSplitTop(40.0f, &button, &main_view);
+	main_view.HSplitTop(20.0f, &button, &main_view);
+	if(DoButton_CheckBox(&config.gfx_texture_quality, localize("Quality Textures"), config.gfx_texture_quality, &button))
 	{
 		config.gfx_texture_quality ^= 1;
 		need_restart = true;
 	}
 
-	ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-	if (ui_do_button(&config.gfx_texture_compression, localize("Texture Compression"), config.gfx_texture_compression, &button, ui_draw_checkbox, 0))
+	main_view.HSplitTop(20.0f, &button, &main_view);
+	if(DoButton_CheckBox(&config.gfx_texture_compression, localize("Texture Compression"), config.gfx_texture_compression, &button))
 	{
 		config.gfx_texture_compression ^= 1;
 		need_restart = true;
 	}
 
-	ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-	if (ui_do_button(&config.gfx_high_detail, localize("High Detail"), config.gfx_high_detail, &button, ui_draw_checkbox, 0))
+	main_view.HSplitTop(20.0f, &button, &main_view);
+	if(DoButton_CheckBox(&config.gfx_high_detail, localize("High Detail"), config.gfx_high_detail, &button))
 		config.gfx_high_detail ^= 1;
 
 	//
 	
-	RECT text;
-	ui_hsplit_t(&main_view, 20.0f, 0, &main_view);
-	ui_hsplit_t(&main_view, 20.0f, &text, &main_view);
-	//ui_vsplit_l(&text, 15.0f, 0, &text);
-	ui_do_label(&text, localize("UI Color"), 14.0f, -1);
+	CUIRect text;
+	main_view.HSplitTop(20.0f, 0, &main_view);
+	main_view.HSplitTop(20.0f, &text, &main_view);
+	//text.VSplitLeft(15.0f, 0, &text);
+	UI()->DoLabel(&text, localize("UI Color"), 14.0f, -1);
 	
 	const char *labels[] = {
 		localize("Hue"),
@@ -560,27 +627,27 @@ void MENUS::render_settings_graphics(RECT main_view)
 	int *color_slider[4] = {&config.ui_color_hue, &config.ui_color_sat, &config.ui_color_lht, &config.ui_color_alpha};
 	for(int s = 0; s < 4; s++)
 	{
-		RECT text;
-		ui_hsplit_t(&main_view, 19.0f, &button, &main_view);
-		ui_vmargin(&button, 15.0f, &button);
-		ui_vsplit_l(&button, 50.0f, &text, &button);
-		ui_vsplit_r(&button, 5.0f, &button, 0);
-		ui_hsplit_t(&button, 4.0f, 0, &button);
+		CUIRect text;
+		main_view.HSplitTop(19.0f, &button, &main_view);
+		button.VMargin(15.0f, &button);
+		button.VSplitLeft(50.0f, &text, &button);
+		button.VSplitRight(5.0f, &button, 0);
+		button.HSplitTop(4.0f, 0, &button);
 		
 		float k = (*color_slider[s]) / 255.0f;
-		k = ui_do_scrollbar_h(color_slider[s], &button, k);
+		k = DoScrollbarH(color_slider[s], &button, k);
 		*color_slider[s] = (int)(k*255.0f);
-		ui_do_label(&text, labels[s], 15.0f, -1);
+		UI()->DoLabel(&text, labels[s], 15.0f, -1);
 	}		
 }
 
-void MENUS::render_settings_sound(RECT main_view)
+void MENUS::render_settings_sound(CUIRect main_view)
 {
-	RECT button;
-	ui_vsplit_l(&main_view, 300.0f, &main_view, 0);
+	CUIRect button;
+	main_view.VSplitLeft(300.0f, &main_view, 0);
 	
-	ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-	if (ui_do_button(&config.snd_enable, localize("Use sounds"), config.snd_enable, &button, ui_draw_checkbox, 0))
+	main_view.HSplitTop(20.0f, &button, &main_view);
+	if(DoButton_CheckBox(&config.snd_enable, localize("Use sounds"), config.snd_enable, &button))
 	{
 		config.snd_enable ^= 1;
 		need_restart = true;
@@ -589,19 +656,19 @@ void MENUS::render_settings_sound(RECT main_view)
 	if(!config.snd_enable)
 		return;
 	
-	ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-	if (ui_do_button(&config.snd_nonactive_mute, localize("Mute when not active"), config.snd_nonactive_mute, &button, ui_draw_checkbox, 0))
+	main_view.HSplitTop(20.0f, &button, &main_view);
+	if(DoButton_CheckBox(&config.snd_nonactive_mute, localize("Mute when not active"), config.snd_nonactive_mute, &button))
 		config.snd_nonactive_mute ^= 1;
 		
 	// sample rate box
 	{
 		char buf[64];
 		str_format(buf, sizeof(buf), "%d", config.snd_rate);
-		ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-		ui_do_label(&button, localize("Sample rate"), 14.0f, -1);
-		ui_vsplit_l(&button, 110.0f, 0, &button);
-		ui_vsplit_l(&button, 180.0f, &button, 0);
-		ui_do_edit_box(&config.snd_rate, &button, buf, sizeof(buf), 14.0f);
+		main_view.HSplitTop(20.0f, &button, &main_view);
+		UI()->DoLabel(&button, localize("Sample rate"), 14.0f, -1);
+		button.VSplitLeft(110.0f, 0, &button);
+		button.VSplitLeft(180.0f, &button, 0);
+		DoEditBox(&config.snd_rate, &button, buf, sizeof(buf), 14.0f);
 		int before = config.snd_rate;
 		config.snd_rate = atoi(buf);
 		
@@ -614,14 +681,14 @@ void MENUS::render_settings_sound(RECT main_view)
 	
 	// volume slider
 	{
-		RECT button, label;
-		ui_hsplit_t(&main_view, 5.0f, &button, &main_view);
-		ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
-		ui_vsplit_l(&button, 110.0f, &label, &button);
-		ui_hmargin(&button, 2.0f, &button);
-		ui_do_label(&label, localize("Sound volume"), 14.0f, -1);
-		config.snd_volume = (int)(ui_do_scrollbar_h(&config.snd_volume, &button, config.snd_volume/100.0f)*100.0f);
-		ui_hsplit_t(&main_view, 20.0f, 0, &main_view);
+		CUIRect button, label;
+		main_view.HSplitTop(5.0f, &button, &main_view);
+		main_view.HSplitTop(20.0f, &button, &main_view);
+		button.VSplitLeft(110.0f, &label, &button);
+		button.HMargin(2.0f, &button);
+		UI()->DoLabel(&label, localize("Sound volume"), 14.0f, -1);
+		config.snd_volume = (int)(DoScrollbarH(&config.snd_volume, &button, config.snd_volume/100.0f)*100.0f);
+		main_view.HSplitTop(20.0f, 0, &main_view);
 	}
 }
 
@@ -660,7 +727,7 @@ void gather_languages(const char *name, int is_dir, void *user)
 	languages.add(LANGUAGE(nicename, filename));
 }
 
-void MENUS::render_settings_general(RECT main_view)
+void MENUS::render_settings_general(CUIRect main_view)
 {
 	static int lanuagelist = 0;
 	static int selected_language = 0;
@@ -680,7 +747,7 @@ void MENUS::render_settings_general(RECT main_view)
 	
 	int old_selected = selected_language;
 	
-	RECT list = main_view;
+	CUIRect list = main_view;
 	ui_do_listbox_start(&lanuagelist, &list, 24.0f, localize("Language"), languages.size(), selected_language);
 	
 	for(sorted_array<LANGUAGE>::range r = languages.all(); !r.empty(); r.pop_front())
@@ -688,7 +755,7 @@ void MENUS::render_settings_general(RECT main_view)
 		LISTBOXITEM item = ui_do_listbox_nextitem(&r.front());
 		
 		if(item.visible)
-			ui_do_label(&item.rect, r.front().name, 16.0f, -1);
+			UI()->DoLabel(&item.rect, r.front().name, 16.0f, -1);
 	}
 	
 	selected_language = ui_do_listbox_end();
@@ -700,20 +767,20 @@ void MENUS::render_settings_general(RECT main_view)
 	}
 }
 
-void MENUS::render_settings(RECT main_view)
+void MENUS::render_settings(CUIRect main_view)
 {
 	static int settings_page = 0;
 	
 	// render background
-	RECT temp, tabbar;
-	ui_vsplit_r(&main_view, 120.0f, &main_view, &tabbar);
-	ui_draw_rect(&main_view, color_tabbar_active, CORNER_B|CORNER_TL, 10.0f);
-	ui_hsplit_t(&tabbar, 50.0f, &temp, &tabbar);
-	ui_draw_rect(&temp, color_tabbar_active, CORNER_R, 10.0f);
+	CUIRect temp, tabbar;
+	main_view.VSplitRight(120.0f, &main_view, &tabbar);
+	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_B|CUI::CORNER_TL, 10.0f);
+	tabbar.HSplitTop(50.0f, &temp, &tabbar);
+	RenderTools()->DrawUIRect(&temp, color_tabbar_active, CUI::CORNER_R, 10.0f);
 	
-	ui_hsplit_t(&main_view, 10.0f, 0, &main_view);
+	main_view.HSplitTop(10.0f, 0, &main_view);
 	
-	RECT button;
+	CUIRect button;
 	
 	const char *tabs[] = {
 		localize("General"),
@@ -721,17 +788,18 @@ void MENUS::render_settings(RECT main_view)
 		localize("Controls"),
 		localize("Graphics"),
 		localize("Sound")};
+		
 	int num_tabs = (int)(sizeof(tabs)/sizeof(*tabs));
 
 	for(int i = 0; i < num_tabs; i++)
 	{
-		ui_hsplit_t(&tabbar, 10, &button, &tabbar);
-		ui_hsplit_t(&tabbar, 26, &button, &tabbar);
-		if(ui_do_button(tabs[i], tabs[i], settings_page == i, &button, ui_draw_settings_tab_button, 0))
+		tabbar.HSplitTop(10, &button, &tabbar);
+		tabbar.HSplitTop(26, &button, &tabbar);
+		if(DoButton_SettingsTab(tabs[i], tabs[i], settings_page == i, &button))
 			settings_page = i;
 	}
 	
-	ui_margin(&main_view, 10.0f, &main_view);
+	main_view.Margin(10.0f, &main_view);
 	
 	if(settings_page == 0)
 		render_settings_general(main_view);
@@ -746,8 +814,8 @@ void MENUS::render_settings(RECT main_view)
 
 	if(need_restart)
 	{
-		RECT restart_warning;
-		ui_hsplit_b(&main_view, 40, &main_view, &restart_warning);
-		ui_do_label(&restart_warning, localize("You must restart the game for all settings to take effect."), 15.0f, -1, 220);
+		CUIRect restart_warning;
+		main_view.HSplitBottom(40, &main_view, &restart_warning);
+		UI()->DoLabel(&restart_warning, localize("You must restart the game for all settings to take effect."), 15.0f, -1, 220);
 	}
 }
diff --git a/src/game/client/components/motd.cpp b/src/game/client/components/motd.cpp
index 0d1eacba..ba85f7f8 100644
--- a/src/game/client/components/motd.cpp
+++ b/src/game/client/components/motd.cpp
@@ -1,4 +1,5 @@
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <engine/e_config.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
@@ -28,22 +29,22 @@ void MOTD::on_render()
 	if(!is_active())
 		return;
 		
-	float width = 400*3.0f*gfx_screenaspect();
+	float width = 400*3.0f*Graphics()->ScreenAspect();
 	float height = 400*3.0f;
 
-	gfx_mapscreen(0, 0, width, height);
+	Graphics()->MapScreen(0, 0, width, height);
 	
 	float h = 800.0f;
 	float w = 650.0f;
 	float x = width/2 - w/2;
 	float y = 150.0f;
 
-	gfx_blend_normal();
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.5f);
-	draw_round_rect(x, y, w, h, 40.0f);
-	gfx_quads_end();
+	Graphics()->BlendNormal();
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(0,0,0,0.5f);
+	RenderTools()->draw_round_rect(x, y, w, h, 40.0f);
+	Graphics()->QuadsEnd();
 
 	gfx_text(0, x+40.0f, y+40.0f, 32.0f, server_motd, (int)(w-80.0f));
 }
diff --git a/src/game/client/components/particles.cpp b/src/game/client/components/particles.cpp
index ef6dbbe9..61fcf738 100644
--- a/src/game/client/components/particles.cpp
+++ b/src/game/client/components/particles.cpp
@@ -1,4 +1,6 @@
 #include <base/math.hpp>
+#include <engine/client/graphics.h>
+
 #include <game/generated/gc_data.hpp>
 #include <game/client/render.hpp>
 #include <game/gamecore.hpp>
@@ -124,31 +126,31 @@ void PARTICLES::on_render()
 
 void PARTICLES::render_group(int group)
 {
-	gfx_blend_normal();
+	Graphics()->BlendNormal();
 	//gfx_blend_additive();
-	gfx_texture_set(data->images[IMAGE_PARTICLES].id);
-	gfx_quads_begin();
+	Graphics()->TextureSet(data->images[IMAGE_PARTICLES].id);
+	Graphics()->QuadsBegin();
 
 	int i = first_part[group];
 	while(i != -1)
 	{
-		select_sprite(particles[i].spr);
+		RenderTools()->select_sprite(particles[i].spr);
 		float a = particles[i].life / particles[i].life_span;
 		vec2 p = particles[i].pos;
 		float size = mix(particles[i].start_size, particles[i].end_size, a);
 
-		gfx_quads_setrotation(particles[i].rot);
+		Graphics()->QuadsSetRotation(particles[i].rot);
 
-		gfx_setcolor(
+		Graphics()->SetColor(
 			particles[i].color.r,
 			particles[i].color.g,
 			particles[i].color.b,
 			particles[i].color.a); // pow(a, 0.75f) * 
 
-		gfx_quads_draw(p.x, p.y, size, size);
+		Graphics()->QuadsDraw(p.x, p.y, size, size);
 		
 		i = particles[i].next_part;
 	}
-	gfx_quads_end();
-	gfx_blend_normal();
+	Graphics()->QuadsEnd();
+	Graphics()->BlendNormal();
 }
diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp
index 6d6bcc37..e1fee3e8 100644
--- a/src/game/client/components/players.cpp
+++ b/src/game/client/components/players.cpp
@@ -1,4 +1,5 @@
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 
@@ -40,23 +41,23 @@ void PLAYERS::render_hand(TEE_RENDER_INFO *info, vec2 center_pos, vec2 dir, floa
 	hand_pos += dirx * post_rot_offset.x;
 	hand_pos += diry * post_rot_offset.y;
 
-	//gfx_texture_set(data->images[IMAGE_CHAR_DEFAULT].id);
-	gfx_texture_set(info->texture);
-	gfx_quads_begin();
-	gfx_setcolor(info->color_body.r, info->color_body.g, info->color_body.b, info->color_body.a);
+	//Graphics()->TextureSet(data->images[IMAGE_CHAR_DEFAULT].id);
+	Graphics()->TextureSet(info->texture);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(info->color_body.r, info->color_body.g, info->color_body.b, info->color_body.a);
 
 	// two passes
 	for (int i = 0; i < 2; i++)
 	{
 		bool outline = i == 0;
 
-		select_sprite(outline?SPRITE_TEE_HAND_OUTLINE:SPRITE_TEE_HAND, 0, 0, 0);
-		gfx_quads_setrotation(angle);
-		gfx_quads_draw(hand_pos.x, hand_pos.y, 2*basesize, 2*basesize);
+		RenderTools()->select_sprite(outline?SPRITE_TEE_HAND_OUTLINE:SPRITE_TEE_HAND, 0, 0, 0);
+		Graphics()->QuadsSetRotation(angle);
+		Graphics()->QuadsDraw(hand_pos.x, hand_pos.y, 2*basesize, 2*basesize);
 	}
 
-	gfx_quads_setrotation(0);
-	gfx_quads_end();
+	Graphics()->QuadsSetRotation(0);
+	Graphics()->QuadsEnd();
 }
 
 inline float normalize_angular(float f)
@@ -237,9 +238,9 @@ void PLAYERS::render_player(
 	// draw hook
 	if (prev.hook_state>0 && player.hook_state>0)
 	{
-		gfx_texture_set(data->images[IMAGE_GAME].id);
-		gfx_quads_begin();
-		//gfx_quads_begin();
+		Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+		Graphics()->QuadsBegin();
+		//Graphics()->QuadsBegin();
 
 		vec2 pos = position;
 		vec2 hook_pos;
@@ -260,36 +261,36 @@ void PLAYERS::render_player(
 		float d = distance(pos, hook_pos);
 		vec2 dir = normalize(pos-hook_pos);
 
-		gfx_quads_setrotation(get_angle(dir)+pi);
+		Graphics()->QuadsSetRotation(get_angle(dir)+pi);
 
 		// render head
-		select_sprite(SPRITE_HOOK_HEAD);
-		gfx_quads_draw(hook_pos.x, hook_pos.y, 24,16);
+		RenderTools()->select_sprite(SPRITE_HOOK_HEAD);
+		Graphics()->QuadsDraw(hook_pos.x, hook_pos.y, 24,16);
 
 		// render chain
-		select_sprite(SPRITE_HOOK_CHAIN);
+		RenderTools()->select_sprite(SPRITE_HOOK_CHAIN);
 		int i = 0;
 		for(float f = 24; f < d && i < 1024; f += 24, i++)
 		{
 			vec2 p = hook_pos + dir*f;
-			gfx_quads_draw(p.x, p.y,24,16);
+			Graphics()->QuadsDraw(p.x, p.y,24,16);
 		}
 
-		gfx_quads_setrotation(0);
-		gfx_quads_end();
+		Graphics()->QuadsSetRotation(0);
+		Graphics()->QuadsEnd();
 
 		render_hand(&render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
 	}
 
 	// draw gun
 	{
-		gfx_texture_set(data->images[IMAGE_GAME].id);
-		gfx_quads_begin();
-		gfx_quads_setrotation(state.attach.angle*pi*2+angle);
+		Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+		Graphics()->QuadsBegin();
+		Graphics()->QuadsSetRotation(state.attach.angle*pi*2+angle);
 
 		// normal weapons
 		int iw = clamp(player.weapon, 0, NUM_WEAPONS-1);
-		select_sprite(data->weapons.id[iw].sprite_body, direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
+		RenderTools()->select_sprite(data->weapons.id[iw].sprite_body, direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
 
 		vec2 dir = direction;
 		float recoil = 0.0f;
@@ -302,14 +303,14 @@ void PLAYERS::render_player(
 			// if attack is under way, bash stuffs
 			if(direction.x < 0)
 			{
-				gfx_quads_setrotation(-pi/2-state.attach.angle*pi*2);
+				Graphics()->QuadsSetRotation(-pi/2-state.attach.angle*pi*2);
 				p.x -= data->weapons.id[iw].offsetx;
 			}
 			else
 			{
-				gfx_quads_setrotation(-pi/2+state.attach.angle*pi*2);
+				Graphics()->QuadsSetRotation(-pi/2+state.attach.angle*pi*2);
 			}
-			draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
+			RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
 		}
 		else if (player.weapon == WEAPON_NINJA)
 		{
@@ -318,16 +319,16 @@ void PLAYERS::render_player(
 
 			if(direction.x < 0)
 			{
-				gfx_quads_setrotation(-pi/2-state.attach.angle*pi*2);
+				Graphics()->QuadsSetRotation(-pi/2-state.attach.angle*pi*2);
 				p.x -= data->weapons.id[iw].offsetx;
 				gameclient.effects->powerupshine(p+vec2(32,0), vec2(32,12));
 			}
 			else
 			{
-				gfx_quads_setrotation(-pi/2+state.attach.angle*pi*2);
+				Graphics()->QuadsSetRotation(-pi/2+state.attach.angle*pi*2);
 				gameclient.effects->powerupshine(p-vec2(32,0), vec2(32,12));
 			}
-			draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
+			RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
 
 			// HADOKEN
 			if ((client_tick()-player.attacktick) <= (SERVER_TICK_SPEED / 6) && data->weapons.id[iw].num_sprite_muzzles)
@@ -339,14 +340,14 @@ void PLAYERS::render_player(
 					vec2 dir = vec2(player_char->x,player_char->y) - vec2(prev_char->x, prev_char->y);
 					dir = normalize(dir);
 					float hadokenangle = get_angle(dir);
-					gfx_quads_setrotation(hadokenangle);
+					Graphics()->QuadsSetRotation(hadokenangle);
 					//float offsety = -data->weapons[iw].muzzleoffsety;
-					select_sprite(data->weapons.id[iw].sprite_muzzles[itex], 0);
+					RenderTools()->select_sprite(data->weapons.id[iw].sprite_muzzles[itex], 0);
 					vec2 diry(-dir.y,dir.x);
 					p = position;
 					float offsetx = data->weapons.id[iw].muzzleoffsetx;
 					p -= dir * offsetx;
-					draw_sprite(p.x, p.y, 160.0f);
+					RenderTools()->draw_sprite(p.x, p.y, 160.0f);
 				}
 			}
 		}
@@ -359,7 +360,7 @@ void PLAYERS::render_player(
 				recoil = sinf(a*pi);
 			p = position + dir * data->weapons.id[iw].offsetx - dir*recoil*10.0f;
 			p.y += data->weapons.id[iw].offsety;
-			draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
+			RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
 		}
 
 		if (player.weapon == WEAPON_GUN || player.weapon == WEAPON_SHOTGUN)
@@ -379,18 +380,18 @@ void PLAYERS::render_player(
 				if (alpha > 0.0f && data->weapons.id[iw].sprite_muzzles[itex])
 				{
 					float offsety = -data->weapons.id[iw].muzzleoffsety;
-					select_sprite(data->weapons.id[iw].sprite_muzzles[itex], direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
+					RenderTools()->select_sprite(data->weapons.id[iw].sprite_muzzles[itex], direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
 					if(direction.x < 0)
 						offsety = -offsety;
 
 					vec2 diry(-dir.y,dir.x);
 					vec2 muzzlepos = p + dir * data->weapons.id[iw].muzzleoffsetx + diry * offsety;
 
-					draw_sprite(muzzlepos.x, muzzlepos.y, data->weapons.id[iw].visual_size);
+					RenderTools()->draw_sprite(muzzlepos.x, muzzlepos.y, data->weapons.id[iw].visual_size);
 				}
 			}
 		}
-		gfx_quads_end();
+		Graphics()->QuadsEnd();
 
 		switch (player.weapon)
 		{
@@ -408,27 +409,27 @@ void PLAYERS::render_player(
 		TEE_RENDER_INFO ghost = render_info;
 		ghost.color_body.a = 0.5f;
 		ghost.color_feet.a = 0.5f;
-		render_tee(&state, &ghost, player.emote, direction, ghost_position); // render ghost
+		RenderTools()->RenderTee(&state, &ghost, player.emote, direction, ghost_position); // render ghost
 	}
 
 	render_info.size = 64.0f; // force some settings
 	render_info.color_body.a = 1.0f;
 	render_info.color_feet.a = 1.0f;
-	render_tee(&state, &render_info, player.emote, direction, position);
+	RenderTools()->RenderTee(&state, &render_info, player.emote, direction, position);
 
 	if(player.player_state == PLAYERSTATE_CHATTING)
 	{
-		gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
-		gfx_quads_begin();
-		select_sprite(SPRITE_DOTDOT);
-		gfx_quads_draw(position.x + 24, position.y - 40, 64,64);
-		gfx_quads_end();
+		Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id);
+		Graphics()->QuadsBegin();
+		RenderTools()->select_sprite(SPRITE_DOTDOT);
+		Graphics()->QuadsDraw(position.x + 24, position.y - 40, 64,64);
+		Graphics()->QuadsEnd();
 	}
 
 	if (gameclient.clients[info.cid].emoticon_start != -1 && gameclient.clients[info.cid].emoticon_start + 2 * client_tickspeed() > client_tick())
 	{
-		gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
-		gfx_quads_begin();
+		Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id);
+		Graphics()->QuadsBegin();
 
 		int since_start = client_tick() - gameclient.clients[info.cid].emoticon_start;
 		int from_end = gameclient.clients[info.cid].emoticon_start + 2 * client_tickspeed() - client_tick();
@@ -448,13 +449,13 @@ void PLAYERS::render_player(
 
 		float wiggle_angle = sin(5*wiggle);
 
-		gfx_quads_setrotation(pi/6*wiggle_angle);
+		Graphics()->QuadsSetRotation(pi/6*wiggle_angle);
 
-		gfx_setcolor(1.0f,1.0f,1.0f,a);
+		Graphics()->SetColor(1.0f,1.0f,1.0f,a);
 		// client_datas::emoticon is an offset from the first emoticon
-		select_sprite(SPRITE_OOP + gameclient.clients[info.cid].emoticon);
-		gfx_quads_draw(position.x, position.y - 23 - 32*h, 64, 64*h);
-		gfx_quads_end();
+		RenderTools()->select_sprite(SPRITE_OOP + gameclient.clients[info.cid].emoticon);
+		Graphics()->QuadsDraw(position.x, position.y - 23 - 32*h, 64, 64*h);
+		Graphics()->QuadsEnd();
 	}
 }
 
diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp
index 2978eff9..e8db1aed 100644
--- a/src/game/client/components/scoreboard.cpp
+++ b/src/game/client/components/scoreboard.cpp
@@ -1,5 +1,6 @@
 #include <string.h>
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 #include <game/client/gameclient.hpp>
@@ -33,12 +34,12 @@ void SCOREBOARD::render_goals(float x, float y, float w)
 {
 	float h = 50.0f;
 
-	gfx_blend_normal();
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.5f);
-	draw_round_rect(x-10.f, y-10.f, w, h, 10.0f);
-	gfx_quads_end();
+	Graphics()->BlendNormal();
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(0,0,0,0.5f);
+	RenderTools()->draw_round_rect(x-10.f, y-10.f, w, h, 10.0f);
+	Graphics()->QuadsEnd();
 
 	// render goals
 	//y = ystart+h-54;
@@ -76,12 +77,12 @@ void SCOREBOARD::render_spectators(float x, float y, float w)
 	
 	str_format(buffer, sizeof(buffer), "%s: ", localize("Spectators"));
 
-	gfx_blend_normal();
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.5f);
-	draw_round_rect(x-10.f, y-10.f, w, h, 10.0f);
-	gfx_quads_end();
+	Graphics()->BlendNormal();
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(0,0,0,0.5f);
+	RenderTools()->draw_round_rect(x-10.f, y-10.f, w, h, 10.0f);
+	Graphics()->QuadsEnd();
 	
 	for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
 	{
@@ -109,12 +110,12 @@ void SCOREBOARD::render_scoreboard(float x, float y, float w, int team, const ch
 	//float ystart = y;
 	float h = 750.0f;
 
-	gfx_blend_normal();
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.5f);
-	draw_round_rect(x-10.f, y-10.f, w, h, 17.0f);
-	gfx_quads_end();
+	Graphics()->BlendNormal();
+	Graphics()->TextureSet(-1);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(0,0,0,0.5f);
+	RenderTools()->draw_round_rect(x-10.f, y-10.f, w, h, 17.0f);
+	Graphics()->QuadsEnd();
 
 	// render title
 	if(!title)
@@ -210,11 +211,11 @@ void SCOREBOARD::render_scoreboard(float x, float y, float w, int team, const ch
 		if(info->local)
 		{
 			// background so it's easy to find the local player
-			gfx_texture_set(-1);
-			gfx_quads_begin();
-			gfx_setcolor(1,1,1,0.25f);
-			draw_round_rect(x, y, w-20, line_height*0.95f, 17.0f);
-			gfx_quads_end();
+			Graphics()->TextureSet(-1);
+			Graphics()->QuadsBegin();
+			Graphics()->SetColor(1,1,1,0.25f);
+			RenderTools()->draw_round_rect(x, y, w-20, line_height*0.95f, 17.0f);
+			Graphics()->QuadsEnd();
 		}
 
 		str_format(buf, sizeof(buf), "%4d", info->score);
@@ -230,21 +231,21 @@ void SCOREBOARD::render_scoreboard(float x, float y, float w, int team, const ch
 		if((gameclient.snap.flags[0] && gameclient.snap.flags[0]->carried_by == info->cid) ||
 			(gameclient.snap.flags[1] && gameclient.snap.flags[1]->carried_by == info->cid))
 		{
-			gfx_blend_normal();
-			gfx_texture_set(data->images[IMAGE_GAME].id);
-			gfx_quads_begin();
+			Graphics()->BlendNormal();
+			Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+			Graphics()->QuadsBegin();
 
-			if(info->team == 0) select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
-			else select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
+			if(info->team == 0) RenderTools()->select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
+			else RenderTools()->select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
 			
 			float size = 64.0f;
-			gfx_quads_drawTL(x+55, y-15, size/2, size);
-			gfx_quads_end();
+			Graphics()->QuadsDrawTL(x+55, y-15, size/2, size);
+			Graphics()->QuadsEnd();
 		}
 		
 		TEE_RENDER_INFO teeinfo = gameclient.clients[info->cid].render_info;
 		teeinfo.size *= tee_sizemod;
-		render_tee(ANIMSTATE::get_idle(), &teeinfo, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28+tee_offset));
+		RenderTools()->RenderTee(ANIMSTATE::get_idle(), &teeinfo, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28+tee_offset));
 
 		
 		y += line_height;
@@ -278,10 +279,10 @@ void SCOREBOARD::on_render()
 		gameclient.motd->clear();
 	
 
-	float width = 400*3.0f*gfx_screenaspect();
+	float width = 400*3.0f*Graphics()->ScreenAspect();
 	float height = 400*3.0f;
 	
-	gfx_mapscreen(0, 0, width, height);
+	Graphics()->MapScreen(0, 0, width, height);
 
 	float w = 650.0f;
 
diff --git a/src/game/client/components/skins.cpp b/src/game/client/components/skins.cpp
index 451a77f3..ad3607a1 100644
--- a/src/game/client/components/skins.cpp
+++ b/src/game/client/components/skins.cpp
@@ -6,12 +6,10 @@
 #include <base/system.h>
 #include <base/math.hpp>
 
+#include <engine/client/graphics.h>
 #include <engine/e_client_interface.h>
 
-extern "C"
-{
-	#include <engine/e_engine.h>
-}
+#include <engine/e_engine.h>
 
 #include "skins.hpp"
 
@@ -32,13 +30,13 @@ void SKINS::skinscan(const char *name, int is_dir, void *user)
 	char buf[512];
 	str_format(buf, sizeof(buf), "skins/%s", name);
 	IMAGE_INFO info;
-	if(!gfx_load_png(&info, buf))
+	if(!self->Graphics()->LoadPNG(&info, buf))
 	{
 		dbg_msg("game", "failed to load skin from %s", name);
 		return;
 	}
 	
-	self->skins[self->num_skins].org_texture = gfx_load_texture_raw(info.width, info.height, info.format, info.data, info.format, 0);
+	self->skins[self->num_skins].org_texture = self->Graphics()->LoadTextureRaw(info.width, info.height, info.format, info.data, info.format, 0);
 	
 	int body_size = 96; // body size
 	unsigned char *d = (unsigned char *)info.data;
@@ -111,7 +109,7 @@ void SKINS::skinscan(const char *name, int is_dir, void *user)
 			}
 	}
 	
-	self->skins[self->num_skins].color_texture = gfx_load_texture_raw(info.width, info.height, info.format, info.data, info.format, 0);
+	self->skins[self->num_skins].color_texture = self->Graphics()->LoadTextureRaw(info.width, info.height, info.format, info.data, info.format, 0);
 	mem_free(info.data);
 
 	// set skin data	
diff --git a/src/game/client/components/voting.cpp b/src/game/client/components/voting.cpp
index 190ba224..dcf5c954 100644
--- a/src/game/client/components/voting.cpp
+++ b/src/game/client/components/voting.cpp
@@ -143,30 +143,30 @@ void VOTING::on_render()
 }
 
 
-void VOTING::render_bars(RECT bars, bool text)
+void VOTING::render_bars(CUIRect bars, bool text)
 {
-	ui_draw_rect(&bars, vec4(0.8f,0.8f,0.8f,0.5f), CORNER_ALL, bars.h/3);
+	RenderTools()->DrawUIRect(&bars, vec4(0.8f,0.8f,0.8f,0.5f), CUI::CORNER_ALL, bars.h/3);
 	
-	RECT splitter = bars;
+	CUIRect splitter = bars;
 	splitter.x = splitter.x+splitter.w/2;
 	splitter.w = splitter.h/2.0f;
 	splitter.x -= splitter.w/2;
-	ui_draw_rect(&splitter, vec4(0.4f,0.4f,0.4f,0.5f), CORNER_ALL, splitter.h/4);
+	RenderTools()->DrawUIRect(&splitter, vec4(0.4f,0.4f,0.4f,0.5f), CUI::CORNER_ALL, splitter.h/4);
 			
 	if(total)
 	{
-		RECT pass_area = bars;
+		CUIRect pass_area = bars;
 		if(yes)
 		{
-			RECT yes_area = bars;
+			CUIRect yes_area = bars;
 			yes_area.w *= yes/(float)total;
-			ui_draw_rect(&yes_area, vec4(0.2f,0.9f,0.2f,0.85f), CORNER_ALL, bars.h/3);
+			RenderTools()->DrawUIRect(&yes_area, vec4(0.2f,0.9f,0.2f,0.85f), CUI::CORNER_ALL, bars.h/3);
 			
 			if(text)
 			{
 				char buf[256];
 				str_format(buf, sizeof(buf), "%d", yes);
-				ui_do_label(&yes_area, buf, bars.h*0.75f, 0);
+				UI()->DoLabel(&yes_area, buf, bars.h*0.75f, 0);
 			}
 			
 			pass_area.x += yes_area.w;
@@ -175,16 +175,16 @@ void VOTING::render_bars(RECT bars, bool text)
 		
 		if(no)
 		{
-			RECT no_area = bars;
+			CUIRect no_area = bars;
 			no_area.w *= no/(float)total;
 			no_area.x = (bars.x + bars.w)-no_area.w;
-			ui_draw_rect(&no_area, vec4(0.9f,0.2f,0.2f,0.85f), CORNER_ALL, bars.h/3);
+			RenderTools()->DrawUIRect(&no_area, vec4(0.9f,0.2f,0.2f,0.85f), CUI::CORNER_ALL, bars.h/3);
 			
 			if(text)
 			{
 				char buf[256];
 				str_format(buf, sizeof(buf), "%d", no);
-				ui_do_label(&no_area, buf, bars.h*0.75f, 0);
+				UI()->DoLabel(&no_area, buf, bars.h*0.75f, 0);
 			}
 
 			pass_area.w -= no_area.w;
@@ -194,7 +194,7 @@ void VOTING::render_bars(RECT bars, bool text)
 		{
 			char buf[256];
 			str_format(buf, sizeof(buf), "%d", pass);
-			ui_do_label(&pass_area, buf, bars.h*0.75f, 0);
+			UI()->DoLabel(&pass_area, buf, bars.h*0.75f, 0);
 		}
 	}	
 }
diff --git a/src/game/client/components/voting.hpp b/src/game/client/components/voting.hpp
index 3341edea..e04e1840 100644
--- a/src/game/client/components/voting.hpp
+++ b/src/game/client/components/voting.hpp
@@ -1,10 +1,6 @@
 #include <game/client/component.hpp>
 #include <game/client/ui.hpp>
-
-extern "C"
-{
-	#include <engine/e_memheap.h>
-}
+#include <engine/e_memheap.h>
 
 class VOTING : public COMPONENT
 {
@@ -38,7 +34,7 @@ public:
 	virtual void on_message(int msgtype, void *rawmsg);
 	virtual void on_render();
 	
-	void render_bars(RECT bars, bool text);
+	void render_bars(CUIRect bars, bool text);
 	
 	void callvote_kick(int client_id);
 	void callvote_option(int option);
diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp
index fa2f4de0..25a42620 100644
--- a/src/game/client/gameclient.cpp
+++ b/src/game/client/gameclient.cpp
@@ -1,5 +1,6 @@
 #include <string.h>
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 #include <engine/e_demorec.h>
 
 #include <game/generated/g_protocol.hpp>
@@ -269,6 +270,13 @@ void GAMECLIENT::on_init()
 	// set the language
 	localization.load(config.cl_languagefile);
 	
+	// propagate pointers
+	m_UI.SetGraphics(Graphics());
+	m_RenderTools.m_pGraphics = Graphics();
+	m_RenderTools.m_pUI = UI();
+	for(int i = 0; i < all.num; i++)
+		all.components[i]->client = this;
+	
 	// init all components
 	for(int i = 0; i < all.num; i++)
 		all.components[i]->on_init();
@@ -297,7 +305,7 @@ void GAMECLIENT::on_init()
 	for(int i = 0; i < data->num_images; i++)
 	{
 		gameclient.menus->render_loading(load_current/load_total);
-		data->images[i].id = gfx_load_texture(data->images[i].filename, IMG_AUTO, 0);
+		data->images[i].id = Graphics()->LoadTexture(data->images[i].filename, IMG_AUTO, 0);
 		load_current++;
 	}
 
@@ -366,7 +374,7 @@ void GAMECLIENT::on_connected()
 {
 	layers_init();
 	col_init();
-	render_tilemap_generate_skip();
+	RenderTools()->render_tilemap_generate_skip();
 
 	for(int i = 0; i < all.num; i++)
 	{
@@ -450,6 +458,21 @@ static void evolve(NETOBJ_CHARACTER *character, int tick)
 
 void GAMECLIENT::on_render()
 {
+	/*Graphics()->Clear(1,0,0);
+	
+	menus->render_background();
+	return;*/
+	/*
+	Graphics()->Clear(1,0,0);
+	Graphics()->MapScreen(0,0,100,100);
+	
+	Graphics()->QuadsBegin();
+		Graphics()->SetColor(1,1,1,1);
+		Graphics()->QuadsDraw(50, 50, 30, 30);
+	Graphics()->QuadsEnd();
+	
+	return;*/
+	
 	// update the local character position
 	update_local_character_pos();
 	
@@ -972,3 +995,17 @@ void GAMECLIENT::conchain_special_infoupdate(void *result, void *user_data, CONS
 	if(console_arg_num(result))
 		((GAMECLIENT*)user_data)->send_info(false);
 }
+
+void GAMECLIENT::SetEngine(class IEngine *pEngine)
+{
+	m_pEngine = pEngine;
+	
+	// digg out some pointers
+	m_pGraphics = m_pEngine->Graphics();
+}
+
+IGameClient *CreateGameClient(IEngine *pEngine)
+{
+	gameclient.SetEngine(pEngine);
+	return &gameclient;
+}
diff --git a/src/game/client/gameclient.hpp b/src/game/client/gameclient.hpp
index e354430d..1da40de0 100644
--- a/src/game/client/gameclient.hpp
+++ b/src/game/client/gameclient.hpp
@@ -1,10 +1,13 @@
+#ifndef FILE_GAMECLIENT_HPP
+#define FILE_GAMECLIENT_HPP
 
 #include <base/vmath.hpp>
 #include <engine/e_console.h>
+#include <engine/client/client.h>
 #include <game/gamecore.hpp>
 #include "render.hpp"
 
-class GAMECLIENT
+class GAMECLIENT : public IGameClient
 {
 	class STACK
 	{
@@ -24,6 +27,9 @@ class GAMECLIENT
 	STACK all;
 	STACK input;
 	
+	class IGraphics *m_pGraphics;
+	class IEngine *m_pEngine;
+	CUI m_UI;
 	
 	void dispatch_input();
 	void process_events();
@@ -38,6 +44,12 @@ class GAMECLIENT
 	static void conchain_special_infoupdate(void *result, void *user_data, CONSOLE_CALLBACK cb, void *cbuser);
 	
 public:
+	class IGraphics *Graphics() const { return m_pGraphics; }
+	class CUI *UI() { return &m_UI; }
+	class CRenderTools *RenderTools() { return &m_RenderTools; }
+	
+	void SetEngine(class IEngine *pEngine);
+
 	bool suppress_events;
 	bool new_tick;
 	bool new_predicted_tick;
@@ -120,6 +132,8 @@ public:
 
 	CLIENT_DATA clients[MAX_CLIENTS];
 	
+	CRenderTools m_RenderTools;
+	
 	void on_reset();
 
 	// hooks
@@ -158,6 +172,10 @@ public:
 	class VOTING *voting;
 };
 
+
+// TODO: Refactor: Remove this
 extern GAMECLIENT gameclient;
 
 extern const char *localize(const char *str);
+
+#endif
diff --git a/src/game/client/render.cpp b/src/game/client/render.cpp
index f63e8692..f271c7d2 100644
--- a/src/game/client/render.cpp
+++ b/src/game/client/render.cpp
@@ -5,6 +5,7 @@
 
 #include <engine/e_client_interface.h>
 #include <engine/e_config.h>
+#include <engine/client/graphics.h>
 #include <game/generated/gc_data.hpp>
 #include <game/generated/g_protocol.hpp>
 #include <game/layers.hpp>
@@ -13,13 +14,15 @@
 
 static float sprite_w_scale;
 static float sprite_h_scale;
+
+
 /*
 static void layershot_begin()
 {
 	if(!config.cl_layershot)
 		return;
 
-	gfx_clear(0,0,0);
+	Graphics()->Clear(0,0,0);
 }
 
 static void layershot_end()
@@ -33,7 +36,7 @@ static void layershot_end()
 	config.cl_layershot++;
 }*/
 
-void select_sprite(SPRITE *spr, int flags, int sx, int sy)
+void CRenderTools::select_sprite(SPRITE *spr, int flags, int sx, int sy)
 {
 	int x = spr->x+sx;
 	int y = spr->y+sy;
@@ -66,22 +69,22 @@ void select_sprite(SPRITE *spr, int flags, int sx, int sy)
 		x2 = temp;
 	}
 	
-	gfx_quads_setsubset(x1, y1, x2, y2);
+	Graphics()->QuadsSetSubset(x1, y1, x2, y2);
 }
 
-void select_sprite(int id, int flags, int sx, int sy)
+void CRenderTools::select_sprite(int id, int flags, int sx, int sy)
 {
 	if(id < 0 || id > data->num_sprites)
 		return;
 	select_sprite(&data->sprites[id], flags, sx, sy);
 }
 
-void draw_sprite(float x, float y, float size)
+void CRenderTools::draw_sprite(float x, float y, float size)
 {
-	gfx_quads_draw(x, y, size*sprite_w_scale, size*sprite_h_scale);
+	Graphics()->QuadsDraw(x, y, size*sprite_w_scale, size*sprite_h_scale);
 }
 
-void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners)
+void CRenderTools::draw_round_rect_ext(float x, float y, float w, float h, float r, int corners)
 {
 	int num = 8;
 	for(int i = 0; i < num; i+=2)
@@ -97,69 +100,73 @@ void draw_round_rect_ext(float x, float y, float w, float h, float r, int corner
 		float sa3 = sinf(a3);
 
 		if(corners&1) // TL
-		gfx_quads_draw_freeform(
+		Graphics()->QuadsDrawFreeform(
 			x+r, y+r,
 			x+(1-ca1)*r, y+(1-sa1)*r,
 			x+(1-ca3)*r, y+(1-sa3)*r,
 			x+(1-ca2)*r, y+(1-sa2)*r);
 
 		if(corners&2) // TR
-		gfx_quads_draw_freeform(
+		Graphics()->QuadsDrawFreeform(
 			x+w-r, y+r,
 			x+w-r+ca1*r, y+(1-sa1)*r,
 			x+w-r+ca3*r, y+(1-sa3)*r,
 			x+w-r+ca2*r, y+(1-sa2)*r);
 
 		if(corners&4) // BL
-		gfx_quads_draw_freeform(
+		Graphics()->QuadsDrawFreeform(
 			x+r, y+h-r,
 			x+(1-ca1)*r, y+h-r+sa1*r,
 			x+(1-ca3)*r, y+h-r+sa3*r,
 			x+(1-ca2)*r, y+h-r+sa2*r);
 
 		if(corners&8) // BR
-		gfx_quads_draw_freeform(
+		Graphics()->QuadsDrawFreeform(
 			x+w-r, y+h-r,
 			x+w-r+ca1*r, y+h-r+sa1*r,
 			x+w-r+ca3*r, y+h-r+sa3*r,
 			x+w-r+ca2*r, y+h-r+sa2*r);
 	}
 
-	gfx_quads_drawTL(x+r, y+r, w-r*2, h-r*2); // center
-	gfx_quads_drawTL(x+r, y, w-r*2, r); // top
-	gfx_quads_drawTL(x+r, y+h-r, w-r*2, r); // bottom
-	gfx_quads_drawTL(x, y+r, r, h-r*2); // left
-	gfx_quads_drawTL(x+w-r, y+r, r, h-r*2); // right
+	Graphics()->QuadsDrawTL(x+r, y+r, w-r*2, h-r*2); // center
+	Graphics()->QuadsDrawTL(x+r, y, w-r*2, r); // top
+	Graphics()->QuadsDrawTL(x+r, y+h-r, w-r*2, r); // bottom
+	Graphics()->QuadsDrawTL(x, y+r, r, h-r*2); // left
+	Graphics()->QuadsDrawTL(x+w-r, y+r, r, h-r*2); // right
 	
-	if(!(corners&1)) gfx_quads_drawTL(x, y, r, r); // TL
-	if(!(corners&2)) gfx_quads_drawTL(x+w, y, -r, r); // TR
-	if(!(corners&4)) gfx_quads_drawTL(x, y+h, r, -r); // BL
-	if(!(corners&8)) gfx_quads_drawTL(x+w, y+h, -r, -r); // BR
+	if(!(corners&1)) Graphics()->QuadsDrawTL(x, y, r, r); // TL
+	if(!(corners&2)) Graphics()->QuadsDrawTL(x+w, y, -r, r); // TR
+	if(!(corners&4)) Graphics()->QuadsDrawTL(x, y+h, r, -r); // BL
+	if(!(corners&8)) Graphics()->QuadsDrawTL(x+w, y+h, -r, -r); // BR
 }
 
-void draw_round_rect(float x, float y, float w, float h, float r)
+void CRenderTools::draw_round_rect(float x, float y, float w, float h, float r)
 {
 	draw_round_rect_ext(x,y,w,h,r,0xf);
 }
 
-void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding)
+void CRenderTools::DrawUIRect(const CUIRect *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();
+	Graphics()->TextureSet(-1);
+	
+	// TODO: FIX US
+	Graphics()->QuadsBegin();
+	Graphics()->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);
+	Graphics()->QuadsEnd();
 }
 
-void render_tee(ANIMSTATE *anim, TEE_RENDER_INFO *info, int emote, vec2 dir, vec2 pos)
+void CRenderTools::RenderTee(ANIMSTATE *anim, TEE_RENDER_INFO *info, int emote, vec2 dir, vec2 pos)
 {
 	vec2 direction = dir;
 	vec2 position = pos;
 
-	//gfx_texture_set(data->images[IMAGE_CHAR_DEFAULT].id);
-	gfx_texture_set(info->texture);
-	gfx_quads_begin();
-	//gfx_quads_draw(pos.x, pos.y-128, 128, 128);
+	//Graphics()->TextureSet(data->images[IMAGE_CHAR_DEFAULT].id);
+	Graphics()->TextureSet(info->texture);
+	
+	// TODO: FIX ME
+	Graphics()->QuadsBegin();
+	//Graphics()->QuadsDraw(pos.x, pos.y-128, 128, 128);
 
 	// first pass we draw the outline
 	// second pass we draw the filling
@@ -173,13 +180,13 @@ void render_tee(ANIMSTATE *anim, TEE_RENDER_INFO *info, int emote, vec2 dir, vec
 			float basesize = info->size;
 			if(f == 1)
 			{
-				gfx_quads_setrotation(anim->body.angle*pi*2);
+				Graphics()->QuadsSetRotation(anim->body.angle*pi*2);
 
 				// draw body
-				gfx_setcolor(info->color_body.r, info->color_body.g, info->color_body.b, 1.0f);
+				Graphics()->SetColor(info->color_body.r, info->color_body.g, info->color_body.b, 1.0f);
 				vec2 body_pos = position + vec2(anim->body.x, anim->body.y)*animscale;
 				select_sprite(outline?SPRITE_TEE_BODY_OUTLINE:SPRITE_TEE_BODY, 0, 0, 0);
-				gfx_quads_draw(body_pos.x, body_pos.y, basesize, basesize);
+				Graphics()->QuadsDraw(body_pos.x, body_pos.y, basesize, basesize);
 
 				// draw eyes
 				if(p == 1)
@@ -207,8 +214,8 @@ void render_tee(ANIMSTATE *anim, TEE_RENDER_INFO *info, int emote, vec2 dir, vec
 					float h = emote == EMOTE_BLINK ? basesize*0.15f : eyescale;
 					float eyeseparation = (0.075f - 0.010f*fabs(direction.x))*basesize;
 					vec2 offset = vec2(direction.x*0.125f, -0.05f+direction.y*0.10f)*basesize;
-					gfx_quads_draw(body_pos.x-eyeseparation+offset.x, body_pos.y+offset.y, eyescale, h);
-					gfx_quads_draw(body_pos.x+eyeseparation+offset.x, body_pos.y+offset.y, -eyescale, h);
+					Graphics()->QuadsDraw(body_pos.x-eyeseparation+offset.x, body_pos.y+offset.y, eyescale, h);
+					Graphics()->QuadsDraw(body_pos.x+eyeseparation+offset.x, body_pos.y+offset.y, -eyescale, h);
 				}
 			}
 
@@ -218,7 +225,7 @@ void render_tee(ANIMSTATE *anim, TEE_RENDER_INFO *info, int emote, vec2 dir, vec
 			float w = basesize;
 			float h = basesize/2;
 
-			gfx_quads_setrotation(foot->angle*pi*2);
+			Graphics()->QuadsSetRotation(foot->angle*pi*2);
 			
 			bool indicate = !info->got_airjump && config.cl_airjumpindicator;
 			float cs = 1.0f; // color scale
@@ -232,12 +239,12 @@ void render_tee(ANIMSTATE *anim, TEE_RENDER_INFO *info, int emote, vec2 dir, vec
 					cs = 0.5f;
 			}
 				
-			gfx_setcolor(info->color_feet.r*cs, info->color_feet.g*cs, info->color_feet.b*cs, 1.0f);
-			gfx_quads_draw(position.x+foot->x*animscale, position.y+foot->y*animscale, w, h);
+			Graphics()->SetColor(info->color_feet.r*cs, info->color_feet.g*cs, info->color_feet.b*cs, 1.0f);
+			Graphics()->QuadsDraw(position.x+foot->x*animscale, position.y+foot->y*animscale, w, h);
 		}
 	}
 
-	gfx_quads_end();
+	Graphics()->QuadsEnd();
 	
 	
 }
@@ -262,7 +269,7 @@ static void calc_screen_params(float amount, float wmax, float hmax, float aspec
 	}
 }
 
-void mapscreen_to_world(float center_x, float center_y, float parallax_x, float parallax_y,
+void CRenderTools::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;
@@ -277,7 +284,7 @@ void mapscreen_to_world(float center_x, float center_y, float parallax_x, float
 	points[3] = offset_y+center_y+height/2;
 }
 
-void render_tilemap_generate_skip()
+void CRenderTools::render_tilemap_generate_skip()
 {
 	for(int g = 0; g < layers_num_groups(); g++)
 	{
diff --git a/src/game/client/render.hpp b/src/game/client/render.hpp
index 9ce555d2..8e99b432 100644
--- a/src/game/client/render.hpp
+++ b/src/game/client/render.hpp
@@ -7,6 +7,7 @@
 #include "../mapitems.hpp"
 #include "ui.hpp"
 
+
 struct TEE_RENDER_INFO
 {
 	TEE_RENDER_INFO()
@@ -37,32 +38,44 @@ enum
 	TILERENDERFLAG_EXTEND=4,
 };
 
-//typedef struct SPRITE;
 
-void select_sprite(struct SPRITE *spr, int flags=0, int sx=0, int sy=0);
-void select_sprite(int id, int flags=0, int sx=0, int sy=0);
+class CRenderTools
+{
+public:
+	class IGraphics *m_pGraphics;
+	class CUI *m_pUI;
+	
+	class IGraphics *Graphics() const { return m_pGraphics; }
+	class CUI *UI() const { return m_pUI; }
 
-void draw_sprite(float x, float y, float size);
+	//typedef struct SPRITE;
 
-// rects
-void draw_round_rect(float x, float y, float w, float h, float r);
-void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners);
-void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding);
+	void select_sprite(struct SPRITE *spr, int flags=0, int sx=0, int sy=0);
+	void select_sprite(int id, int flags=0, int sx=0, int sy=0);
 
-// larger rendering methods
-void render_tilemap_generate_skip();
+	void draw_sprite(float x, float y, float size);
 
-// object render methods (gc_render_obj.cpp)
-void render_tee(class ANIMSTATE *anim, TEE_RENDER_INFO *info, int emote, vec2 dir, vec2 pos);
+	// rects
+	void draw_round_rect(float x, float y, float w, float h, float r);
+	void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners);
+	
+	void DrawUIRect(const CUIRect *r, vec4 color, int corners, float rounding);
 
-// map render methods (gc_render_map.cpp)
-void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result);
-void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, int env, float *channels), int flags);
-void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int flags);
+	// larger rendering methods
+	void render_tilemap_generate_skip();
 
-// helpers
-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);
+	// object render methods (gc_render_obj.cpp)
+	void RenderTee(class ANIMSTATE *anim, TEE_RENDER_INFO *info, int emote, vec2 dir, vec2 pos);
 
+	// map render methods (gc_render_map.cpp)
+	static void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result);
+	void render_quads(QUAD *quads, int num_quads, int flags, void (*eval)(float time_offset, int env, float *channels, void *user), void *user);
+	void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int flags);
+
+	// helpers
+	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);	
+	
+};
 
 #endif
diff --git a/src/game/client/render_map.cpp b/src/game/client/render_map.cpp
index 118a4d73..ea3b8420 100644
--- a/src/game/client/render_map.cpp
+++ b/src/game/client/render_map.cpp
@@ -2,10 +2,11 @@
 #include <math.h>
 #include <base/math.hpp>
 #include <engine/e_client_interface.h>
+#include <engine/client/graphics.h>
 
 #include "render.hpp"
 
-void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result)
+void CRenderTools::render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result)
 {
 	if(num_points == 0)
 	{
@@ -77,9 +78,9 @@ static void rotate(POINT *center, POINT *point, float rotation)
 	point->y = (int)(x * sinf(rotation) + y * cosf(rotation) + center->y);
 }
 
-void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, int env, float *channels), int renderflags)
+void CRenderTools::render_quads(QUAD *quads, int num_quads, int renderflags, void (*eval)(float time_offset, int env, float *channels, void *user), void *user)
 {
-	gfx_quads_begin();
+	Graphics()->QuadsBegin();
 	float conv = 1/255.0f;
 	for(int i = 0; i < num_quads; i++)
 	{
@@ -90,7 +91,7 @@ void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, in
 		if(q->color_env >= 0)
 		{
 			float channels[4];
-			eval(q->color_env_offset/1000.0f, q->color_env, channels);
+			eval(q->color_env_offset/1000.0f, q->color_env, channels, user);
 			r = channels[0];
 			g = channels[1];
 			b = channels[2];
@@ -106,7 +107,7 @@ void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, in
 		if(!opaque && !(renderflags&LAYERRENDERFLAG_TRANSPARENT))
 			continue;
 		
-		gfx_quads_setsubset_free(
+		Graphics()->QuadsSetSubsetFree(
 			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),
@@ -121,17 +122,17 @@ void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, in
 		if(q->pos_env >= 0)
 		{
 			float channels[4];
-			eval(q->pos_env_offset/1000.0f, q->pos_env, channels);
+			eval(q->pos_env_offset/1000.0f, q->pos_env, channels, user);
 			offset_x = channels[0];
 			offset_y = channels[1];
 			rot = channels[2]/360.0f*pi*2;
 		}
 		
 		
-		gfx_setcolorvertex(0, q->colors[0].r*conv*r, q->colors[0].g*conv*g, q->colors[0].b*conv*b, q->colors[0].a*conv*a);
-		gfx_setcolorvertex(1, q->colors[1].r*conv*r, q->colors[1].g*conv*g, q->colors[1].b*conv*b, q->colors[1].a*conv*a);
-		gfx_setcolorvertex(2, q->colors[2].r*conv*r, q->colors[2].g*conv*g, q->colors[2].b*conv*b, q->colors[2].a*conv*a);
-		gfx_setcolorvertex(3, q->colors[3].r*conv*r, q->colors[3].g*conv*g, q->colors[3].b*conv*b, q->colors[3].a*conv*a);
+		Graphics()->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);
+		Graphics()->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);
+		Graphics()->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);
+		Graphics()->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;
 	
@@ -150,30 +151,30 @@ void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, in
 			rotate(&q->points[4], &rotated[3], rot);
 		}
 		
-		gfx_quads_draw_freeform(
+		Graphics()->QuadsDrawFreeform(
 			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();	
+	Graphics()->QuadsEnd();	
 }
 
-void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int renderflags)
+void CRenderTools::render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int renderflags)
 {
-	//gfx_texture_set(img_get(tmap->image));
+	//Graphics()->TextureSet(img_get(tmap->image));
 	float screen_x0, screen_y0, screen_x1, screen_y1;
-	gfx_getscreen(&screen_x0, &screen_y0, &screen_x1, &screen_y1);
-	//gfx_mapscreen(screen_x0-50, screen_y0-50, screen_x1+50, screen_y1+50);
+	Graphics()->GetScreen(&screen_x0, &screen_y0, &screen_x1, &screen_y1);
+	//Graphics()->MapScreen(screen_x0-50, screen_y0-50, screen_x1+50, screen_y1+50);
 
 	// calculate the final pixelsize for the tiles	
 	float tile_pixelsize = 1024/32.0f;
-	float final_tilesize = scale/(screen_x1-screen_x0) * gfx_screenwidth();
+	float final_tilesize = scale/(screen_x1-screen_x0) * Graphics()->ScreenWidth();
 	float final_tilesize_scale = final_tilesize/tile_pixelsize;
 	
-	gfx_quads_begin();
-	gfx_setcolor(color.r, color.g, color.b, color.a);
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(color.r, color.g, color.b, color.a);
 	
 	int starty = (int)(screen_y0/scale)-1;
 	int startx = (int)(screen_x0/scale)-1;
@@ -262,13 +263,13 @@ void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int rend
 						v1 = tmp;
 					}
 					
-					gfx_quads_setsubset(u0,v0,u1,v1);
-					gfx_quads_drawTL(x*scale, y*scale, scale, scale);
+					Graphics()->QuadsSetSubset(u0,v0,u1,v1);
+					Graphics()->QuadsDrawTL(x*scale, y*scale, scale, scale);
 				}
 			}
 			x += tiles[c].skip;
 		}
 	
-	gfx_quads_end();
-	gfx_mapscreen(screen_x0, screen_y0, screen_x1, screen_y1);
+	Graphics()->QuadsEnd();
+	Graphics()->MapScreen(screen_x0, screen_y0, screen_x1, screen_y1);
 }
diff --git a/src/game/client/ui.cpp b/src/game/client/ui.cpp
index 1361b85c..4aaaf32f 100644
--- a/src/game/client/ui.cpp
+++ b/src/game/client/ui.cpp
@@ -3,101 +3,95 @@
 
 #include <engine/e_client_interface.h>
 #include <engine/e_config.h>
+#include <engine/client/graphics.h>
 #include "ui.hpp"
 
 /********************************************************
  UI                                                      
 *********************************************************/
-static const void *hot_item = 0;
-static const void *active_item = 0;
-static const void *last_active_item = 0;
-static const void *becomming_hot_item = 0;
-static float mouse_x, mouse_y; /* in gui space */
-static float mouse_wx, mouse_wy; /* in world space */
-static unsigned mouse_buttons = 0;
-static unsigned last_mouse_buttons = 0;
-
-float ui_mouse_x() { return mouse_x; }
-float ui_mouse_y() { return mouse_y; }
-float ui_mouse_world_x() { return mouse_wx; }
-float ui_mouse_world_y() { return mouse_wy; }
-int ui_mouse_button(int index) { return (mouse_buttons>>index)&1; }
-int ui_mouse_button_clicked(int index) { return ui_mouse_button(index) && !((last_mouse_buttons>>index)&1) ; }
-
-void ui_set_hot_item(const void *id) { becomming_hot_item = id; }
-void ui_set_active_item(const void *id) { active_item = id; if (id) last_active_item = id; }
-void ui_clear_last_active_item() { last_active_item = 0; }
-const void *ui_hot_item() { return hot_item; }
-const void *ui_next_hot_item() { return becomming_hot_item; }
-const void *ui_active_item() { return active_item; }
-const void *ui_last_active_item() { return last_active_item; }
-
-int ui_update(float mx, float my, float mwx, float mwy, int buttons)
+
+CUI::CUI()
+{
+	m_pHotItem = 0;
+	m_pActiveItem = 0;
+	m_pLastActiveItem = 0;
+	m_pBecommingHotItem = 0;
+	
+	m_MouseX = 0;
+	m_MouseY = 0;
+	m_MouseWorldX = 0;
+	m_MouseWorldY = 0;
+	m_MouseButtons = 0;
+	m_LastMouseButtons = 0;	
+	
+	m_Screen.x = 0;
+	m_Screen.y = 0;
+	m_Screen.w = 848.0f;
+	m_Screen.h = 480.0f;
+}
+
+int CUI::Update(float mx, float my, float mwx, float mwy, int Buttons)
 {
-    mouse_x = mx;
-    mouse_y = my;
-    mouse_wx = mwx;
-    mouse_wy = mwy;
-    last_mouse_buttons = mouse_buttons;
-    mouse_buttons = buttons;
-    hot_item = becomming_hot_item;
-    if(active_item)
-    	hot_item = active_item;
-    becomming_hot_item = 0;
+    m_MouseX = mx;
+    m_MouseY = my;
+    m_MouseWorldX = mwx;
+    m_MouseWorldY = mwy;
+    m_LastMouseButtons = m_MouseButtons;
+    m_MouseButtons = Buttons;
+    m_pHotItem = m_pBecommingHotItem;
+    if(m_pActiveItem)
+    	m_pHotItem = m_pActiveItem;
+    m_pBecommingHotItem = 0;
     return 0;
 }
-/*
-bool ui_
-*/
-int ui_mouse_inside(const RECT *r)
+
+int CUI::MouseInside(const CUIRect *r)
 {
-    if(mouse_x >= r->x && mouse_x <= r->x+r->w && mouse_y >= r->y && mouse_y <= r->y+r->h)
+    if(m_MouseX >= r->x && m_MouseX <= r->x+r->w && m_MouseY >= r->y && m_MouseY <= r->y+r->h)
         return 1;
     return 0;
 }
 
-static RECT screen = { 0.0f, 0.0f, 848.0f, 480.0f };
-
-RECT *ui_screen()
+CUIRect *CUI::Screen()
 {
-    float aspect = gfx_screenaspect();
+    float aspect = Graphics()->ScreenAspect();
     float w, h;
 
     h = 600;
     w = aspect*h;
 
-    screen.w = w;
-    screen.h = h;
+    m_Screen.w = w;
+    m_Screen.h = h;
 
-    return &screen;
+    return &m_Screen;
 }
 
-void ui_set_scale(float s)
+void CUI::SetScale(float s)
 {
-    config.ui_scale = (int)(s*100.0f);
+    //config.UI()->Scale = (int)(s*100.0f);
 }
 
-float ui_scale()
+/*float CUI::Scale()
 {
-    return config.ui_scale/100.0f;
-}
+    return config.UI()->Scale/100.0f;
+}*/
 
-void ui_clip_enable(const RECT *r)
+void CUI::ClipEnable(const CUIRect *r)
 {
-	float xscale = gfx_screenwidth()/ui_screen()->w;
-	float yscale = gfx_screenheight()/ui_screen()->h;
-	gfx_clip_enable((int)(r->x*xscale), (int)(r->y*yscale), (int)(r->w*xscale), (int)(r->h*yscale));
+	float xscale = Graphics()->ScreenWidth()/Screen()->w;
+	float yscale = Graphics()->ScreenHeight()/Screen()->h;
+	Graphics()->ClipEnable((int)(r->x*xscale), (int)(r->y*yscale), (int)(r->w*xscale), (int)(r->h*yscale));
 }
 
-void ui_clip_disable()
+void CUI::ClipDisable()
 {
-	gfx_clip_disable();
+	Graphics()->ClipDisable();
 }
 
-void ui_hsplit_t(const RECT *original, float cut, RECT *top, RECT *bottom)
+void CUIRect::HSplitTop(float cut, CUIRect *top, CUIRect *bottom) const
 {
-    RECT r = *original;
-    cut *= ui_scale();
+    CUIRect r = *this;
+    cut *= Scale();
 
     if (top)
     {
@@ -116,10 +110,10 @@ void ui_hsplit_t(const RECT *original, float cut, RECT *top, RECT *bottom)
     }
 }
 
-void ui_hsplit_b(const RECT *original, float cut, RECT *top, RECT *bottom)
+void CUIRect::HSplitBottom(float cut, CUIRect *top, CUIRect *bottom) const
 {
-    RECT r = *original;
-    cut *= ui_scale();
+    CUIRect r = *this;
+    cut *= Scale();
 
     if (top)
     {
@@ -139,9 +133,9 @@ void ui_hsplit_b(const RECT *original, float cut, RECT *top, RECT *bottom)
 }
 
 
-void ui_vsplit_mid(const RECT *original, RECT *left, RECT *right)
+void CUIRect::VSplitMid(CUIRect *left, CUIRect *right) const
 {
-    RECT r = *original;
+    CUIRect r = *this;
     float cut = r.w/2;
 
     if (left)
@@ -161,10 +155,10 @@ void ui_vsplit_mid(const RECT *original, RECT *left, RECT *right)
     }
 }
 
-void ui_vsplit_l(const RECT *original, float cut, RECT *left, RECT *right)
+void CUIRect::VSplitLeft(float cut, CUIRect *left, CUIRect *right) const
 {
-    RECT r = *original;
-    cut *= ui_scale();
+    CUIRect r = *this;
+    cut *= Scale();
 
     if (left)
     {
@@ -183,10 +177,10 @@ void ui_vsplit_l(const RECT *original, float cut, RECT *left, RECT *right)
     }
 }
 
-void ui_vsplit_r(const RECT *original, float cut, RECT *left, RECT *right)
+void CUIRect::VSplitRight(float cut, CUIRect *left, CUIRect *right) const
 {
-    RECT r = *original;
-    cut *= ui_scale();
+    CUIRect r = *this;
+    cut *= Scale();
 
     if (left)
     {
@@ -205,10 +199,10 @@ void ui_vsplit_r(const RECT *original, float cut, RECT *left, RECT *right)
     }
 }
 
-void ui_margin(const RECT *original, float cut, RECT *other_rect)
+void CUIRect::Margin(float cut, CUIRect *other_rect) const
 {
-    RECT r = *original;
-	cut *= ui_scale();
+    CUIRect r = *this;
+	cut *= Scale();
 
     other_rect->x = r.x + cut;
     other_rect->y = r.y + cut;
@@ -216,10 +210,10 @@ void ui_margin(const RECT *original, float cut, RECT *other_rect)
     other_rect->h = r.h - 2*cut;
 }
 
-void ui_vmargin(const RECT *original, float cut, RECT *other_rect)
+void CUIRect::VMargin(float cut, CUIRect *other_rect) const
 {
-    RECT r = *original;
-	cut *= ui_scale();
+    CUIRect r = *this;
+	cut *= Scale();
 
     other_rect->x = r.x + cut;
     other_rect->y = r.y;
@@ -227,10 +221,10 @@ void ui_vmargin(const RECT *original, float cut, RECT *other_rect)
     other_rect->h = r.h;
 }
 
-void ui_hmargin(const RECT *original, float cut, RECT *other_rect)
+void CUIRect::HMargin(float cut, CUIRect *other_rect) const
 {
-    RECT r = *original;
-	cut *= ui_scale();
+    CUIRect r = *this;
+	cut *= Scale();
 
     other_rect->x = r.x;
     other_rect->y = r.y + cut;
@@ -238,50 +232,87 @@ void ui_hmargin(const RECT *original, float cut, RECT *other_rect)
     other_rect->h = r.h - 2*cut;
 }
 
-
-int ui_do_button(const void *id, const char *text, int checked, const RECT *r, ui_draw_button_func draw_func, const void *extra)
+int CUI::DoButtonLogic(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
     /* logic */
+    int ReturnValue = 0;
+    int Inside = MouseInside(pRect);
+	static int ButtonUsed = 0;
+
+	if(ActiveItem() == pID)
+	{
+		if(!MouseButton(ButtonUsed))
+		{
+			if(Inside && Checked >= 0)
+				ReturnValue = 1+ButtonUsed;
+			SetActiveItem(0);
+		}
+	}
+	else if(HotItem() == pID)
+	{
+		if(MouseButton(0))
+		{
+			SetActiveItem(pID);
+			ButtonUsed = 0;
+		}
+		
+		if(MouseButton(1))
+		{
+			SetActiveItem(pID);
+			ButtonUsed = 1;
+		}
+	}
+	
+	if(Inside)
+		SetHotItem(pID);
+
+    return ReturnValue;
+}
+/*
+int CUI::DoButton(const void *id, const char *text, int checked, const CUIRect *r, ui_draw_button_func draw_func, const void *extra)
+{
+    // logic
     int ret = 0;
-    int inside = ui_mouse_inside(r);
+    int inside = ui_MouseInside(r);
 	static int button_used = 0;
 
-	if(ui_active_item() == id)
+	if(ui_ActiveItem() == id)
 	{
-		if(!ui_mouse_button(button_used))
+		if(!ui_MouseButton(button_used))
 		{
 			if(inside && checked >= 0)
 				ret = 1+button_used;
-			ui_set_active_item(0);
+			ui_SetActiveItem(0);
 		}
 	}
-	else if(ui_hot_item() == id)
+	else if(ui_HotItem() == id)
 	{
-		if(ui_mouse_button(0))
+		if(ui_MouseButton(0))
 		{
-			ui_set_active_item(id);
+			ui_SetActiveItem(id);
 			button_used = 0;
 		}
 		
-		if(ui_mouse_button(1))
+		if(ui_MouseButton(1))
 		{
-			ui_set_active_item(id);
+			ui_SetActiveItem(id);
 			button_used = 1;
 		}
 	}
 	
 	if(inside)
-		ui_set_hot_item(id);
+		ui_SetHotItem(id);
 
 	if(draw_func)
     	draw_func(id, text, checked, r, extra);
     return ret;
-}
+}*/
 
-void ui_do_label(const RECT *r, const char *text, float size, int align, int max_width)
+void CUI::DoLabel(const CUIRect *r, const char *text, float size, int align, int max_width)
 {
-    gfx_blend_normal();
-    size *= ui_scale();
+	// TODO: FIX ME!!!!
+    //Graphics()->BlendNormal();
+    size *= Scale();
     if(align == 0)
     {
     	float tw = gfx_text_width(0, size, text, max_width);
diff --git a/src/game/client/ui.hpp b/src/game/client/ui.hpp
index 7a6cb5de..96f6c48b 100644
--- a/src/game/client/ui.hpp
+++ b/src/game/client/ui.hpp
@@ -2,64 +2,93 @@
 #ifndef FILE_GAME_CLIENT_UI_H
 #define FILE_GAME_CLIENT_UI_H
 
-typedef struct 
+class CUIRect
 {
+	// TODO: Refactor: Redo UI scaling
+	float Scale() const { return 1.0f; }
+public:
     float x, y, w, h;
-} RECT;
+	
+	void HSplitTop(float Cut, CUIRect *pTop, CUIRect *pBottom) const;
+	void HSplitBottom(float Cut, CUIRect *pTop, CUIRect *pBottom) const;
+	void VSplitMid(CUIRect *pLeft, CUIRect *pRight) const;
+	void VSplitLeft(float Cut, CUIRect *pLeft, CUIRect *pRight) const;
+	void VSplitRight(float Cut, CUIRect *pLeft, CUIRect *pRight) const;
+
+	void Margin(float Cut, CUIRect *pOtherRect) const;
+	void VMargin(float Cut, CUIRect *pOtherRect) const;
+	void HMargin(float Cut, CUIRect *pOtherRect) const;
+	
+};
 
-enum
+class CUI
 {
-	CORNER_TL=1,
-	CORNER_TR=2,
-	CORNER_BL=4,
-	CORNER_BR=8,
+	const void *m_pHotItem;
+	const void *m_pActiveItem;
+	const void *m_pLastActiveItem;
+	const void *m_pBecommingHotItem;
+	float m_MouseX, m_MouseY; /* in gui space */
+	float m_MouseWorldX, m_MouseWorldY; /* in world space */
+	unsigned m_MouseButtons;
+	unsigned m_LastMouseButtons;
 	
-	CORNER_T=CORNER_TL|CORNER_TR,
-	CORNER_B=CORNER_BL|CORNER_BR,
-	CORNER_R=CORNER_TR|CORNER_BR,
-	CORNER_L=CORNER_TL|CORNER_BL,
+	CUIRect m_Screen;
+	class IGraphics *m_pGraphics;
 	
-	CORNER_ALL=CORNER_T|CORNER_B
-};
+public:
+	// TODO: Refactor: Fill this in
+	void SetGraphics(class IGraphics *pGraphics) { m_pGraphics = pGraphics; }
+	class IGraphics *Graphics() { return m_pGraphics; }
 
-int ui_update(float mx, float my, float mwx, float mwy, int buttons);
+	CUI();
 
-float ui_mouse_x();
-float ui_mouse_y();
-float ui_mouse_world_x();
-float ui_mouse_world_y();
-int ui_mouse_button(int index);
-int ui_mouse_button_clicked(int index);
+	enum
+	{
+		CORNER_TL=1,
+		CORNER_TR=2,
+		CORNER_BL=4,
+		CORNER_BR=8,
+		
+		CORNER_T=CORNER_TL|CORNER_TR,
+		CORNER_B=CORNER_BL|CORNER_BR,
+		CORNER_R=CORNER_TR|CORNER_BR,
+		CORNER_L=CORNER_TL|CORNER_BL,
+		
+		CORNER_ALL=CORNER_T|CORNER_B
+	};
 
-void ui_set_hot_item(const void *id);
-void ui_set_active_item(const void *id);
-void ui_clear_last_active_item();
-const void *ui_hot_item();
-const void *ui_next_hot_item();
-const void *ui_active_item();
-const void *ui_last_active_item();
+	int Update(float mx, float my, float mwx, float mwy, int buttons);
 
-int ui_mouse_inside(const RECT *r);
+	float MouseX() const { return m_MouseX; }
+	float MouseY() const { return m_MouseY; }
+	float MouseWorldX() const { return m_MouseWorldX; }
+	float MouseWorldY() const { return m_MouseWorldY; }
+	int MouseButton(int Index) const { return (m_MouseButtons>>Index)&1; }
+	int MouseButtonClicked(int Index) { return MouseButton(Index) && !((m_LastMouseButtons>>Index)&1) ; }
 
-RECT *ui_screen();
-void ui_set_scale(float s);
-float ui_scale();
-void ui_clip_enable(const RECT *r);
-void ui_clip_disable();
+	void SetHotItem(const void *pID) { m_pBecommingHotItem = pID; }
+	void SetActiveItem(const void *pID) { m_pActiveItem = pID; if (pID) m_pLastActiveItem = pID; }
+	void ClearLastActiveItem() { m_pLastActiveItem = 0; }
+	const void *HotItem() const { return m_pHotItem; }
+	const void *NextHotItem() const { return m_pBecommingHotItem; }
+	const void *ActiveItem() const { return m_pActiveItem; }
+	const void *LastActiveItem() const { return m_pLastActiveItem; }
 
-void ui_hsplit_t(const RECT *original, float cut, RECT *top, RECT *bottom);
-void ui_hsplit_b(const RECT *original, float cut, RECT *top, RECT *bottom);
-void ui_vsplit_mid(const RECT *original, RECT *left, RECT *right);
-void ui_vsplit_l(const RECT *original, float cut, RECT *left, RECT *right);
-void ui_vsplit_r(const RECT *original, float cut, RECT *left, RECT *right);
+	int MouseInside(const CUIRect *r);
 
-void ui_margin(const RECT *original, float cut, RECT *other_rect);
-void ui_vmargin(const RECT *original, float cut, RECT *other_rect);
-void ui_hmargin(const RECT *original, float cut, RECT *other_rect);
+	CUIRect *Screen();
+	void ClipEnable(const CUIRect *r);
+	void ClipDisable();
+	
+	// TODO: Refactor: Redo UI scaling
+	void SetScale(float s);
+	float Scale() const { return 1.0f; }
 
-typedef void (*ui_draw_button_func)(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-int ui_do_button(const void *id, const char *text, int checked, const RECT *r, ui_draw_button_func draw_func, const void *extra);
-void ui_do_label(const RECT *r, const char *text, float size, int align, int max_width = -1);
+	int DoButtonLogic(const void *pID, const char *pText /* TODO: Refactor: Remove */, int Checked, const CUIRect *pRect);
+	
+	// TODO: Refactor: Remove this?
+	void DoLabel(const CUIRect *r, const char *text, float size, int align, int max_width = -1);
+};
 
 
 #endif
diff --git a/src/game/editor/ed_editor.cpp b/src/game/editor/ed_editor.cpp
index d56a0506..17b891fc 100644
--- a/src/game/editor/ed_editor.cpp
+++ b/src/game/editor/ed_editor.cpp
@@ -6,12 +6,11 @@
 #include <stdlib.h>
 #include <string.h>
 
-extern "C" {
-	#include <engine/e_common_interface.h>
-	#include <engine/e_datafile.h>
-	#include <engine/e_config.h>
-	#include <engine/e_engine.h>
-}
+#include <engine/e_common_interface.h>
+#include <engine/e_datafile.h>
+#include <engine/e_config.h>
+#include <engine/e_engine.h>
+#include <engine/client/graphics.h>
 
 #include <game/client/ui.hpp>
 #include <game/gamecore.hpp>
@@ -25,10 +24,19 @@ static int background_texture = 0;
 static int cursor_texture = 0;
 static int entities_texture = 0;
 
+enum
+{
+	BUTTON_CONTEXT=1,
+};
 
-static const void *ui_got_context = 0;
 
-EDITOR editor;
+
+EDITOR_IMAGE::~EDITOR_IMAGE()
+{
+	editor->Graphics()->UnloadTexture(tex_id);
+}
+
+static const void *ui_got_context = 0;
 
 LAYERGROUP::LAYERGROUP()
 {
@@ -52,7 +60,7 @@ LAYERGROUP::~LAYERGROUP()
 	clear();
 }
 
-void LAYERGROUP::convert(RECT *rect)
+void LAYERGROUP::convert(CUIRect *rect)
 {
 	rect->x += offset_x;
 	rect->y += offset_y;
@@ -60,52 +68,53 @@ void LAYERGROUP::convert(RECT *rect)
 
 void LAYERGROUP::mapping(float *points)
 {
-	mapscreen_to_world(
-		editor.world_offset_x, editor.world_offset_y,
+	m_pMap->editor->RenderTools()->mapscreen_to_world(
+		m_pMap->editor->world_offset_x, m_pMap->editor->world_offset_y,
 		parallax_x/100.0f, parallax_y/100.0f,
 		offset_x, offset_y,
-		gfx_screenaspect(), editor.world_zoom, points);
+		m_pMap->editor->Graphics()->ScreenAspect(), m_pMap->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;
+	points[0] += m_pMap->editor->editor_offset_x;
+	points[1] += m_pMap->editor->editor_offset_y;
+	points[2] += m_pMap->editor->editor_offset_x;
+	points[3] += m_pMap->editor->editor_offset_y;
 }
 
 void LAYERGROUP::mapscreen()
 {
 	float points[4];
 	mapping(points);
-	gfx_mapscreen(points[0], points[1], points[2], points[3]);
+	m_pMap->editor->Graphics()->MapScreen(points[0], points[1], points[2], points[3]);
 }
 
 void LAYERGROUP::render()
 {
 	mapscreen();
+	IGraphics *pGraphics = m_pMap->editor->Graphics();
 	
 	if(use_clipping)
 	{
 		float points[4];
-		editor.map.game_group->mapping(points);
+		m_pMap->game_group->mapping(points);
 		float x0 = (clip_x - points[0]) / (points[2]-points[0]);
 		float y0 = (clip_y - points[1]) / (points[3]-points[1]);
 		float x1 = ((clip_x+clip_w) - points[0]) / (points[2]-points[0]);
 		float y1 = ((clip_y+clip_h) - points[1]) / (points[3]-points[1]);
 		
-		gfx_clip_enable((int)(x0*gfx_screenwidth()), (int)(y0*gfx_screenheight()),
-			(int)((x1-x0)*gfx_screenwidth()), (int)((y1-y0)*gfx_screenheight()));
+		pGraphics->ClipEnable((int)(x0*pGraphics->ScreenWidth()), (int)(y0*pGraphics->ScreenHeight()),
+			(int)((x1-x0)*pGraphics->ScreenWidth()), (int)((y1-y0)*pGraphics->ScreenHeight()));
 	}
 	
 	for(int i = 0; i < layers.len(); i++)
 	{
-		if(layers[i]->visible && layers[i] != editor.map.game_layer)
+		if(layers[i]->visible && layers[i] != m_pMap->game_layer)
 		{
-			if(editor.show_detail || !(layers[i]->flags&LAYERFLAG_DETAIL))
+			if(m_pMap->editor->show_detail || !(layers[i]->flags&LAYERFLAG_DETAIL))
 				layers[i]->render();
 		}
 	}
 	
-	gfx_clip_disable();
+	pGraphics->ClipDisable();
 }
 
 bool LAYERGROUP::is_empty() const { return layers.len() == 0; }
@@ -178,21 +187,105 @@ void EDITOR_IMAGE::analyse_tileflags()
 *********************************************************/
 
 // copied from gc_menu.cpp, should be more generalized
-//extern int ui_do_edit_box(void *id, const RECT *rect, char *str, int str_size, float font_size, bool hidden=false);
+//extern int ui_do_edit_box(void *id, const CUIRect *rect, char *str, int str_size, float font_size, bool hidden=false);
 
-int ui_do_edit_box(void *id, const RECT *rect, char *str, int str_size, float font_size, bool hidden=false)
+int EDITOR::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden)
 {
-    int inside = ui_mouse_inside(rect);
+    int Inside = UI()->MouseInside(pRect);
+	int ReturnValue = 0;
+	static int AtIndex = 0;
+
+	if(UI()->LastActiveItem() == pID)
+	{
+		int Len = strlen(pStr);
+			
+		if(Inside && UI()->MouseButton(0))
+		{
+			int mx_rel = (int)(UI()->MouseX() - pRect->x);
+
+			for (int i = 1; i <= Len; i++)
+			{
+				if (gfx_text_width(0, FontSize, pStr, i) + 10 > mx_rel)
+				{
+					AtIndex = i - 1;
+					break;
+				}
+
+				if (i == Len)
+					AtIndex = Len;
+			}
+		}
+
+		for(int i = 0; i < inp_num_events(); i++)
+		{
+			Len = strlen(pStr);
+			LINEINPUT::manipulate(inp_get_event(i), pStr, StrSize, &Len, &AtIndex);
+		}
+	}
+
+	bool JustGotActive = false;
+	
+	if(UI()->ActiveItem() == pID)
+	{
+		if(!UI()->MouseButton(0))
+			UI()->SetActiveItem(0);
+	}
+	else if(UI()->HotItem() == pID)
+	{
+		if(UI()->MouseButton(0))
+		{
+			if (UI()->LastActiveItem() != pID)
+				JustGotActive = true;
+			UI()->SetActiveItem(pID);
+		}
+	}
+	
+	if(Inside)
+		UI()->SetHotItem(pID);
+
+	CUIRect Textbox = *pRect;
+	RenderTools()->DrawUIRect(&Textbox, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 5.0f);
+	Textbox.VMargin(5.0f, &Textbox);
+	
+	const char *pDisplayStr = pStr;
+	char aStars[128];
+	
+	if(Hidden)
+	{
+		unsigned s = strlen(pStr);
+		if(s >= sizeof(aStars))
+			s = sizeof(aStars)-1;
+		memset(aStars, '*', s);
+		aStars[s] = 0;
+		pDisplayStr = aStars;
+	}
+
+	UI()->DoLabel(&Textbox, pDisplayStr, FontSize, -1);
+	
+	if (UI()->LastActiveItem() == pID && !JustGotActive)
+	{
+		float w = gfx_text_width(0, FontSize, pDisplayStr, AtIndex);
+		Textbox.x += w*UI()->Scale();
+		UI()->DoLabel(&Textbox, "_", FontSize, -1);
+	}
+
+	return ReturnValue;
+}
+
+/*
+int ui_do_edit_box(void *id, const CUIRect *rect, char *str, int str_size, float font_size, bool hidden=false)
+{
+    int inside = UI()->MouseInside(rect);
 	int r = 0;
 	static int at_index = 0;
 
-	if(ui_last_active_item() == id)
+	if(UI()->LastActiveItem() == id)
 	{
 		int len = strlen(str);
 
-		if (inside && ui_mouse_button(0))
+		if (inside && UI()->MouseButton(0))
 		{
-			int mx_rel = (int)(ui_mouse_x() - rect->x);
+			int mx_rel = (int)(UI()->MouseX() - rect->x);
 
 			for (int i = 1; i <= len; i++)
 			{
@@ -218,27 +311,27 @@ int ui_do_edit_box(void *id, const RECT *rect, char *str, int str_size, float fo
 
 	bool just_got_active = false;
 	
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == id)
 	{
-		if(!ui_mouse_button(0))
-			ui_set_active_item(0);
+		if(!UI()->MouseButton(0))
+			UI()->SetActiveItem(0);
 	}
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == id)
 	{
-		if(ui_mouse_button(0))
+		if(UI()->MouseButton(0))
 		{
-			if (ui_last_active_item() != id)
+			if (UI()->LastActiveItem() != id)
 				just_got_active = true;
-			ui_set_active_item(id);
+			UI()->SetActiveItem(id);
 		}
 	}
 	
 	if(inside)
-		ui_set_hot_item(id);
+		UI()->SetHotItem(id);
 
-	RECT textbox = *rect;
-	ui_draw_rect(&textbox, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f);
-	ui_vmargin(&textbox, 5.0f, &textbox);
+	CUIRect textbox = *rect;
+	RenderTools()->DrawUIRect(&textbox, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 5.0f);
+	textbox.VMargin(5.0f, &textbox);
 	
 	const char *display_str = str;
 	char stars[128];
@@ -253,197 +346,251 @@ int ui_do_edit_box(void *id, const RECT *rect, char *str, int str_size, float fo
 		display_str = stars;
 	}
 
-	ui_do_label(&textbox, display_str, font_size, -1);
+	UI()->DoLabel(&textbox, display_str, font_size, -1);
 	
-	if (ui_last_active_item() == id && !just_got_active)
+	if (UI()->LastActiveItem() == id && !just_got_active)
 	{
 		float w = gfx_text_width(0, font_size, display_str, at_index);
-		textbox.x += w*ui_scale();
-		ui_do_label(&textbox, "_", font_size, -1);
+		textbox.x += w*UI()->Scale();
+		UI()->DoLabel(&textbox, "_", font_size, -1);
 	}
 
 	return r;
 }
+*/
 
-vec4 button_color_mul(const void *id)
+vec4 EDITOR::button_color_mul(const void *id)
 {
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == id)
 		return vec4(1,1,1,0.5f);
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == id)
 		return vec4(1,1,1,1.5f);
 	return vec4(1,1,1,1);
 }
 
-float ui_do_scrollbar_v(const void *id, const RECT *rect, float current)
+float EDITOR::ui_do_scrollbar_v(const void *id, const CUIRect *rect, float current)
 {
-	RECT handle;
+	CUIRect handle;
 	static float offset_y;
-	ui_hsplit_t(rect, 33, &handle, 0);
+	rect->HSplitTop(33, &handle, 0);
 
 	handle.y += (rect->h-handle.h)*current;
 
 	/* logic */
     float ret = current;
-    int inside = ui_mouse_inside(&handle);
+    int inside = UI()->MouseInside(&handle);
 
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == id)
 	{
-		if(!ui_mouse_button(0))
-			ui_set_active_item(0);
+		if(!UI()->MouseButton(0))
+			UI()->SetActiveItem(0);
 		
 		float min = rect->y;
 		float max = rect->h-handle.h;
-		float cur = ui_mouse_y()-offset_y;
+		float cur = UI()->MouseY()-offset_y;
 		ret = (cur-min)/max;
 		if(ret < 0.0f) ret = 0.0f;
 		if(ret > 1.0f) ret = 1.0f;
 	}
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == id)
 	{
-		if(ui_mouse_button(0))
+		if(UI()->MouseButton(0))
 		{
-			ui_set_active_item(id);
-			offset_y = ui_mouse_y()-handle.y;
+			UI()->SetActiveItem(id);
+			offset_y = UI()->MouseY()-handle.y;
 		}
 	}
 	
 	if(inside)
-		ui_set_hot_item(id);
+		UI()->SetHotItem(id);
 
 	// render
-	RECT rail;
-	ui_vmargin(rect, 5.0f, &rail);
-	ui_draw_rect(&rail, vec4(1,1,1,0.25f), 0, 0.0f);
+	CUIRect rail;
+	rect->VMargin(5.0f, &rail);
+	RenderTools()->DrawUIRect(&rail, vec4(1,1,1,0.25f), 0, 0.0f);
 
-	RECT slider = handle;
+	CUIRect slider = handle;
 	slider.w = rail.x-slider.x;
-	ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_L, 2.5f);
+	RenderTools()->DrawUIRect(&slider, vec4(1,1,1,0.25f), CUI::CORNER_L, 2.5f);
 	slider.x = rail.x+rail.w;
-	ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_R, 2.5f);
+	RenderTools()->DrawUIRect(&slider, vec4(1,1,1,0.25f), CUI::CORNER_R, 2.5f);
 
 	slider = handle;
-	ui_margin(&slider, 5.0f, &slider);
-	ui_draw_rect(&slider, vec4(1,1,1,0.25f)*button_color_mul(id), CORNER_ALL, 2.5f);
+	slider.Margin(5.0f, &slider);
+	RenderTools()->DrawUIRect(&slider, vec4(1,1,1,0.25f)*button_color_mul(id), CUI::CORNER_ALL, 2.5f);
 	
     return ret;
 }
 
-static vec4 get_button_color(const void *id, int checked)
+vec4 EDITOR::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)
+		if(UI()->HotItem() == id)
 			return vec4(1,0,0,0.75f);
 		return vec4(1,0,0,0.5f);
 	}
 	
-	if(ui_hot_item() == id)
+	if(UI()->HotItem() == id)
 		return vec4(1,1,1,0.75f);
 	return vec4(1,1,1,0.5f);
 }
 
-void draw_editor_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int EDITOR::DoButton_Editor_Common(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
 {
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), CORNER_ALL, 3.0f);
-	ui_do_label(r, text, 10, 0, -1);
+	if(UI()->MouseInside(pRect))
+	{
+		if(Flags&BUTTON_CONTEXT)
+			ui_got_context = pID;
+		if(tooltip)
+			tooltip = pToolTip;
+	}
+	
+	if(UI()->HotItem() == pID && pToolTip)
+		tooltip = (const char *)pToolTip;
+	
+	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
+
+	// Draw here
+	//return UI()->DoButton(id, text, checked, r, draw_func, 0);
+}
+
+
+int EDITOR::DoButton_Editor(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
+{
+	RenderTools()->DrawUIRect(pRect, get_button_color(pID, Checked), CUI::CORNER_ALL, 3.0f);
+	UI()->DoLabel(pRect, pText, 10, 0, -1);
+	return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip);
 }
 
-static void draw_editor_button_file(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int EDITOR::DoButton_File(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
 {
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	if(ui_hot_item() == id)
-		ui_draw_rect(r, get_button_color(id, checked), CORNER_ALL, 3.0f);
+	if(UI()->HotItem() == pID)
+		RenderTools()->DrawUIRect(pRect, get_button_color(pID, Checked), CUI::CORNER_ALL, 3.0f);
 	
-	RECT t = *r;
-	ui_vmargin(&t, 5.0f, &t);
-	ui_do_label(&t, text, 10, -1, -1);
+	CUIRect t = *pRect;
+	t.VMargin(5.0f, &t);
+	UI()->DoLabel(&t, pText, 10, -1, -1);
+	return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip);
 }
 
-static void draw_editor_button_menu(const void *id, const char *text, int checked, const RECT *rect, const void *extra)
+//static void draw_editor_button_menu(const void *id, const char *text, int checked, const CUIRect *rect, const void *extra)
+int EDITOR::DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
 {
 	/*
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	if(ui_hot_item() == id)
-		ui_draw_rect(r, get_button_color(id, checked), CORNER_ALL, 3.0f);
+	if(UI()->HotItem() == id) if(extra) editor.tooltip = (const char *)extra;
+	if(UI()->HotItem() == id)
+		RenderTools()->DrawUIRect(r, get_button_color(id, checked), CUI::CORNER_ALL, 3.0f);
 	*/
 
-	RECT r = *rect;
+	CUIRect r = *pRect;
 	/*
 	if(ui_popups[id == id)
 	{
-		ui_draw_rect(&r, vec4(0.5f,0.5f,0.5f,0.75f), CORNER_T, 3.0f);
-		ui_margin(&r, 1.0f, &r);
-		ui_draw_rect(&r, vec4(0,0,0,0.75f), CORNER_T, 3.0f);
+		RenderTools()->DrawUIRect(&r, vec4(0.5f,0.5f,0.5f,0.75f), CUI::CORNER_T, 3.0f);
+		r.Margin(1.0f, &r);
+		RenderTools()->DrawUIRect(&r, vec4(0,0,0,0.75f), CUI::CORNER_T, 3.0f);
 	}
 	else*/
-		ui_draw_rect(&r, vec4(0.5f,0.5f,0.5f, 1.0f), CORNER_T, 3.0f);
+		RenderTools()->DrawUIRect(&r, vec4(0.5f,0.5f,0.5f, 1.0f), CUI::CORNER_T, 3.0f);
 	
 
-	r = *rect;
-	ui_vmargin(&r, 5.0f, &r);
-	ui_do_label(&r, text, 10, -1, -1);
+	r = *pRect;
+	r.VMargin(5.0f, &r);
+	UI()->DoLabel(&r, pText, 10, -1, -1);
+	
+	return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip);
 	
-	//RECT t = *r;
+	//CUIRect t = *r;
 }
 
-void draw_editor_button_menuitem(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int EDITOR::DoButton_MenuItem(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
 {
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	if(ui_hot_item() == id || checked)
-		ui_draw_rect(r, get_button_color(id, checked), CORNER_ALL, 3.0f);
+	if(UI()->HotItem() == pID || Checked)
+		RenderTools()->DrawUIRect(pRect, get_button_color(pID, Checked), CUI::CORNER_ALL, 3.0f);
 	
-	RECT t = *r;
-	ui_vmargin(&t, 5.0f, &t);
-	ui_do_label(&t, text, 10, -1, -1);
+	CUIRect t = *pRect;
+	t.VMargin(5.0f, &t);
+	UI()->DoLabel(&t, pText, 10, -1, -1);
+	return DoButton_Editor_Common(pID, pText, Checked, pRect, 0, 0);
 }
 
-static void draw_editor_button_l(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int EDITOR::DoButton_ButtonL(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
 {
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), CORNER_L, 3.0f);
-	ui_do_label(r, text, 10, 0, -1);
+	RenderTools()->DrawUIRect(pRect, get_button_color(pID, Checked), CUI::CORNER_L, 3.0f);
+	UI()->DoLabel(pRect, pText, 10, 0, -1);
+	return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip);
 }
 
-static void draw_editor_button_m(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int EDITOR::DoButton_ButtonM(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
 {
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), 0, 3.0f);
-	ui_do_label(r, text, 10, 0, -1);
+	RenderTools()->DrawUIRect(pRect, get_button_color(pID, Checked), 0, 3.0f);
+	UI()->DoLabel(pRect, pText, 10, 0, -1);
+	return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip);
 }
 
-static void draw_editor_button_r(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int EDITOR::DoButton_ButtonR(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
 {
-	if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), CORNER_R, 3.0f);
-	ui_do_label(r, text, 10, 0, -1);
+	RenderTools()->DrawUIRect(pRect, get_button_color(pID, Checked), CUI::CORNER_R, 3.0f);
+	UI()->DoLabel(pRect, pText, 10, 0, -1);
+	return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip);
 }
 
-static void draw_inc_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int EDITOR::DoButton_ButtonInc(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
 {
-	if(ui_hot_item == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), CORNER_R, 3.0f);
-	ui_do_label(r, text?text:">", 10, 0, -1);
+	RenderTools()->DrawUIRect(pRect, get_button_color(pID, Checked), CUI::CORNER_R, 3.0f);
+	UI()->DoLabel(pRect, pText?pText:">", 10, 0, -1);
+	return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip);
 }
 
-static void draw_dec_button(const void *id, const char *text, int checked, const RECT *r, const void *extra)
+int EDITOR::DoButton_ButtonDec(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
 {
-	if(ui_hot_item == id) if(extra) editor.tooltip = (const char *)extra;
-	ui_draw_rect(r, get_button_color(id, checked), CORNER_L, 3.0f);
-	ui_do_label(r, text?text:"<", 10, 0, -1);
+	RenderTools()->DrawUIRect(pRect, get_button_color(pID, Checked), CUI::CORNER_L, 3.0f);
+	UI()->DoLabel(pRect, pText?pText:"<", 10, 0, -1);
+	return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip);
 }
 
-enum
+/*
+static void draw_editor_button_l(const void *id, const char *text, int checked, const CUIRect *r, const void *extra)
 {
-	BUTTON_CONTEXT=1,
-};
+	RenderTools()->DrawUIRect(r, get_button_color(id, checked), CUI::CORNER_L, 3.0f);
+	UI()->DoLabel(r, text, 10, 0, -1);
+}
+
+static void draw_editor_button_m(const void *id, const char *text, int checked, const CUIRect *r, const void *extra)
+{
+	if(UI()->HotItem() == id) if(extra) editor.tooltip = (const char *)extra;
+	RenderTools()->DrawUIRect(r, get_button_color(id, checked), 0, 3.0f);
+	UI()->DoLabel(r, text, 10, 0, -1);
+}
+
+static void draw_editor_button_r(const void *id, const char *text, int checked, const CUIRect *r, const void *extra)
+{
+	if(UI()->HotItem() == id) if(extra) editor.tooltip = (const char *)extra;
+	RenderTools()->DrawUIRect(r, get_button_color(id, checked), CUI::CORNER_R, 3.0f);
+	UI()->DoLabel(r, text, 10, 0, -1);
+}
+
+static void draw_inc_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra)
+{
+	if(UI()->HotItem == id) if(extra) editor.tooltip = (const char *)extra;
+	RenderTools()->DrawUIRect(r, get_button_color(id, checked), CUI::CORNER_R, 3.0f);
+	UI()->DoLabel(r, text?text:">", 10, 0, -1);
+}
 
-int do_editor_button(const void *id, const char *text, int checked, const RECT *r, ui_draw_button_func draw_func, int flags, const char *tooltip)
+static void draw_dec_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra)
 {
-	if(ui_mouse_inside(r))
+	if(UI()->HotItem == id) if(extra) editor.tooltip = (const char *)extra;
+	RenderTools()->DrawUIRect(r, get_button_color(id, checked), CUI::CORNER_L, 3.0f);
+	UI()->DoLabel(r, text?text:"<", 10, 0, -1);
+}
+
+int do_editor_button(const void *id, const char *text, int checked, const CUIRect *r, ui_draw_button_func draw_func, int flags, const char *tooltip)
+{
+	if(UI()->MouseInside(r))
 	{
 		if(flags&BUTTON_CONTEXT)
 			ui_got_context = id;
@@ -451,46 +598,46 @@ int do_editor_button(const void *id, const char *text, int checked, const RECT *
 			editor.tooltip = tooltip;
 	}
 	
-	return ui_do_button(id, text, checked, r, draw_func, 0);
-}
+	return UI()->DoButton(id, text, checked, r, draw_func, 0);
+}*/
 
 
-static void render_background(RECT view, int texture, float size, float brightness)
+void EDITOR::render_background(CUIRect 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();
+	Graphics()->TextureSet(texture);
+	Graphics()->BlendNormal();
+	Graphics()->QuadsBegin();
+	Graphics()->SetColor(brightness,brightness,brightness,1.0f);
+	Graphics()->QuadsSetSubset(0,0, view.w/size, view.h/size);
+	Graphics()->QuadsDrawTL(view.x, view.y, view.w, view.h);
+	Graphics()->QuadsEnd();
 }
 
 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)
+int EDITOR::ui_do_value_selector(void *id, CUIRect *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);
+    int inside = UI()->MouseInside(r);
 
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == id)
 	{
-		if(!ui_mouse_button(0))
+		if(!UI()->MouseButton(0))
 		{
 			if(inside)
 				ret = 1;
-			editor.lock_mouse = false;
-			ui_set_active_item(0);
+			lock_mouse = false;
+			UI()->SetActiveItem(0);
 		}
 		else
 		{
 			if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-				value += editor.mouse_delta_x*0.05f;
+				value += mouse_delta_x*0.05f;
 			else
-				value += editor.mouse_delta_x;
+				value += mouse_delta_x;
 			
 			if(fabs(value) > scale)
 			{
@@ -504,31 +651,31 @@ static int ui_do_value_selector(void *id, RECT *r, const char *label, int curren
 			}
 		}
 	}
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == id)
 	{
-		if(ui_mouse_button(0))
+		if(UI()->MouseButton(0))
 		{
-			editor.lock_mouse = true;
+			lock_mouse = true;
 			value = 0;
-			ui_set_active_item(id);
+			UI()->SetActiveItem(id);
 		}
 	}
 	
 	if(inside)
-		ui_set_hot_item(id);
+		UI()->SetHotItem(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, 10, 0, -1);
+	RenderTools()->DrawUIRect(r, get_button_color(id, 0), CUI::CORNER_ALL, 5.0f);
+	UI()->DoLabel(r, buf, 10, 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];
+	if(selected_group >= 0 && selected_group < map.groups.len())
+		return map.groups[selected_group];
 	return 0x0;
 }
 
@@ -538,7 +685,7 @@ LAYER *EDITOR::get_selected_layer(int index)
 	if(!group)
 		return 0x0;
 
-	if(selected_layer >= 0 && selected_layer < editor.map.groups[selected_group]->layers.len())
+	if(selected_layer >= 0 && selected_layer < map.groups[selected_group]->layers.len())
 		return group->layers[selected_layer];
 	return 0x0;
 }
@@ -561,108 +708,108 @@ QUAD *EDITOR::get_selected_quad()
 	return 0;
 }
 
-static void callback_open_map(const char *filename) { editor.load(filename); }
-static void callback_append_map(const char *filename) { editor.append(filename); }
-static void callback_save_map(const char *filename) { editor.save(filename); }
+static void callback_open_map(const char *filename, void *user) { ((EDITOR*)user)->load(filename); }
+static void callback_append_map(const char *filename, void *user) { ((EDITOR*)user)->append(filename); }
+static void callback_save_map(const char *filename, void *user) { ((EDITOR*)user)->save(filename); }
 
-static void do_toolbar(RECT toolbar)
+void EDITOR::do_toolbar(CUIRect toolbar)
 {
-	RECT button;
+	CUIRect button;
 	
 	// ctrl+o to open
 	if(inp_key_down('o') && (inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL)))
-		editor.invoke_file_dialog(LISTDIRTYPE_ALL, "Open Map", "Open", "maps/", "", callback_open_map);
+		invoke_file_dialog(LISTDIRTYPE_ALL, "Open Map", "Open", "maps/", "", callback_open_map, this);
 	
 	// ctrl+s to save
 	if(inp_key_down('s') && (inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL)))
-		editor.invoke_file_dialog(LISTDIRTYPE_SAVE, "Save Map", "Save", "maps/", "", callback_save_map);
+		invoke_file_dialog(LISTDIRTYPE_SAVE, "Save Map", "Save", "maps/", "", callback_save_map, this);
 
 	// detail button
-	ui_vsplit_l(&toolbar, 30.0f, &button, &toolbar);
+	toolbar.VSplitLeft(30.0f, &button, &toolbar);
 	static int hq_button = 0;
-	if(do_editor_button(&hq_button, "Detail", editor.show_detail, &button, draw_editor_button, 0, "[ctrl+h] Toggle High Detail") ||
+	if(DoButton_Editor(&hq_button, "Detail", show_detail, &button, 0, "[ctrl+h] Toggle High Detail") ||
 		(inp_key_down('h') && (inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL))))
 	{
-		editor.show_detail = !editor.show_detail;
+		show_detail = !show_detail;
 	}
 
-	ui_vsplit_l(&toolbar, 5.0f, 0, &toolbar);
+	toolbar.VSplitLeft(5.0f, 0, &toolbar);
 	
 	// animation button
-	ui_vsplit_l(&toolbar, 30.0f, &button, &toolbar);
+	toolbar.VSplitLeft(30.0f, &button, &toolbar);
 	static int animate_button = 0;
-	if(do_editor_button(&animate_button, "Anim", editor.animate, &button, draw_editor_button, 0, "[ctrl+m] Toggle animation") ||
+	if(DoButton_Editor(&animate_button, "Anim", animate, &button, 0, "[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;
+		animate_start = time_get();
+		animate = !animate;
 	}
 
-	ui_vsplit_l(&toolbar, 5.0f, 0, &toolbar);
+	toolbar.VSplitLeft(5.0f, 0, &toolbar);
 
 	// proof button
-	ui_vsplit_l(&toolbar, 30.0f, &button, &toolbar);
+	toolbar.VSplitLeft(30.0f, &button, &toolbar);
 	static int proof_button = 0;
-	if(do_editor_button(&proof_button, "Proof", editor.proof_borders, &button, draw_editor_button, 0, "[ctrl-p] Toggles proof borders. These borders represent what a player maximum can see.") ||
+	if(DoButton_Editor(&proof_button, "Proof", proof_borders, &button, 0, "[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;
+		proof_borders = !proof_borders;
 	}
 
-	ui_vsplit_l(&toolbar, 15.0f, 0, &toolbar);
+	toolbar.VSplitLeft(15.0f, 0, &toolbar);
 	
 	// zoom group
-	ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar);
+	toolbar.VSplitLeft(16.0f, &button, &toolbar);
 	static int zoom_out_button = 0;
-	if(do_editor_button(&zoom_out_button, "ZO", 0, &button, draw_editor_button_l, 0, "[NumPad-] Zoom out") || inp_key_down(KEY_KP_MINUS))
-		editor.zoom_level += 50;
+	if(DoButton_ButtonL(&zoom_out_button, "ZO", 0, &button, 0, "[NumPad-] Zoom out") || inp_key_down(KEY_KP_MINUS))
+		zoom_level += 50;
 		
-	ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar);
+	toolbar.VSplitLeft(16.0f, &button, &toolbar);
 	static int zoom_normal_button = 0;
-	if(do_editor_button(&zoom_normal_button, "1:1", 0, &button, draw_editor_button_m, 0, "[NumPad*] Zoom to normal and remove editor offset") || inp_key_down(KEY_KP_MULTIPLY))
+	if(DoButton_ButtonM(&zoom_normal_button, "1:1", 0, &button, 0, "[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;
+		editor_offset_x = 0;
+		editor_offset_y = 0;
+		zoom_level = 100;
 	}
 		
-	ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar);
+	toolbar.VSplitLeft(16.0f, &button, &toolbar);
 	static int zoom_in_button = 0;
-	if(do_editor_button(&zoom_in_button, "ZI", 0, &button, draw_editor_button_r, 0, "[NumPad+] Zoom in") || inp_key_down(KEY_KP_PLUS))
-		editor.zoom_level -= 50;
+	if(DoButton_ButtonR(&zoom_in_button, "ZI", 0, &button, 0, "[NumPad+] Zoom in") || inp_key_down(KEY_KP_PLUS))
+		zoom_level -= 50;
 	
-	ui_vsplit_l(&toolbar, 15.0f, 0, &toolbar);
+	toolbar.VSplitLeft(15.0f, 0, &toolbar);
 	
 	// animation speed
-	ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar);
+	toolbar.VSplitLeft(16.0f, &button, &toolbar);
 	static int anim_faster_button = 0;
-	if(do_editor_button(&anim_faster_button, "A+", 0, &button, draw_editor_button_l, 0, "Increase animation speed"))
-		editor.animate_speed += 0.5f;
+	if(DoButton_ButtonL(&anim_faster_button, "A+", 0, &button, 0, "Increase animation speed"))
+		animate_speed += 0.5f;
 	
-	ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar);
+	toolbar.VSplitLeft(16.0f, &button, &toolbar);
 	static int anim_normal_button = 0;
-	if(do_editor_button(&anim_normal_button, "1", 0, &button, draw_editor_button_m, 0, "Normal animation speed"))
-		editor.animate_speed = 1.0f;
+	if(DoButton_ButtonM(&anim_normal_button, "1", 0, &button, 0, "Normal animation speed"))
+		animate_speed = 1.0f;
 	
-	ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar);
+	toolbar.VSplitLeft(16.0f, &button, &toolbar);
 	static int anim_slower_button = 0;
-	if(do_editor_button(&anim_slower_button, "A-", 0, &button, draw_editor_button_r, 0, "Decrease animation speed"))
+	if(DoButton_ButtonR(&anim_slower_button, "A-", 0, &button, 0, "Decrease animation speed"))
 	{
-		if(editor.animate_speed > 0.5f)
-			editor.animate_speed -= 0.5f;
+		if(animate_speed > 0.5f)
+			animate_speed -= 0.5f;
 	}
 	
-	if(inp_key_presses(KEY_MOUSE_WHEEL_UP) && editor.dialog == DIALOG_NONE)
-		editor.zoom_level -= 20;
+	if(inp_key_presses(KEY_MOUSE_WHEEL_UP) && dialog == DIALOG_NONE)
+		zoom_level -= 20;
 		
-	if(inp_key_presses(KEY_MOUSE_WHEEL_DOWN) && editor.dialog == DIALOG_NONE)
-		editor.zoom_level += 20;
+	if(inp_key_presses(KEY_MOUSE_WHEEL_DOWN) && dialog == DIALOG_NONE)
+		zoom_level += 20;
 	
-	if(editor.zoom_level < 50)
-		editor.zoom_level = 50;
-	editor.world_zoom = editor.zoom_level/100.0f;
+	if(zoom_level < 50)
+		zoom_level = 50;
+	world_zoom = zoom_level/100.0f;
 
-	ui_vsplit_l(&toolbar, 10.0f, &button, &toolbar);
+	toolbar.VSplitLeft(10.0f, &button, &toolbar);
 
 
 	// brush manipulation
@@ -670,41 +817,41 @@ static void do_toolbar(RECT toolbar)
 		int enabled = brush.is_empty()?-1:0;
 		
 		// flip buttons
-		ui_vsplit_l(&toolbar, 20.0f, &button, &toolbar);
+		toolbar.VSplitLeft(20.0f, &button, &toolbar);
 		static int flipx_button = 0;
-		if(do_editor_button(&flipx_button, "^X", enabled, &button, draw_editor_button_l, 0, "[N] Flip brush horizontal") || inp_key_down('n'))
+		if(DoButton_ButtonL(&flipx_button, "^X", enabled, &button, 0, "[N] Flip brush horizontal") || inp_key_down('n'))
 		{
 			for(int i = 0; i < brush.layers.len(); i++)
 				brush.layers[i]->brush_flip_x();
 		}
 			
-		ui_vsplit_l(&toolbar, 20.0f, &button, &toolbar);
+		toolbar.VSplitLeft(20.0f, &button, &toolbar);
 		static int flipy_button = 0;
-		if(do_editor_button(&flipy_button, "^Y", enabled, &button, draw_editor_button_r, 0, "[M] Flip brush vertical") || inp_key_down('m'))
+		if(DoButton_ButtonR(&flipy_button, "^Y", enabled, &button, 0, "[M] Flip brush vertical") || inp_key_down('m'))
 		{
 			for(int i = 0; i < brush.layers.len(); i++)
 				brush.layers[i]->brush_flip_y();
 		}
 
 		// rotate buttons
-		ui_vsplit_l(&toolbar, 20.0f, &button, &toolbar);
+		toolbar.VSplitLeft(20.0f, &button, &toolbar);
 		
-		ui_vsplit_l(&toolbar, 30.0f, &button, &toolbar);
+		toolbar.VSplitLeft(30.0f, &button, &toolbar);
 		static int rotation_amount = 90;
 		rotation_amount = ui_do_value_selector(&rotation_amount, &button, "", rotation_amount, 1, 360, 2.0f);
 		
-		ui_vsplit_l(&toolbar, 5.0f, &button, &toolbar);
-		ui_vsplit_l(&toolbar, 30.0f, &button, &toolbar);
+		toolbar.VSplitLeft(5.0f, &button, &toolbar);
+		toolbar.VSplitLeft(30.0f, &button, &toolbar);
 		static int ccw_button = 0;
-		if(do_editor_button(&ccw_button, "CCW", enabled, &button, draw_editor_button_l, 0, "[R] Rotates the brush counter clockwise") || inp_key_down('r'))
+		if(DoButton_ButtonL(&ccw_button, "CCW", enabled, &button, 0, "[R] Rotates the brush counter clockwise") || inp_key_down('r'))
 		{
 			for(int i = 0; i < brush.layers.len(); i++)
 				brush.layers[i]->brush_rotate(-rotation_amount/360.0f*pi*2);
 		}
 			
-		ui_vsplit_l(&toolbar, 30.0f, &button, &toolbar);
+		toolbar.VSplitLeft(30.0f, &button, &toolbar);
 		static int cw_button = 0;
-		if(do_editor_button(&cw_button, "CW", enabled, &button, draw_editor_button_r, 0, "[T] Rotates the brush clockwise") || inp_key_down('t'))
+		if(DoButton_ButtonR(&cw_button, "CW", enabled, &button, 0, "[T] Rotates the brush clockwise") || inp_key_down('t'))
 		{
 			for(int i = 0; i < brush.layers.len(); i++)
 				brush.layers[i]->brush_rotate(rotation_amount/360.0f*pi*2);
@@ -714,18 +861,18 @@ static void do_toolbar(RECT toolbar)
 	// quad manipulation
 	{
 		// do add button
-		ui_vsplit_l(&toolbar, 10.0f, &button, &toolbar);
-		ui_vsplit_l(&toolbar, 60.0f, &button, &toolbar);
+		toolbar.VSplitLeft(10.0f, &button, &toolbar);
+		toolbar.VSplitLeft(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(do_editor_button(&new_button, "Add Quad", qlayer?0:-1, &button, draw_editor_button, 0, "Adds a new quad"))
+		LAYER_QUADS *qlayer = (LAYER_QUADS *)get_selected_layer_type(0, LAYERTYPE_QUADS);
+		//LAYER_TILES *tlayer = (LAYER_TILES *)get_selected_layer_type(0, LAYERTYPE_TILES);
+		if(DoButton_Editor(&new_button, "Add Quad", qlayer?0:-1, &button, 0, "Adds a new quad"))
 		{
 			if(qlayer)
 			{
 				float mapping[4];
-				LAYERGROUP *g = editor.get_selected_group();
+				LAYERGROUP *g = 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);
@@ -749,7 +896,7 @@ static void rotate(POINT *center, POINT *point, float rotation)
 	point->y = (int)(x * sinf(rotation) + y * cosf(rotation) + center->y);
 }
 
-static void do_quad(QUAD *q, int index)
+void EDITOR::do_quad(QUAD *q, int index)
 {
 	enum
 	{
@@ -767,8 +914,8 @@ static void do_quad(QUAD *q, int index)
 	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();
+	float wx = UI()->MouseWorldX();
+	float wy = UI()->MouseWorldY();
 	
 	// get pivot
 	float center_x = fx2f(q->points[4].x);
@@ -777,16 +924,16 @@ static void do_quad(QUAD *q, int index)
 	float dx = (center_x - wx);
 	float dy = (center_y - wy);
 	if(dx*dx+dy*dy < 10*10)
-		ui_set_hot_item(id);
+		UI()->SetHotItem(id);
 
 	// draw selection background	
-	if(editor.selected_quad == index)
+	if(selected_quad == index)
 	{
-		gfx_setcolor(0,0,0,1);
-		gfx_quads_draw(center_x, center_y, 7.0f, 7.0f);
+		Graphics()->SetColor(0,0,0,1);
+		Graphics()->QuadsDraw(center_x, center_y, 7.0f, 7.0f);
 	}
 	
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == id)
 	{
 		// check if we only should move pivot
 		if(operation == OP_MOVE_PIVOT)
@@ -812,47 +959,47 @@ static void do_quad(QUAD *q, int index)
 			}
 		}
 		
-		rotate_angle += (editor.mouse_delta_x) * 0.002f;
+		rotate_angle += (mouse_delta_x) * 0.002f;
 		last_wx = wx;
 		last_wy = wy;
 		
 		if(operation == OP_CONTEXT_MENU)
 		{
-			if(!ui_mouse_button(1))
+			if(!UI()->MouseButton(1))
 			{
 				static int quad_popup_id = 0;
-				ui_invoke_popup_menu(&quad_popup_id, 0, ui_mouse_x(), ui_mouse_y(), 120, 150, popup_quad);
-				editor.lock_mouse = false;
+				ui_invoke_popup_menu(&quad_popup_id, 0, UI()->MouseX(), UI()->MouseY(), 120, 150, popup_quad);
+				lock_mouse = false;
 				operation = OP_NONE;
-				ui_set_active_item(0);
+				UI()->SetActiveItem(0);
 			}
 		}
 		else
 		{
-			if(!ui_mouse_button(0))
+			if(!UI()->MouseButton(0))
 			{
-				editor.lock_mouse = false;
+				lock_mouse = false;
 				operation = OP_NONE;
-				ui_set_active_item(0);
+				UI()->SetActiveItem(0);
 			}
 		}			
 
-		gfx_setcolor(1,1,1,1);
+		Graphics()->SetColor(1,1,1,1);
 	}
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == id)
 	{
 		ui_got_context = id;
 		
-		gfx_setcolor(1,1,1,1);
-		editor.tooltip = "Left mouse button to move. Hold shift to move pivot. Hold ctrl to rotate";
+		Graphics()->SetColor(1,1,1,1);
+		tooltip = "Left mouse button to move. Hold shift to move pivot. Hold ctrl to rotate";
 		
-		if(ui_mouse_button(0))
+		if(UI()->MouseButton(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;
+				lock_mouse = true;
 				operation = OP_ROTATE;
 				rotate_angle = 0;
 				rotate_points[0] = q->points[0];
@@ -863,31 +1010,31 @@ static void do_quad(QUAD *q, int index)
 			else
 				operation = OP_MOVE_ALL;
 				
-			ui_set_active_item(id);
-			editor.selected_quad = index;
+			UI()->SetActiveItem(id);
+			selected_quad = index;
 			last_wx = wx;
 			last_wy = wy;
 		}
 		
-		if(ui_mouse_button(1))
+		if(UI()->MouseButton(1))
 		{
-			editor.selected_quad = index;
+			selected_quad = index;
 			operation = OP_CONTEXT_MENU;
-			ui_set_active_item(id);
+			UI()->SetActiveItem(id);
 		}
 	}
 	else
-		gfx_setcolor(0,1,0,1);
+		Graphics()->SetColor(0,1,0,1);
 
-	gfx_quads_draw(center_x, center_y, 5.0f, 5.0f);
+	Graphics()->QuadsDraw(center_x, center_y, 5.0f, 5.0f);
 }
 
-static void do_quad_point(QUAD *q, int quad_index, int v)
+void EDITOR::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 wx = UI()->MouseWorldX();
+	float wy = UI()->MouseWorldY();
 	
 	float px = fx2f(q->points[v].x);
 	float py = fx2f(q->points[v].y);
@@ -895,13 +1042,13 @@ static void do_quad_point(QUAD *q, int quad_index, int v)
 	float dx = (px - wx);
 	float dy = (py - wy);
 	if(dx*dx+dy*dy < 10*10)
-		ui_set_hot_item(id);
+		UI()->SetHotItem(id);
 
 	// draw selection background	
-	if(editor.selected_quad == quad_index && editor.selected_points&(1<<v))
+	if(selected_quad == quad_index && selected_points&(1<<v))
 	{
-		gfx_setcolor(0,0,0,1);
-		gfx_quads_draw(px, py, 7.0f, 7.0f);
+		Graphics()->SetColor(0,0,0,1);
+		Graphics()->QuadsDraw(px, py, 7.0f, 7.0f);
 	}
 	
 	enum
@@ -915,10 +1062,10 @@ static void do_quad_point(QUAD *q, int quad_index, int v)
 	static bool moved;
 	static int operation = OP_NONE;
 
-	if(ui_active_item() == id)
+	if(UI()->ActiveItem() == id)
 	{
-		float dx = editor.mouse_delta_wx;
-		float dy = editor.mouse_delta_wy;
+		float dx = mouse_delta_wx;
+		float dy = mouse_delta_wy;
 		if(!moved)
 		{
 			if(dx*dx+dy*dy > 0.5f)
@@ -930,7 +1077,7 @@ static void do_quad_point(QUAD *q, int quad_index, int v)
 			if(operation == OP_MOVEPOINT)
 			{
 				for(int m = 0; m < 4; m++)
-					if(editor.selected_points&(1<<m))
+					if(selected_points&(1<<m))
 					{
 						q->points[m].x += f2fx(dx);
 						q->points[m].y += f2fx(dy);
@@ -939,7 +1086,7 @@ static void do_quad_point(QUAD *q, int quad_index, int v)
 			else if(operation == OP_MOVEUV)
 			{
 				for(int m = 0; m < 4; m++)
-					if(editor.selected_points&(1<<m))
+					if(selected_points&(1<<m))
 					{
 						q->texcoords[m].x += f2fx(dx*0.001f);
 						q->texcoords[m].y += f2fx(dy*0.001f);
@@ -949,106 +1096,106 @@ static void do_quad_point(QUAD *q, int quad_index, int v)
 		
 		if(operation == OP_CONTEXT_MENU)
 		{
-			if(!ui_mouse_button(1))
+			if(!UI()->MouseButton(1))
 			{
 				static int point_popup_id = 0;
-				ui_invoke_popup_menu(&point_popup_id, 0, ui_mouse_x(), ui_mouse_y(), 120, 150, popup_point);
-				ui_set_active_item(0);
+				ui_invoke_popup_menu(&point_popup_id, 0, UI()->MouseX(), UI()->MouseY(), 120, 150, popup_point);
+				UI()->SetActiveItem(0);
 			}
 		}
 		else
 		{
-			if(!ui_mouse_button(0))
+			if(!UI()->MouseButton(0))
 			{
 				if(!moved)
 				{
 					if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-						editor.selected_points ^= 1<<v;
+						selected_points ^= 1<<v;
 					else
-						editor.selected_points = 1<<v;
+						selected_points = 1<<v;
 				}
-				editor.lock_mouse = false;
-				ui_set_active_item(0);
+				lock_mouse = false;
+				UI()->SetActiveItem(0);
 			}
 		}
 
-		gfx_setcolor(1,1,1,1);
+		Graphics()->SetColor(1,1,1,1);
 	}
-	else if(ui_hot_item() == id)
+	else if(UI()->HotItem() == id)
 	{
 		ui_got_context = id;
 		
-		gfx_setcolor(1,1,1,1);
-		editor.tooltip = "Left mouse button to move. Hold shift to move the texture.";
+		Graphics()->SetColor(1,1,1,1);
+		tooltip = "Left mouse button to move. Hold shift to move the texture.";
 		
-		if(ui_mouse_button(0))
+		if(UI()->MouseButton(0))
 		{
-			ui_set_active_item(id);
+			UI()->SetActiveItem(id);
 			moved = false;
 			if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
 			{
 				operation = OP_MOVEUV;
-				editor.lock_mouse = true;
+				lock_mouse = true;
 			}
 			else
 				operation = OP_MOVEPOINT;
 				
-			if(!(editor.selected_points&(1<<v)))
+			if(!(selected_points&(1<<v)))
 			{
 				if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
-					editor.selected_points |= 1<<v;
+					selected_points |= 1<<v;
 				else
-					editor.selected_points = 1<<v;
+					selected_points = 1<<v;
 				moved = true;
 			}
 															
-			editor.selected_quad = quad_index;
+			selected_quad = quad_index;
 		}
-		else if(ui_mouse_button(1))
+		else if(UI()->MouseButton(1))
 		{
 			operation = OP_CONTEXT_MENU;
-			editor.selected_quad = quad_index;
-			ui_set_active_item(id);
+			selected_quad = quad_index;
+			UI()->SetActiveItem(id);
 		}
 	}
 	else
-		gfx_setcolor(1,0,0,1);
+		Graphics()->SetColor(1,0,0,1);
 	
-	gfx_quads_draw(px, py, 5.0f, 5.0f);	
+	Graphics()->QuadsDraw(px, py, 5.0f, 5.0f);	
 }
 
-static void do_map_editor(RECT view, RECT toolbar)
+void EDITOR::do_map_editor(CUIRect view, CUIRect toolbar)
 {
-	//ui_clip_enable(&view);
+	//UI()->ClipEnable(&view);
 	
-	bool show_picker = inp_key_pressed(KEY_SPACE) != 0 && editor.dialog == DIALOG_NONE;
+	bool show_picker = inp_key_pressed(KEY_SPACE) != 0 && dialog == DIALOG_NONE;
 
 	// render all good stuff
 	if(!show_picker)
 	{
-		for(int g = 0; g < editor.map.groups.len(); g++)
+		for(int g = 0; g < map.groups.len(); g++)
 		{
-			if(editor.map.groups[g]->visible)
-				editor.map.groups[g]->render();
-			//ui_clip_enable(&view);
+			if(map.groups[g]->visible)
+				map.groups[g]->render();
+			//UI()->ClipEnable(&view);
 		}
 		
 		// render the game above everything else
-		if(editor.map.game_group->visible && editor.map.game_layer->visible)
+		if(map.game_group->visible && map.game_layer->visible)
 		{
-			editor.map.game_group->mapscreen();
-			editor.map.game_layer->render();
+			map.game_group->mapscreen();
+			map.game_layer->render();
 		}
 	}
 
 	static void *editor_id = (void *)&editor_id;
-	int inside = ui_mouse_inside(&view);
+	int inside = UI()->MouseInside(&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();
+	float wx = UI()->MouseWorldX();
+	float wy = UI()->MouseWorldY();
+	float mx = UI()->MouseX();
+	float my = UI()->MouseY();
 	
 	static float start_wx = 0;
 	static float start_wy = 0;
@@ -1067,7 +1214,7 @@ static void do_map_editor(RECT view, RECT toolbar)
 	// remap the screen so it can display the whole tileset
 	if(show_picker)
 	{
-		RECT screen = *ui_screen();
+		CUIRect screen = *UI()->Screen();
 		float size = 32.0*16.0f;
 		float w = size*(screen.w/view.w);
 		float h = size*(screen.h/view.h);
@@ -1075,8 +1222,8 @@ static void do_map_editor(RECT view, RECT toolbar)
 		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);
+		Graphics()->MapScreen(x, y, x+w, y+h);
+		LAYER_TILES *t = (LAYER_TILES *)get_selected_layer_type(0, LAYERTYPE_TILES);
 		if(t)
 		{
 			tileset_picker.image = t->image;
@@ -1099,11 +1246,11 @@ static void do_map_editor(RECT view, RECT toolbar)
 	}
 	else
 	{
-		edit_layers[0] = editor.get_selected_layer(0);
+		edit_layers[0] = get_selected_layer(0);
 		if(edit_layers[0])
 			num_edit_layers++;
 
-		LAYERGROUP *g = editor.get_selected_group();
+		LAYERGROUP *g = get_selected_group();
 		if(g)
 		{
 			g->mapscreen();
@@ -1116,50 +1263,50 @@ static void do_map_editor(RECT view, RECT toolbar)
 				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();
+				Graphics()->TextureSet(-1);
+				Graphics()->LinesBegin();
+				Graphics()->LinesDraw(0,0, w,0);
+				Graphics()->LinesDraw(w,0, w,h);
+				Graphics()->LinesDraw(w,h, 0,h);
+				Graphics()->LinesDraw(0,h, 0,0);
+				Graphics()->LinesEnd();
 			}
 		}
 	}
 		
 	if(inside)
 	{
-		ui_set_hot_item(editor_id);
+		UI()->SetHotItem(editor_id);
 				
 		// do global operations like pan and zoom
-		if(ui_active_item() == 0 && (ui_mouse_button(0) || ui_mouse_button(2)))
+		if(UI()->ActiveItem() == 0 && (UI()->MouseButton(0) || UI()->MouseButton(2)))
 		{
 			start_wx = wx;
 			start_wy = wy;
 			start_mx = mx;
 			start_my = my;
 					
-			if(inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL) || ui_mouse_button(2))
+			if(inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL) || UI()->MouseButton(2))
 			{
 				if(inp_key_pressed(KEY_LSHIFT))
 					operation = OP_PAN_EDITOR;
 				else
 					operation = OP_PAN_WORLD;
-				ui_set_active_item(editor_id);
+				UI()->SetActiveItem(editor_id);
 			}
 		}
 
 		// brush editing
-		if(ui_hot_item() == editor_id)
+		if(UI()->HotItem() == editor_id)
 		{
 			if(brush.is_empty())
-				editor.tooltip = "Use left mouse button to drag and create a brush.";
+				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.";
+				tooltip = "Use left mouse button to paint with the brush. Right button clears the brush.";
 
-			if(ui_active_item() == editor_id)
+			if(UI()->ActiveItem() == editor_id)
 			{
-				RECT r;
+				CUIRect r;
 				r.x = start_wx;
 				r.y = start_wy;
 				r.w = wx-start_wx;
@@ -1190,7 +1337,7 @@ static void do_map_editor(RECT view, RECT toolbar)
 				}
 				else if(operation == OP_BRUSH_GRAB)
 				{
-					if(!ui_mouse_button(0))
+					if(!UI()->MouseButton(0))
 					{
 						// grab brush
 						dbg_msg("editor", "grabbing %f %f %f %f", r.x, r.y, r.w, r.h);
@@ -1207,18 +1354,18 @@ static void do_map_editor(RECT view, RECT toolbar)
 						//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);
+						Graphics()->MapScreen(UI()->Screen()->x, UI()->Screen()->y, UI()->Screen()->w, UI()->Screen()->h);
 					}
 				}
 			}
 			else
 			{
-				if(ui_mouse_button(1))
+				if(UI()->MouseButton(1))
 					brush.clear();
 					
-				if(ui_mouse_button(0) && operation == OP_NONE)
+				if(UI()->MouseButton(0) && operation == OP_NONE)
 				{
-					ui_set_active_item(editor_id);
+					UI()->SetActiveItem(editor_id);
 					
 					if(brush.is_empty())
 						operation = OP_BRUSH_GRAB;
@@ -1248,7 +1395,7 @@ static void do_map_editor(RECT view, RECT toolbar)
 						}
 					}
 				
-					LAYERGROUP *g = editor.get_selected_group();
+					LAYERGROUP *g = get_selected_group();
 					brush.offset_x += g->offset_x;
 					brush.offset_y += g->offset_y;
 					brush.parallax_x = g->parallax_x;
@@ -1257,13 +1404,13 @@ static void do_map_editor(RECT view, RECT toolbar)
 					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();
+					Graphics()->TextureSet(-1);
+					Graphics()->LinesBegin();
+					Graphics()->LinesDraw(0,0, w,0);
+					Graphics()->LinesDraw(w,0, w,h);
+					Graphics()->LinesDraw(w,h, 0,h);
+					Graphics()->LinesDraw(0,h, 0,0);
+					Graphics()->LinesEnd();
 					
 				}
 			}
@@ -1274,7 +1421,7 @@ static void do_map_editor(RECT view, RECT toolbar)
 			if(!show_picker && brush.is_empty())
 			{
 				// fetch layers
-				LAYERGROUP *g = editor.get_selected_group();
+				LAYERGROUP *g = get_selected_group();
 				if(g)
 					g->mapscreen();
 					
@@ -1284,8 +1431,8 @@ static void do_map_editor(RECT view, RECT toolbar)
 					{
 						LAYER_QUADS *layer = (LAYER_QUADS *)edit_layers[k];
 		
-						gfx_texture_set(-1);
-						gfx_quads_begin();				
+						Graphics()->TextureSet(-1);
+						Graphics()->QuadsBegin();				
 						for(int i = 0; i < layer->quads.len(); i++)
 						{
 							for(int v = 0; v < 4; v++)
@@ -1293,68 +1440,68 @@ static void do_map_editor(RECT view, RECT toolbar)
 								
 							do_quad(&layer->quads[i], i);
 						}
-						gfx_quads_end();
+						Graphics()->QuadsEnd();
 					}
 				}
 				
-				gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
+				Graphics()->MapScreen(UI()->Screen()->x, UI()->Screen()->y, UI()->Screen()->w, UI()->Screen()->h);
 			}		
 			
 			// do panning
-			if(ui_active_item() == editor_id)
+			if(UI()->ActiveItem() == 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;
+					world_offset_x -= mouse_delta_x*world_zoom;
+					world_offset_y -= mouse_delta_y*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;
+					editor_offset_x -= mouse_delta_x*world_zoom;
+					editor_offset_y -= mouse_delta_y*world_zoom;
 				}
 
 				// release mouse
-				if(!ui_mouse_button(0))
+				if(!UI()->MouseButton(0))
 				{
 					operation = OP_NONE;
-					ui_set_active_item(0);
+					UI()->SetActiveItem(0);
 				}
 			}
 		}
 	}
 	
-	if(editor.get_selected_group() && editor.get_selected_group()->use_clipping)
+	if(get_selected_group() && get_selected_group()->use_clipping)
 	{
-		LAYERGROUP *g = editor.map.game_group;
+		LAYERGROUP *g = map.game_group;
 		g->mapscreen();
 		
-		gfx_texture_set(-1);
-		gfx_lines_begin();
-
-			RECT r;
-			r.x = editor.get_selected_group()->clip_x;
-			r.y = editor.get_selected_group()->clip_y;
-			r.w = editor.get_selected_group()->clip_w;
-			r.h = editor.get_selected_group()->clip_h;
+		Graphics()->TextureSet(-1);
+		Graphics()->LinesBegin();
+
+			CUIRect r;
+			r.x = get_selected_group()->clip_x;
+			r.y = get_selected_group()->clip_y;
+			r.w = get_selected_group()->clip_w;
+			r.h = get_selected_group()->clip_h;
 			
-			gfx_setcolor(1,0,0,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);
+			Graphics()->SetColor(1,0,0,1);
+			Graphics()->LinesDraw(r.x, r.y, r.x+r.w, r.y);
+			Graphics()->LinesDraw(r.x+r.w, r.y, r.x+r.w, r.y+r.h);
+			Graphics()->LinesDraw(r.x+r.w, r.y+r.h, r.x, r.y+r.h);
+			Graphics()->LinesDraw(r.x, r.y+r.h, r.x, r.y);
 			
-		gfx_lines_end();
+		Graphics()->LinesEnd();
 	}
 
 	// render screen sizes	
-	if(editor.proof_borders)
+	if(proof_borders)
 	{
-		LAYERGROUP *g = editor.map.game_group;
+		LAYERGROUP *g = map.game_group;
 		g->mapscreen();
 		
-		gfx_texture_set(-1);
-		gfx_lines_begin();
+		Graphics()->TextureSet(-1);
+		Graphics()->LinesBegin();
 		
 		float last_points[4];
 		float start = 1.0f; //9.0f/16.0f;
@@ -1365,28 +1512,28 @@ static void do_map_editor(RECT view, RECT toolbar)
 			float points[4];
 			float aspect = start + (end-start)*(i/(float)num_steps);
 			
-			mapscreen_to_world(
-				editor.world_offset_x, editor.world_offset_y,
+			RenderTools()->mapscreen_to_world(
+				world_offset_x, 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]);
+				Graphics()->LinesDraw(points[0], points[1], points[2], points[1]);
+				Graphics()->LinesDraw(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]);
+				Graphics()->LinesDraw(points[0], points[1], last_points[0], last_points[1]);
+				Graphics()->LinesDraw(points[2], points[1], last_points[2], last_points[1]);
+				Graphics()->LinesDraw(points[0], points[3], last_points[0], last_points[3]);
+				Graphics()->LinesDraw(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]);
+				Graphics()->LinesDraw(points[0], points[1], points[0], points[3]);
+				Graphics()->LinesDraw(points[2], points[1], points[2], points[3]);
 			}
 			
 			mem_copy(last_points, points, sizeof(points));
@@ -1394,64 +1541,64 @@ static void do_map_editor(RECT view, RECT toolbar)
 
 		if(1)
 		{
-			gfx_setcolor(1,0,0,1);
+			Graphics()->SetColor(1,0,0,1);
 			for(int i = 0; i < 2; i++)
 			{
 				float points[4];
 				float aspects[] = {4.0f/3.0f, 16.0f/10.0f, 5.0f/4.0f, 16.0f/9.0f};
 				float aspect = aspects[i];
 				
-				mapscreen_to_world(
-					editor.world_offset_x, editor.world_offset_y,
+				RenderTools()->mapscreen_to_world(
+					world_offset_x, world_offset_y,
 					1.0f, 1.0f, 0.0f, 0.0f, aspect, 1.0f, points);
 				
-				RECT r;
+				CUIRect 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_setcolor(0,1,0,1);
+				Graphics()->LinesDraw(r.x, r.y, r.x+r.w, r.y);
+				Graphics()->LinesDraw(r.x+r.w, r.y, r.x+r.w, r.y+r.h);
+				Graphics()->LinesDraw(r.x+r.w, r.y+r.h, r.x, r.y+r.h);
+				Graphics()->LinesDraw(r.x, r.y+r.h, r.x, r.y);
+				Graphics()->SetColor(0,1,0,1);
 			}
 		}
 			
-		gfx_lines_end();
+		Graphics()->LinesEnd();
 	}
 	
-	gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
-	//ui_clip_disable();
+	Graphics()->MapScreen(UI()->Screen()->x, UI()->Screen()->y, UI()->Screen()->w, UI()->Screen()->h);
+	//UI()->ClipDisable();
 }
 
 
-int EDITOR::do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val)
+int EDITOR::do_properties(CUIRect *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);
+		CUIRect slot;
+		toolbox->HSplitTop(13.0f, &slot, toolbox);
+		CUIRect label, shifter;
+		slot.VSplitMid(&label, &shifter);
+		shifter.HMargin(1.0f, &shifter);
+		UI()->DoLabel(&label, props[i].name, 10.0f, -1, -1);
 		
 		if(props[i].type == PROPTYPE_INT_STEP)
 		{
-			RECT inc, dec;
+			CUIRect inc, dec;
 			char buf[64];
 			
-			ui_vsplit_r(&shifter, 10.0f, &shifter, &inc);
-			ui_vsplit_l(&shifter, 10.0f, &dec, &shifter);
+			shifter.VSplitRight(10.0f, &shifter, &inc);
+			shifter.VSplitLeft(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);
+			RenderTools()->DrawUIRect(&shifter, vec4(1,1,1,0.5f), 0, 0.0f);
+			UI()->DoLabel(&shifter, buf, 10.0f, 0, -1);
 			
-			if(do_editor_button(&ids[i], 0, 0, &dec, draw_dec_button, 0, "Decrease"))
+			if(DoButton_ButtonDec(&ids[i], 0, 0, &dec, 0, "Decrease"))
 			{
 				if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
 					*new_val = props[i].value-5;
@@ -1459,7 +1606,7 @@ int EDITOR::do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val
 					*new_val = props[i].value-1;
 				change = i;
 			}
-			if(do_editor_button(((char *)&ids[i])+1, 0, 0, &inc, draw_inc_button, 0, "Increase"))
+			if(DoButton_ButtonInc(((char *)&ids[i])+1, 0, 0, &inc, 0, "Increase"))
 			{
 				if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT))
 					*new_val = props[i].value+5;
@@ -1470,14 +1617,14 @@ int EDITOR::do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val
 		}
 		else if(props[i].type == PROPTYPE_BOOL)
 		{
-			RECT no, yes;
-			ui_vsplit_mid(&shifter, &no, &yes);
-			if(do_editor_button(&ids[i], "No", !props[i].value, &no, draw_dec_button, 0, ""))
+			CUIRect no, yes;
+			shifter.VSplitMid(&no, &yes);
+			if(DoButton_ButtonDec(&ids[i], "No", !props[i].value, &no, 0, ""))
 			{
 				*new_val = 0;
 				change = i;
 			}
-			if(do_editor_button(((char *)&ids[i])+1, "Yes", props[i].value, &yes, draw_inc_button, 0, ""))
+			if(DoButton_ButtonInc(((char *)&ids[i])+1, "Yes", props[i].value, &yes, 0, ""))
 			{
 				*new_val = 1;
 				change = i;
@@ -1505,9 +1652,9 @@ int EDITOR::do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val
 
 				if(c != 3)
 				{
-					ui_hsplit_t(toolbox, 13.0f, &slot, toolbox);
-					ui_vsplit_mid(&slot, 0, &shifter);
-					ui_hmargin(&shifter, 1.0f, &shifter);
+					toolbox->HSplitTop(13.0f, &slot, toolbox);
+					slot.VSplitMid(0, &shifter);
+					shifter.HMargin(1.0f, &shifter);
 				}
 			}
 			
@@ -1523,10 +1670,10 @@ int EDITOR::do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val
 			if(props[i].value < 0)
 				strcpy(buf, "None");
 			else
-				sprintf(buf, "%s",  editor.map.images[props[i].value]->name);
+				sprintf(buf, "%s",  map.images[props[i].value]->name);
 			
-			if(do_editor_button(&ids[i], buf, 0, &shifter, draw_editor_button, 0, 0))
-				popup_select_image_invoke(props[i].value, ui_mouse_x(), ui_mouse_y());
+			if(DoButton_Editor(&ids[i], buf, 0, &shifter, 0, 0))
+				popup_select_image_invoke(props[i].value, UI()->MouseX(), UI()->MouseY());
 			
 			int r = popup_select_image_result();
 			if(r >= -1)
@@ -1540,90 +1687,90 @@ int EDITOR::do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val
 	return change;
 }
 
-static void render_layers(RECT toolbox, RECT toolbar, RECT view)
+void EDITOR::render_layers(CUIRect toolbox, CUIRect toolbar, CUIRect view)
 {
-	RECT layersbox = toolbox;
+	CUIRect layersbox = toolbox;
 
-	if(!editor.gui_active)
+	if(!gui_active)
 		return;
 			
-	RECT slot, button;
+	CUIRect slot, button;
 	char buf[64];
 
 	int valid_group = 0;
 	int valid_layer = 0;
-	if(editor.selected_group >= 0 && editor.selected_group < editor.map.groups.len())
+	if(selected_group >= 0 && selected_group < map.groups.len())
 		valid_group = 1;
 
-	if(valid_group && editor.selected_layer >= 0 && editor.selected_layer < editor.map.groups[editor.selected_group]->layers.len())
+	if(valid_group && selected_layer >= 0 && selected_layer < map.groups[selected_group]->layers.len())
 		valid_layer = 1;
 		
 	// render layers	
 	{
-		for(int g = 0; g < editor.map.groups.len(); g++)
+		for(int g = 0; g < map.groups.len(); g++)
 		{
-			RECT visible_toggle;
-			ui_hsplit_t(&layersbox, 12.0f, &slot, &layersbox);
-			ui_vsplit_l(&slot, 12, &visible_toggle, &slot);
-			if(do_editor_button(&editor.map.groups[g]->visible, editor.map.groups[g]->visible?"V":"H", 0, &visible_toggle, draw_editor_button_l, 0, "Toggle group visibility"))
-				editor.map.groups[g]->visible = !editor.map.groups[g]->visible;
-
-			sprintf(buf, "#%d %s", g, editor.map.groups[g]->name);
-			if(int result = do_editor_button(&editor.map.groups[g], buf, g==editor.selected_group, &slot, draw_editor_button_r,
+			CUIRect visible_toggle;
+			layersbox.HSplitTop(12.0f, &slot, &layersbox);
+			slot.VSplitLeft(12, &visible_toggle, &slot);
+			if(DoButton_ButtonL(&map.groups[g]->visible, map.groups[g]->visible?"V":"H", 0, &visible_toggle, 0, "Toggle group visibility"))
+				map.groups[g]->visible = !map.groups[g]->visible;
+
+			sprintf(buf, "#%d %s", g, map.groups[g]->name);
+			if(int result = DoButton_ButtonR(&map.groups[g], buf, g==selected_group, &slot,
 				BUTTON_CONTEXT, "Select group. Right click for properties."))
 			{
-				editor.selected_group = g;
-				editor.selected_layer = 0;
+				selected_group = g;
+				selected_layer = 0;
 				
 				static int group_popup_id = 0;
 				if(result == 2)
-					ui_invoke_popup_menu(&group_popup_id, 0, ui_mouse_x(), ui_mouse_y(), 120, 200, popup_group);
+					ui_invoke_popup_menu(&group_popup_id, 0, UI()->MouseX(), UI()->MouseY(), 120, 200, popup_group);
 			}
 			
 			
-			ui_hsplit_t(&layersbox, 2.0f, &slot, &layersbox);
+			layersbox.HSplitTop(2.0f, &slot, &layersbox);
 			
-			for(int i = 0; i < editor.map.groups[g]->layers.len(); i++)
+			for(int i = 0; i < 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);
+				layersbox.HSplitTop(12.0f, &slot, &layersbox);
+				slot.VSplitLeft(12.0f, 0, &button);
+				button.VSplitLeft(15, &visible_toggle, &button);
 
-				if(do_editor_button(&editor.map.groups[g]->layers[i]->visible, editor.map.groups[g]->layers[i]->visible?"V":"H", 0, &visible_toggle, draw_editor_button_l, 0, "Toggle layer visibility"))
-					editor.map.groups[g]->layers[i]->visible = !editor.map.groups[g]->layers[i]->visible;
+				if(DoButton_ButtonL(&map.groups[g]->layers[i]->visible, map.groups[g]->layers[i]->visible?"V":"H", 0, &visible_toggle, 0, "Toggle layer visibility"))
+					map.groups[g]->layers[i]->visible = !map.groups[g]->layers[i]->visible;
 
-				sprintf(buf, "#%d %s ", i, editor.map.groups[g]->layers[i]->type_name);
-				if(int result = do_editor_button(editor.map.groups[g]->layers[i], buf, g==editor.selected_group&&i==editor.selected_layer, &button, draw_editor_button_r,
+				sprintf(buf, "#%d %s ", i, map.groups[g]->layers[i]->type_name);
+				if(int result = DoButton_ButtonR(map.groups[g]->layers[i], buf, g==selected_group&&i==selected_layer, &button,
 					BUTTON_CONTEXT, "Select layer. Right click for properties."))
 				{
-					editor.selected_layer = i;
-					editor.selected_group = g;
+					selected_layer = i;
+					selected_group = g;
 					static int layer_popup_id = 0;
 					if(result == 2)
-						ui_invoke_popup_menu(&layer_popup_id, 0, ui_mouse_x(), ui_mouse_y(), 120, 150, popup_layer);
+						ui_invoke_popup_menu(&layer_popup_id, 0, UI()->MouseX(), UI()->MouseY(), 120, 150, popup_layer);
 				}
 				
 				
-				ui_hsplit_t(&layersbox, 2.0f, &slot, &layersbox);
+				layersbox.HSplitTop(2.0f, &slot, &layersbox);
 			}
-			ui_hsplit_t(&layersbox, 5.0f, &slot, &layersbox);
+			layersbox.HSplitTop(5.0f, &slot, &layersbox);
 		}
 	}
 	
 
 	{
-		ui_hsplit_t(&layersbox, 12.0f, &slot, &layersbox);
+		layersbox.HSplitTop(12.0f, &slot, &layersbox);
 
 		static int new_group_button = 0;
-		if(do_editor_button(&new_group_button, "Add Group", 0, &slot, draw_editor_button, 0, "Adds a new group"))
+		if(DoButton_Editor(&new_group_button, "Add Group", 0, &slot, 0, "Adds a new group"))
 		{
-			editor.map.new_group();
-			editor.selected_group = editor.map.groups.len()-1;
+			map.new_group();
+			selected_group = map.groups.len()-1;
 		}
 	}
 
-	ui_hsplit_t(&layersbox, 5.0f, &slot, &layersbox);
+	layersbox.HSplitTop(5.0f, &slot, &layersbox);
 	
 }
 
@@ -1659,31 +1806,33 @@ static void extract_name(const char *filename, char *name)
 	dbg_msg("", "%s %s %d %d", filename, name, start, end);
 }
 
-static void replace_image(const char *filename)
+void EDITOR::replace_image(const char *filename, void *user)
 {
-	EDITOR_IMAGE imginfo;
-	if(!gfx_load_png(&imginfo, filename))
+	EDITOR *editor = (EDITOR *)user;
+	EDITOR_IMAGE imginfo(editor);
+	if(!editor->Graphics()->LoadPNG(&imginfo, filename))
 		return;
 	
-	EDITOR_IMAGE *img = editor.map.images[editor.selected_image];
-	gfx_unload_texture(img->tex_id);
+	EDITOR_IMAGE *img = editor->map.images[editor->selected_image];
+	editor->Graphics()->UnloadTexture(img->tex_id);
 	*img = imginfo;
 	extract_name(filename, img->name);
-	img->tex_id = gfx_load_texture_raw(imginfo.width, imginfo.height, imginfo.format, imginfo.data, IMG_AUTO, 0);
+	img->tex_id = editor->Graphics()->LoadTextureRaw(imginfo.width, imginfo.height, imginfo.format, imginfo.data, IMG_AUTO, 0);
 }
 
-static void add_image(const char *filename)
+void EDITOR::add_image(const char *filename, void *user)
 {
-	EDITOR_IMAGE imginfo;
-	if(!gfx_load_png(&imginfo, filename))
+	EDITOR *editor = (EDITOR *)user;
+	EDITOR_IMAGE imginfo(editor);
+	if(!editor->Graphics()->LoadPNG(&imginfo, filename))
 		return;
 
-	EDITOR_IMAGE *img = new EDITOR_IMAGE;
+	EDITOR_IMAGE *img = new EDITOR_IMAGE(editor);
 	*img = imginfo;
-	img->tex_id = gfx_load_texture_raw(imginfo.width, imginfo.height, imginfo.format, imginfo.data, IMG_AUTO, 0);
+	img->tex_id = editor->Graphics()->LoadTextureRaw(imginfo.width, imginfo.height, imginfo.format, imginfo.data, IMG_AUTO, 0);
 	img->external = 1; // external by default
 	extract_name(filename, img->name);
-	editor.map.images.add(img);
+	editor->map.images.add(img);
 }
 
 
@@ -1696,20 +1845,20 @@ static void modify_index_deleted(int *index)
 		*index = *index - 1;
 }
 
-static int popup_image(RECT view)
+int EDITOR::popup_image(EDITOR *pEditor, CUIRect view)
 {
 	static int replace_button = 0;	
 	static int remove_button = 0;	
 
-	RECT slot;
-	ui_hsplit_t(&view, 2.0f, &slot, &view);
-	ui_hsplit_t(&view, 12.0f, &slot, &view);
-	EDITOR_IMAGE *img = editor.map.images[editor.selected_image];
+	CUIRect slot;
+	view.HSplitTop(2.0f, &slot, &view);
+	view.HSplitTop(12.0f, &slot, &view);
+	EDITOR_IMAGE *img = pEditor->map.images[pEditor->selected_image];
 	
 	static int external_button = 0;
 	if(img->external)
 	{
-		if(do_editor_button(&external_button, "Embedd", 0, &slot, draw_editor_button_menuitem, 0, "Embedds the image into the map file."))
+		if(pEditor->DoButton_MenuItem(&external_button, "Embedd", 0, &slot, 0, "Embedds the image into the map file."))
 		{
 			img->external = 0;
 			return 1;
@@ -1717,29 +1866,29 @@ static int popup_image(RECT view)
 	}
 	else
 	{		
-		if(do_editor_button(&external_button, "Make external", 0, &slot, draw_editor_button_menuitem, 0, "Removes the image from the map file."))
+		if(pEditor->DoButton_MenuItem(&external_button, "Make external", 0, &slot, 0, "Removes the image from the map file."))
 		{
 			img->external = 1;
 			return 1;
 		}
 	}
 
-	ui_hsplit_t(&view, 10.0f, &slot, &view);
-	ui_hsplit_t(&view, 12.0f, &slot, &view);
-	if(do_editor_button(&replace_button, "Replace", 0, &slot, draw_editor_button_menuitem, 0, "Replaces the image with a new one"))
+	view.HSplitTop(10.0f, &slot, &view);
+	view.HSplitTop(12.0f, &slot, &view);
+	if(pEditor->DoButton_MenuItem(&replace_button, "Replace", 0, &slot, 0, "Replaces the image with a new one"))
 	{
-		editor.invoke_file_dialog(LISTDIRTYPE_ALL, "Replace Image", "Replace", "mapres/", "", replace_image);
+		pEditor->invoke_file_dialog(LISTDIRTYPE_ALL, "Replace Image", "Replace", "mapres/", "", replace_image, pEditor);
 		return 1;
 	}
 
-	ui_hsplit_t(&view, 10.0f, &slot, &view);
-	ui_hsplit_t(&view, 12.0f, &slot, &view);
-	if(do_editor_button(&remove_button, "Remove", 0, &slot, draw_editor_button_menuitem, 0, "Removes the image from the map"))
+	view.HSplitTop(10.0f, &slot, &view);
+	view.HSplitTop(12.0f, &slot, &view);
+	if(pEditor->DoButton_MenuItem(&remove_button, "Remove", 0, &slot, 0, "Removes the image from the map"))
 	{
 		delete img;
-		editor.map.images.removebyindex(editor.selected_image);
-		modify_index_deleted_index = editor.selected_image;
-		editor.map.modify_image_index(modify_index_deleted);
+		pEditor->map.images.removebyindex(pEditor->selected_image);
+		modify_index_deleted_index = pEditor->selected_image;
+		pEditor->map.modify_image_index(modify_index_deleted);
 		return 1;
 	}
 
@@ -1747,76 +1896,77 @@ static int popup_image(RECT view)
 }
 
 
-static void render_images(RECT toolbox, RECT toolbar, RECT view)
+void EDITOR::render_images(CUIRect toolbox, CUIRect toolbar, CUIRect view)
 {
 	for(int e = 0; e < 2; e++) // two passes, first embedded, then external
 	{
-		RECT slot;
-		ui_hsplit_t(&toolbox, 15.0f, &slot, &toolbox);
+		CUIRect slot;
+		toolbox.HSplitTop(15.0f, &slot, &toolbox);
 		if(e == 0)
-			ui_do_label(&slot, "Embedded", 12.0f, 0);
+			UI()->DoLabel(&slot, "Embedded", 12.0f, 0);
 		else
-			ui_do_label(&slot, "External", 12.0f, 0);
+			UI()->DoLabel(&slot, "External", 12.0f, 0);
 		
-		for(int i = 0; i < editor.map.images.len(); i++)
+		for(int i = 0; i < map.images.len(); i++)
 		{
-			if((e && !editor.map.images[i]->external) ||
-				(!e && editor.map.images[i]->external))
+			if((e && !map.images[i]->external) ||
+				(!e && map.images[i]->external))
 			{
 				continue;
 			}
 			
 			char buf[128];
-			sprintf(buf, "%s", editor.map.images[i]->name);
-			ui_hsplit_t(&toolbox, 12.0f, &slot, &toolbox);
+			sprintf(buf, "%s", map.images[i]->name);
+			toolbox.HSplitTop(12.0f, &slot, &toolbox);
 			
-			if(int result = do_editor_button(&editor.map.images[i], buf, editor.selected_image == i, &slot, draw_editor_button,
+			if(int result = DoButton_Editor(&map.images[i], buf, selected_image == i, &slot,
 				BUTTON_CONTEXT, "Select image"))
 			{
-				editor.selected_image = i;
+				selected_image = i;
 				
 				static int popup_image_id = 0;
 				if(result == 2)
-					ui_invoke_popup_menu(&popup_image_id, 0, ui_mouse_x(), ui_mouse_y(), 120, 80, popup_image);
+					ui_invoke_popup_menu(&popup_image_id, 0, UI()->MouseX(), UI()->MouseY(), 120, 80, popup_image);
 			}
 			
-			ui_hsplit_t(&toolbox, 2.0f, 0, &toolbox);
+			toolbox.HSplitTop(2.0f, 0, &toolbox);
 			
 			// render image
-			if(editor.selected_image == i)
+			if(selected_image == i)
 			{
-				RECT r;
-				ui_margin(&view, 10.0f, &r);
+				CUIRect r;
+				view.Margin(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();
+				Graphics()->TextureSet(map.images[i]->tex_id);
+				Graphics()->BlendNormal();
+				Graphics()->QuadsBegin();
+				Graphics()->QuadsDrawTL(r.x, r.y, r.w, r.h);
+				Graphics()->QuadsEnd();
 				
 			}
 		}
 	}
 	
-	RECT slot;
-	ui_hsplit_t(&toolbox, 5.0f, &slot, &toolbox);
+	CUIRect slot;
+	toolbox.HSplitTop(5.0f, &slot, &toolbox);
 	
 	// new image
 	static int new_image_button = 0;
-	ui_hsplit_t(&toolbox, 10.0f, &slot, &toolbox);
-	ui_hsplit_t(&toolbox, 12.0f, &slot, &toolbox);
-	if(do_editor_button(&new_image_button, "Add", 0, &slot, draw_editor_button, 0, "Load a new image to use in the map"))
-		editor.invoke_file_dialog(LISTDIRTYPE_ALL, "Add Image", "Add", "mapres/", "", add_image);
+	toolbox.HSplitTop(10.0f, &slot, &toolbox);
+	toolbox.HSplitTop(12.0f, &slot, &toolbox);
+	if(DoButton_Editor(&new_image_button, "Add", 0, &slot, 0, "Load a new image to use in the map"))
+		invoke_file_dialog(LISTDIRTYPE_ALL, "Add Image", "Add", "mapres/", "", add_image, this);
 }
 
 
 static int file_dialog_dirtypes = 0;
 static const char *file_dialog_title = 0;
 static const char *file_dialog_button_text = 0;
-static void (*file_dialog_func)(const char *filename);
+static void (*file_dialog_func)(const char *filename, void *user);
+static void *file_dialog_user = 0;
 static char file_dialog_filename[512] = {0};
 static char file_dialog_path[512] = {0};
 static char file_dialog_complete_filename[512] = {0};
@@ -1825,6 +1975,12 @@ int files_startat = 0;
 int files_cur = 0;
 int files_stopat = 999;
 
+struct LISTDIRINFO
+{
+	CUIRect *rect;
+	EDITOR *editor;
+};
+
 static void editor_listdir_callback(const char *name, int is_dir, void *user)
 {
 	if(name[0] == '.' || is_dir) // skip this shit!
@@ -1837,13 +1993,14 @@ static void editor_listdir_callback(const char *name, int is_dir, void *user)
 	if(files_cur-1 < files_startat || files_cur > files_stopat)
 		return;
 	
-	RECT *view = (RECT *)user;
-	RECT button;
-	ui_hsplit_t(view, 15.0f, &button, view);
-	ui_hsplit_t(view, 2.0f, 0, view);
+	LISTDIRINFO *info = (LISTDIRINFO *)user;
+	CUIRect *view = info->rect;
+	CUIRect button;
+	view->HSplitTop(15.0f, &button, view);
+	view->HSplitTop(2.0f, 0, view);
 	//char buf[512];
 	
-	if(do_editor_button((void*)(10+(int)button.y), name, 0, &button, draw_editor_button_file, 0, 0))
+	if(info->editor->DoButton_File((void*)(10+(int)button.y), name, 0, &button, 0, 0))
 	{
 		strncpy(file_dialog_filename, name, sizeof(file_dialog_filename));
 		
@@ -1854,43 +2011,43 @@ static void editor_listdir_callback(const char *name, int is_dir, void *user)
 		if(inp_mouse_doubleclick())
 		{
 			if(file_dialog_func)
-				file_dialog_func(file_dialog_complete_filename);
-			editor.dialog = DIALOG_NONE;
+				file_dialog_func(file_dialog_complete_filename, user);
+			info->editor->dialog = DIALOG_NONE;
 		}
 	}
 }
 
-static void render_file_dialog()
+void EDITOR::render_file_dialog()
 {
 	// GUI coordsys
-	gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
-	
-	RECT view = *ui_screen();
-	ui_draw_rect(&view, vec4(0,0,0,0.25f), 0, 0);
-	ui_vmargin(&view, 150.0f, &view);
-	ui_hmargin(&view, 50.0f, &view);
-	ui_draw_rect(&view, vec4(0,0,0,0.75f), CORNER_ALL, 5.0f);
-	ui_margin(&view, 10.0f, &view);
-
-	RECT title, filebox, filebox_label, buttonbar, scroll;
-	ui_hsplit_t(&view, 18.0f, &title, &view);
-	ui_hsplit_t(&view, 5.0f, 0, &view); // some spacing
-	ui_hsplit_b(&view, 14.0f, &view, &buttonbar);
-	ui_hsplit_b(&view, 10.0f, &view, 0); // some spacing
-	ui_hsplit_b(&view, 14.0f, &view, &filebox);
-	ui_vsplit_l(&filebox, 50.0f, &filebox_label, &filebox);
-	ui_vsplit_r(&view, 15.0f, &view, &scroll);
+	Graphics()->MapScreen(UI()->Screen()->x, UI()->Screen()->y, UI()->Screen()->w, UI()->Screen()->h);
+	
+	CUIRect view = *UI()->Screen();
+	RenderTools()->DrawUIRect(&view, vec4(0,0,0,0.25f), 0, 0);
+	view.VMargin(150.0f, &view);
+	view.HMargin(50.0f, &view);
+	RenderTools()->DrawUIRect(&view, vec4(0,0,0,0.75f), CUI::CORNER_ALL, 5.0f);
+	view.Margin(10.0f, &view);
+
+	CUIRect title, filebox, filebox_label, buttonbar, scroll;
+	view.HSplitTop(18.0f, &title, &view);
+	view.HSplitTop(5.0f, 0, &view); // some spacing
+	view.HSplitBottom(14.0f, &view, &buttonbar);
+	view.HSplitBottom(10.0f, &view, 0); // some spacing
+	view.HSplitBottom(14.0f, &view, &filebox);
+	filebox.VSplitLeft(50.0f, &filebox_label, &filebox);
+	view.VSplitRight(15.0f, &view, &scroll);
 	
 	// title
-	ui_draw_rect(&title, vec4(1,1,1,0.25f), CORNER_ALL, 5.0f);
-	ui_vmargin(&title, 10.0f, &title);
-	ui_do_label(&title, file_dialog_title, 14.0f, -1, -1);
+	RenderTools()->DrawUIRect(&title, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 5.0f);
+	title.VMargin(10.0f, &title);
+	UI()->DoLabel(&title, file_dialog_title, 14.0f, -1, -1);
 	
 	// filebox
-	ui_do_label(&filebox_label, "Filename:", 10.0f, -1, -1);
+	UI()->DoLabel(&filebox_label, "Filename:", 10.0f, -1, -1);
 	
 	static int filebox_id = 0;
-	ui_do_edit_box(&filebox_id, &filebox, file_dialog_filename, sizeof(file_dialog_filename), 10.0f);
+	DoEditBox(&filebox_id, &filebox, file_dialog_filename, sizeof(file_dialog_filename), 10.0f);
 
 	file_dialog_complete_filename[0] = 0;
 	strcat(file_dialog_complete_filename, file_dialog_path);
@@ -1899,7 +2056,7 @@ static void render_file_dialog()
 	int num = (int)(view.h/17.0);
 	static float scrollvalue = 0;
 	static int scrollbar = 0;
-	ui_hmargin(&scroll, 5.0f, &scroll);
+	scroll.HMargin(5.0f, &scroll);
 	scrollvalue = ui_do_scrollbar_v(&scrollbar, &scroll, scrollvalue);
 	
 	int scrollnum = files_num-num+10;
@@ -1925,41 +2082,45 @@ static void render_file_dialog()
 	files_cur = 0;
 	
 	// set clipping
-	ui_clip_enable(&view);
+	UI()->ClipEnable(&view);
 	
 	// the list
-	engine_listdir(file_dialog_dirtypes, file_dialog_path, editor_listdir_callback, &view);
+	LISTDIRINFO info;
+	info.rect = &view;
+	info.editor = this;
+	engine_listdir(file_dialog_dirtypes, file_dialog_path, editor_listdir_callback, &info);
 	
 	// disable clipping again
-	ui_clip_disable();
+	UI()->ClipDisable();
 	
 	// the buttons
 	static int ok_button = 0;	
 	static int cancel_button = 0;	
 
-	RECT button;
-	ui_vsplit_r(&buttonbar, 50.0f, &buttonbar, &button);
-	if(do_editor_button(&ok_button, file_dialog_button_text, 0, &button, draw_editor_button, 0, 0) || inp_key_pressed(KEY_RETURN))
+	CUIRect button;
+	buttonbar.VSplitRight(50.0f, &buttonbar, &button);
+	if(DoButton_Editor(&ok_button, file_dialog_button_text, 0, &button, 0, 0) || inp_key_pressed(KEY_RETURN))
 	{
 		if(file_dialog_func)
-			file_dialog_func(file_dialog_complete_filename);
-		editor.dialog = DIALOG_NONE;
+			file_dialog_func(file_dialog_complete_filename, file_dialog_user);
+		dialog = DIALOG_NONE;
 	}
 
-	ui_vsplit_r(&buttonbar, 40.0f, &buttonbar, &button);
-	ui_vsplit_r(&buttonbar, 50.0f, &buttonbar, &button);
-	if(do_editor_button(&cancel_button, "Cancel", 0, &button, draw_editor_button, 0, 0) || inp_key_pressed(KEY_ESCAPE))
-		editor.dialog = DIALOG_NONE;
+	buttonbar.VSplitRight(40.0f, &buttonbar, &button);
+	buttonbar.VSplitRight(50.0f, &buttonbar, &button);
+	if(DoButton_Editor(&cancel_button, "Cancel", 0, &button, 0, 0) || inp_key_pressed(KEY_ESCAPE))
+		dialog = DIALOG_NONE;
 }
 
 void EDITOR::invoke_file_dialog(int listdirtypes, const char *title, const char *button_text,
 	const char *basepath, const char *default_name,
-	void (*func)(const char *filename))
+	void (*func)(const char *filename, void *user), void *user)
 {
 	file_dialog_dirtypes = listdirtypes;
 	file_dialog_title = title;
 	file_dialog_button_text = button_text;
 	file_dialog_func = func;
+	file_dialog_user = user;
 	file_dialog_filename[0] = 0;
 	file_dialog_path[0] = 0;
 	
@@ -1968,78 +2129,78 @@ void EDITOR::invoke_file_dialog(int listdirtypes, const char *title, const char
 	if(basepath)
 		strncpy(file_dialog_path, basepath, sizeof(file_dialog_path));
 		
-	editor.dialog = DIALOG_FILE;
+	dialog = DIALOG_FILE;
 }
 
 
 
-static void render_modebar(RECT view)
+void EDITOR::render_modebar(CUIRect view)
 {
-	RECT button;
+	CUIRect button;
 
 	// mode buttons
 	{
-		ui_vsplit_l(&view, 40.0f, &button, &view);
+		view.VSplitLeft(40.0f, &button, &view);
 		static int tile_button = 0;
-		if(do_editor_button(&tile_button, "Layers", editor.mode == MODE_LAYERS, &button, draw_editor_button_m, 0, "Switch to edit layers."))
-			editor.mode = MODE_LAYERS;
+		if(DoButton_ButtonM(&tile_button, "Layers", mode == MODE_LAYERS, &button, 0, "Switch to edit layers."))
+			mode = MODE_LAYERS;
 
-		ui_vsplit_l(&view, 40.0f, &button, &view);
+		view.VSplitLeft(40.0f, &button, &view);
 		static int img_button = 0;
-		if(do_editor_button(&img_button, "Images", editor.mode == MODE_IMAGES, &button, draw_editor_button_r, 0, "Switch to manage images."))
-			editor.mode = MODE_IMAGES;
+		if(DoButton_ButtonR(&img_button, "Images", mode == MODE_IMAGES, &button, 0, "Switch to manage images."))
+			mode = MODE_IMAGES;
 	}
 
-	ui_vsplit_l(&view, 5.0f, 0, &view);
+	view.VSplitLeft(5.0f, 0, &view);
 	
 	// spacing
-	//ui_vsplit_l(&view, 10.0f, 0, &view);
+	//view.VSplitLeft(10.0f, 0, &view);
 }
 
-static void render_statusbar(RECT view)
+void EDITOR::render_statusbar(CUIRect view)
 {
-	RECT button;
-	ui_vsplit_r(&view, 60.0f, &view, &button);
+	CUIRect button;
+	view.VSplitRight(60.0f, &view, &button);
 	static int envelope_button = 0;
-	if(do_editor_button(&envelope_button, "Envelopes", editor.show_envelope_editor, &button, draw_editor_button, 0, "Toggles the envelope editor."))
-		editor.show_envelope_editor = (editor.show_envelope_editor+1)%4;
+	if(DoButton_Editor(&envelope_button, "Envelopes", show_envelope_editor, &button, 0, "Toggles the envelope editor."))
+		show_envelope_editor = (show_envelope_editor+1)%4;
 	
-	if(editor.tooltip)
+	if(tooltip)
 	{
-		if(ui_got_context && ui_got_context == ui_hot_item())
+		if(ui_got_context && ui_got_context == UI()->HotItem())
 		{
 			char buf[512];
-			sprintf(buf, "%s Right click for context menu.", editor.tooltip);
-			ui_do_label(&view, buf, 10.0f, -1, -1);
+			sprintf(buf, "%s Right click for context menu.", tooltip);
+			UI()->DoLabel(&view, buf, 10.0f, -1, -1);
 		}
 		else
-			ui_do_label(&view, editor.tooltip, 10.0f, -1, -1);
+			UI()->DoLabel(&view, tooltip, 10.0f, -1, -1);
 	}
 }
 
-static void render_envelopeeditor(RECT view)
+void EDITOR::render_envelopeeditor(CUIRect view)
 {
-	if(editor.selected_envelope < 0) editor.selected_envelope = 0;
-	if(editor.selected_envelope >= editor.map.envelopes.len()) editor.selected_envelope--;
+	if(selected_envelope < 0) selected_envelope = 0;
+	if(selected_envelope >= map.envelopes.len()) selected_envelope--;
 
 	ENVELOPE *envelope = 0;
-	if(editor.selected_envelope >= 0 && editor.selected_envelope < editor.map.envelopes.len())
-		envelope = editor.map.envelopes[editor.selected_envelope];
+	if(selected_envelope >= 0 && selected_envelope < map.envelopes.len())
+		envelope = map.envelopes[selected_envelope];
 
 	bool show_colorbar = false;
 	if(envelope && envelope->channels == 4)
 		show_colorbar = true;
 
-	RECT toolbar, curvebar, colorbar;
-	ui_hsplit_t(&view, 15.0f, &toolbar, &view);
-	ui_hsplit_t(&view, 15.0f, &curvebar, &view);
-	ui_margin(&toolbar, 2.0f, &toolbar);
-	ui_margin(&curvebar, 2.0f, &curvebar);
+	CUIRect toolbar, curvebar, colorbar;
+	view.HSplitTop(15.0f, &toolbar, &view);
+	view.HSplitTop(15.0f, &curvebar, &view);
+	toolbar.Margin(2.0f, &toolbar);
+	curvebar.Margin(2.0f, &curvebar);
 
 	if(show_colorbar)
 	{
-		ui_hsplit_t(&view, 20.0f, &colorbar, &view);
-		ui_margin(&colorbar, 2.0f, &colorbar);
+		view.HSplitTop(20.0f, &colorbar, &view);
+		colorbar.Margin(2.0f, &colorbar);
 		render_background(colorbar, checker_texture, 16.0f, 1.0f);
 	}
 
@@ -2047,19 +2208,19 @@ static void render_envelopeeditor(RECT view)
 
 	// do the toolbar
 	{
-		RECT button;
+		CUIRect button;
 		ENVELOPE *new_env = 0;
 		
-		ui_vsplit_r(&toolbar, 50.0f, &toolbar, &button);
+		toolbar.VSplitRight(50.0f, &toolbar, &button);
 		static int new_4d_button = 0;
-		if(do_editor_button(&new_4d_button, "Color+", 0, &button, draw_editor_button, 0, "Creates a new color envelope"))
-			new_env = editor.map.new_envelope(4);
+		if(DoButton_Editor(&new_4d_button, "Color+", 0, &button, 0, "Creates a new color envelope"))
+			new_env = map.new_envelope(4);
 
-		ui_vsplit_r(&toolbar, 5.0f, &toolbar, &button);
-		ui_vsplit_r(&toolbar, 50.0f, &toolbar, &button);
+		toolbar.VSplitRight(5.0f, &toolbar, &button);
+		toolbar.VSplitRight(50.0f, &toolbar, &button);
 		static int new_2d_button = 0;
-		if(do_editor_button(&new_2d_button, "Pos.+", 0, &button, draw_editor_button, 0, "Creates a new pos envelope"))
-			new_env = editor.map.new_envelope(3);
+		if(DoButton_Editor(&new_2d_button, "Pos.+", 0, &button, 0, "Creates a new pos envelope"))
+			new_env = map.new_envelope(3);
 		
 		if(new_env) // add the default points
 		{
@@ -2075,33 +2236,33 @@ static void render_envelopeeditor(RECT view)
 			}
 		}
 		
-		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);
+		CUIRect shifter, inc, dec;
+		toolbar.VSplitLeft(60.0f, &shifter, &toolbar);
+		shifter.VSplitRight(15.0f, &shifter, &inc);
+		shifter.VSplitLeft(15.0f, &dec, &shifter);
 		char buf[512];
-		sprintf(buf, "%d/%d", editor.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, 10.0f, 0, -1);
+		sprintf(buf, "%d/%d", selected_envelope+1, map.envelopes.len());
+		RenderTools()->DrawUIRect(&shifter, vec4(1,1,1,0.5f), 0, 0.0f);
+		UI()->DoLabel(&shifter, buf, 10.0f, 0, -1);
 		
 		static int prev_button = 0;
-		if(do_editor_button(&prev_button, 0, 0, &dec, draw_dec_button, 0, "Previous Envelope"))
-			editor.selected_envelope--;
+		if(DoButton_ButtonDec(&prev_button, 0, 0, &dec, 0, "Previous Envelope"))
+			selected_envelope--;
 		
 		static int next_button = 0;
-		if(do_editor_button(&next_button, 0, 0, &inc, draw_inc_button, 0, "Next Envelope"))
-			editor.selected_envelope++;
+		if(DoButton_ButtonInc(&next_button, 0, 0, &inc, 0, "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:", 10.0f, -1, -1);
+			toolbar.VSplitLeft(15.0f, &button, &toolbar);
+			toolbar.VSplitLeft(35.0f, &button, &toolbar);
+			UI()->DoLabel(&button, "Name:", 10.0f, -1, -1);
 
-			ui_vsplit_l(&toolbar, 80.0f, &button, &toolbar);
+			toolbar.VSplitLeft(80.0f, &button, &toolbar);
 			
 			static int name_box = 0;
-			ui_do_edit_box(&name_box, &button, envelope->name, sizeof(envelope->name), 10.0f);
+			DoEditBox(&name_box, &button, envelope->name, sizeof(envelope->name), 10.0f);
 		}
 	}
 	
@@ -2113,9 +2274,9 @@ static void render_envelopeeditor(RECT view)
 		
 		if(envelope)
 		{
-			RECT button;	
+			CUIRect button;	
 			
-			ui_vsplit_l(&toolbar, 15.0f, &button, &toolbar);
+			toolbar.VSplitLeft(15.0f, &button, &toolbar);
 
 			static const char *names[4][4] = {
 				{"X", "", "", ""},
@@ -2126,17 +2287,17 @@ static void render_envelopeeditor(RECT view)
 			
 			static int channel_buttons[4] = {0};
 			int bit = 1;
-			ui_draw_button_func draw_func;
+			/*ui_draw_button_func draw_func;*/
 			
 			for(int i = 0; i < envelope->channels; i++, bit<<=1)
 			{
-				ui_vsplit_l(&toolbar, 15.0f, &button, &toolbar);
+				toolbar.VSplitLeft(15.0f, &button, &toolbar);
 				
-				if(i == 0) draw_func = draw_editor_button_l;
+				/*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;
+				else draw_func = draw_editor_button_m;*/
 				
-				if(do_editor_button(&channel_buttons[i], names[envelope->channels-1][i], active_channels&bit, &button, draw_func, 0, 0))
+				if(DoButton_Editor(&channel_buttons[i], names[envelope->channels-1][i], active_channels&bit, &button, 0, 0))
 					active_channels ^= bit;
 			}
 		}		
@@ -2157,19 +2318,19 @@ static void render_envelopeeditor(RECT view)
 		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()->MouseInside(&view))
+			UI()->SetHotItem(&envelope_editor_id);
 			
-		if(ui_hot_item() == &envelope_editor_id)
+		if(UI()->HotItem() == &envelope_editor_id)
 		{
 			// do stuff
 			if(envelope)
 			{
-				if(ui_mouse_button_clicked(1))
+				if(UI()->MouseButtonClicked(1))
 				{
 					// add point
-					int time = (int)(((ui_mouse_x()-view.x)*timescale)*1000.0f);
-					//float env_y = (ui_mouse_y()-view.y)/timescale;
+					int time = (int)(((UI()->MouseX()-view.x)*timescale)*1000.0f);
+					//float env_y = (UI()->MouseY()-view.y)/timescale;
 					float channels[4];
 					envelope->eval(time, channels);
 					envelope->add_point(time,
@@ -2177,7 +2338,7 @@ static void render_envelopeeditor(RECT view)
 						f2fx(channels[2]), f2fx(channels[3]));
 				}
 				
-				editor.tooltip = "Press right mouse button to create a new point";
+				tooltip = "Press right mouse button to create a new point";
 			}
 		}
 
@@ -2185,22 +2346,22 @@ static void render_envelopeeditor(RECT view)
 
 		// render lines
 		{
-			ui_clip_enable(&view);
-			gfx_texture_set(-1);
-			gfx_lines_begin();
+			UI()->ClipEnable(&view);
+			Graphics()->TextureSet(-1);
+			Graphics()->LinesBegin();
 			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);
+					Graphics()->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);
+					Graphics()->SetColor(colors[c].r*0.5f,colors[c].g*0.5f,colors[c].b*0.5f,1);
 				
 				float prev_x = 0;
 				float results[4];
 				envelope->eval(0.000001f, results);
 				float prev_value = results[c];
 				
-				int steps = (int)((view.w/ui_screen()->w) * gfx_screenwidth());
+				int steps = (int)((view.w/UI()->Screen()->w) * Graphics()->ScreenWidth());
 				for(int i = 1; i <= steps; i++)
 				{
 					float a = i/(float)steps;
@@ -2208,13 +2369,13 @@ static void render_envelopeeditor(RECT view)
 					float v = results[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);
+					Graphics()->LinesDraw(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();
-			ui_clip_disable();
+			Graphics()->LinesEnd();
+			UI()->ClipDisable();
 		}
 		
 		// render curve options
@@ -2226,7 +2387,7 @@ static void render_envelopeeditor(RECT view)
 
 				//dbg_msg("", "%f", end_time);
 				
-				RECT v;
+				CUIRect v;
 				v.x = curvebar.x + (t0+(t1-t0)*0.5f) * curvebar.w;
 				v.y = curvebar.y;
 				v.h = curvebar.h;
@@ -2237,7 +2398,7 @@ static void render_envelopeeditor(RECT view)
 					"N", "L", "S", "F", "M"
 					};
 				
-				if(do_editor_button(id, type_name[envelope->points[i].curvetype], 0, &v, draw_editor_button, 0, "Switch curve type"))
+				if(DoButton_Editor(id, type_name[envelope->points[i].curvetype], 0, &v, 0, "Switch curve type"))
 					envelope->points[i].curvetype = (envelope->points[i].curvetype+1)%NUM_CURVETYPES;
 			}
 		}
@@ -2245,8 +2406,8 @@ static void render_envelopeeditor(RECT view)
 		// render colorbar
 		if(show_colorbar)
 		{
-			gfx_texture_set(-1);
-			gfx_quads_begin();
+			Graphics()->TextureSet(-1);
+			Graphics()->QuadsBegin();
 			for(int i = 0; i < envelope->points.len()-1; i++)
 			{
 				float r0 = fx2f(envelope->points[i].values[0]);
@@ -2258,24 +2419,24 @@ static void render_envelopeeditor(RECT view)
 				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);
+				Graphics()->SetColorVertex(0, r0, g0, b0, a0);
+				Graphics()->SetColorVertex(1, r1, g1, b1, a1);
+				Graphics()->SetColorVertex(2, r1, g1, b1, a1);
+				Graphics()->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;
+				CUIRect 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);
+				Graphics()->QuadsDrawTL(v.x, v.y, v.w, v.h);
 			}
-			gfx_quads_end();
+			Graphics()->QuadsEnd();
 		}
 		
 		// render handles
@@ -2284,8 +2445,8 @@ static void render_envelopeeditor(RECT view)
 			
 			int current_value = 0, current_time = 0;
 			
-			gfx_texture_set(-1);
-			gfx_quads_begin();
+			Graphics()->TextureSet(-1);
+			Graphics()->QuadsBegin();
 			for(int c = 0; c < envelope->channels; c++)
 			{
 				if(!(active_channels&(1<<c)))
@@ -2295,7 +2456,7 @@ static void render_envelopeeditor(RECT view)
 				{
 					float x0 = envelope->points[i].time/1000.0f/end_time;
 					float y0 = (fx2f(envelope->points[i].values[c])-bottom)/(top-bottom);
-					RECT final;
+					CUIRect final;
 					final.x = view.x + x0*view.w;
 					final.y = view.y+view.h - y0*view.h;
 					final.x -= 2.0f;
@@ -2305,26 +2466,26 @@ static void render_envelopeeditor(RECT view)
 					
 					void *id = &envelope->points[i].values[c];
 					
-					if(ui_mouse_inside(&final))
-						ui_set_hot_item(id);
+					if(UI()->MouseInside(&final))
+						UI()->SetHotItem(id);
 						
 					float colormod = 1.0f;
 
-					if(ui_active_item() == id)
+					if(UI()->ActiveItem() == id)
 					{
-						if(!ui_mouse_button(0))
+						if(!UI()->MouseButton(0))
 						{
-							ui_set_active_item(0);
+							UI()->SetActiveItem(0);
 							move = false;
 						}
 						else
 						{
-							envelope->points[i].values[c] -= f2fx(editor.mouse_delta_y*valuescale);
+							envelope->points[i].values[c] -= f2fx(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);
+									envelope->points[i].time += (int)((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)
@@ -2334,46 +2495,46 @@ static void render_envelopeeditor(RECT view)
 						}
 						
 						colormod = 100.0f;
-						gfx_setcolor(1,1,1,1);
+						Graphics()->SetColor(1,1,1,1);
 					}
-					else if(ui_hot_item() == id)
+					else if(UI()->HotItem() == id)
 					{
-						if(ui_mouse_button(0))
+						if(UI()->MouseButton(0))
 						{
 							selection.clear();
 							selection.add(i);
-							ui_set_active_item(id);
+							UI()->SetActiveItem(id);
 						}
 
 						// remove point
-						if(ui_mouse_button_clicked(1))
+						if(UI()->MouseButtonClicked(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.";
+						Graphics()->SetColor(1,0.75f,0.75f,1);
+						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)
+					if(UI()->ActiveItem() == id || UI()->HotItem() == 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);
+					Graphics()->SetColor(colors[c].r*colormod, colors[c].g*colormod, colors[c].b*colormod, 1.0f);
+					Graphics()->QuadsDrawTL(final.x, final.y, final.w, final.h);
 				}
 			}
-			gfx_quads_end();
+			Graphics()->QuadsEnd();
 
 			char buf[512];
 			sprintf(buf, "%.3f %.3f", current_time/1000.0f, fx2f(current_value));
-			ui_do_label(&toolbar, buf, 10.0f, 0, -1);
+			UI()->DoLabel(&toolbar, buf, 10.0f, 0, -1);
 		}
 	}
 }
 
-static int popup_menu_file(RECT view)
+int EDITOR::popup_menu_file(EDITOR *pEditor, CUIRect view)
 {
 	static int new_map_button = 0;
 	static int save_button = 0;
@@ -2382,49 +2543,49 @@ static int popup_menu_file(RECT view)
 	static int append_button = 0;
 	static int exit_button = 0;
 
-	RECT slot;
-	ui_hsplit_t(&view, 2.0f, &slot, &view);
-	ui_hsplit_t(&view, 12.0f, &slot, &view);
-	if(do_editor_button(&new_map_button, "New", 0, &slot, draw_editor_button_menuitem, 0, "Creates a new map"))
+	CUIRect slot;
+	view.HSplitTop(2.0f, &slot, &view);
+	view.HSplitTop(12.0f, &slot, &view);
+	if(pEditor->DoButton_MenuItem(&new_map_button, "New", 0, &slot, 0, "Creates a new map"))
 	{
-		editor.reset();
+		pEditor->reset();
 		return 1;
 	}
 
-	ui_hsplit_t(&view, 10.0f, &slot, &view);
-	ui_hsplit_t(&view, 12.0f, &slot, &view);
-	if(do_editor_button(&open_button, "Open", 0, &slot, draw_editor_button_menuitem, 0, "Opens a map for editing"))
+	view.HSplitTop(10.0f, &slot, &view);
+	view.HSplitTop(12.0f, &slot, &view);
+	if(pEditor->DoButton_MenuItem(&open_button, "Open", 0, &slot, 0, "Opens a map for editing"))
 	{
-		editor.invoke_file_dialog(LISTDIRTYPE_ALL, "Open Map", "Open", "maps/", "", callback_open_map);
+		pEditor->invoke_file_dialog(LISTDIRTYPE_ALL, "Open Map", "Open", "maps/", "", callback_open_map, pEditor);
 		return 1;
 	}
 
-	ui_hsplit_t(&view, 10.0f, &slot, &view);
-	ui_hsplit_t(&view, 12.0f, &slot, &view);
-	if(do_editor_button(&append_button, "Append", 0, &slot, draw_editor_button_menuitem, 0, "Opens a map and adds everything from that map to the current one"))
+	view.HSplitTop(10.0f, &slot, &view);
+	view.HSplitTop(12.0f, &slot, &view);
+	if(pEditor->DoButton_MenuItem(&append_button, "Append", 0, &slot, 0, "Opens a map and adds everything from that map to the current one"))
 	{
-		editor.invoke_file_dialog(LISTDIRTYPE_ALL, "Append Map", "Append", "maps/", "", callback_append_map);
+		pEditor->invoke_file_dialog(LISTDIRTYPE_ALL, "Append Map", "Append", "maps/", "", callback_append_map, pEditor);
 		return 1;
 	}
 
-	ui_hsplit_t(&view, 10.0f, &slot, &view);
-	ui_hsplit_t(&view, 12.0f, &slot, &view);
-	if(do_editor_button(&save_button, "Save (NOT IMPL)", 0, &slot, draw_editor_button_menuitem, 0, "Saves the current map"))
+	view.HSplitTop(10.0f, &slot, &view);
+	view.HSplitTop(12.0f, &slot, &view);
+	if(pEditor->DoButton_MenuItem(&save_button, "Save (NOT IMPL)", 0, &slot, 0, "Saves the current map"))
 	{
 		return 1;
 	}
 
-	ui_hsplit_t(&view, 2.0f, &slot, &view);
-	ui_hsplit_t(&view, 12.0f, &slot, &view);
-	if(do_editor_button(&save_as_button, "Save As", 0, &slot, draw_editor_button_menuitem, 0, "Saves the current map under a new name"))
+	view.HSplitTop(2.0f, &slot, &view);
+	view.HSplitTop(12.0f, &slot, &view);
+	if(pEditor->DoButton_MenuItem(&save_as_button, "Save As", 0, &slot, 0, "Saves the current map under a new name"))
 	{
-		editor.invoke_file_dialog(LISTDIRTYPE_SAVE, "Save Map", "Save", "maps/", "", callback_save_map);
+		pEditor->invoke_file_dialog(LISTDIRTYPE_SAVE, "Save Map", "Save", "maps/", "", callback_save_map, pEditor);
 		return 1;
 	}
 	
-	ui_hsplit_t(&view, 10.0f, &slot, &view);
-	ui_hsplit_t(&view, 12.0f, &slot, &view);
-	if(do_editor_button(&exit_button, "Exit", 0, &slot, draw_editor_button_menuitem, 0, "Exits from the editor"))
+	view.HSplitTop(10.0f, &slot, &view);
+	view.HSplitTop(12.0f, &slot, &view);
+	if(pEditor->DoButton_MenuItem(&exit_button, "Exit", 0, &slot, 0, "Exits from the editor"))
 	{
 		config.cl_editor = 0;
 		return 1;
@@ -2433,22 +2594,22 @@ static int popup_menu_file(RECT view)
 	return 0;
 }
 
-static void render_menubar(RECT menubar)
+void EDITOR::render_menubar(CUIRect menubar)
 {
-	static RECT file /*, view, help*/;
+	static CUIRect file /*, view, help*/;
 
-	ui_vsplit_l(&menubar, 60.0f, &file, &menubar);
-	if(do_editor_button(&file, "File", 0, &file, draw_editor_button_menu, 0, 0))
-		ui_invoke_popup_menu(&file, 1, file.x, file.y+file.h-1.0f, 120, 150, popup_menu_file);
+	menubar.VSplitLeft(60.0f, &file, &menubar);
+	if(DoButton_Menu(&file, "File", 0, &file, 0, 0))
+		ui_invoke_popup_menu(&file, 1, file.x, file.y+file.h-1.0f, 120, 150, popup_menu_file, this);
 	
 	/*
-	ui_vsplit_l(&menubar, 5.0f, 0, &menubar);
-	ui_vsplit_l(&menubar, 60.0f, &view, &menubar);
+	menubar.VSplitLeft(5.0f, 0, &menubar);
+	menubar.VSplitLeft(60.0f, &view, &menubar);
 	if(do_editor_button(&view, "View", 0, &view, draw_editor_button_menu, 0, 0))
 		(void)0;
 
-	ui_vsplit_l(&menubar, 5.0f, 0, &menubar);
-	ui_vsplit_l(&menubar, 60.0f, &help, &menubar);
+	menubar.VSplitLeft(5.0f, 0, &menubar);
+	menubar.VSplitLeft(60.0f, &help, &menubar);
 	if(do_editor_button(&help, "Help", 0, &help, draw_editor_button_menu, 0, 0))
 		(void)0;
 		*/
@@ -2457,102 +2618,102 @@ static void render_menubar(RECT menubar)
 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);
+	Graphics()->Clear(1.0f,0.0f,1.0f);
+	CUIRect view = *UI()->Screen();
+	Graphics()->MapScreen(UI()->Screen()->x, UI()->Screen()->y, UI()->Screen()->w, UI()->Screen()->h);
 	
 	// reset tip
-	editor.tooltip = 0;
+	tooltip = 0;
 	
 	// render checker
 	render_background(view, checker_texture, 32.0f, 1.0f);
 	
-	RECT menubar, modebar, toolbar, statusbar, envelope_editor, toolbox;
+	CUIRect menubar, modebar, toolbar, statusbar, envelope_editor, toolbox;
 	
-	if(editor.gui_active)
+	if(gui_active)
 	{
 		
-		ui_hsplit_t(&view, 16.0f, &menubar, &view);
-		ui_vsplit_l(&view, 80.0f, &toolbox, &view);
-		ui_hsplit_t(&view, 16.0f, &toolbar, &view);
-		ui_hsplit_b(&view, 16.0f, &view, &statusbar);
+		view.HSplitTop(16.0f, &menubar, &view);
+		view.VSplitLeft(80.0f, &toolbox, &view);
+		view.HSplitTop(16.0f, &toolbar, &view);
+		view.HSplitBottom(16.0f, &view, &statusbar);
 
-		if(editor.show_envelope_editor)
+		if(show_envelope_editor)
 		{
 			float size = 125.0f;
-			if(editor.show_envelope_editor == 2)
+			if(show_envelope_editor == 2)
 				size *= 2.0f;
-			else if(editor.show_envelope_editor == 3)
+			else if(show_envelope_editor == 3)
 				size *= 3.0f;
-			ui_hsplit_b(&view, size, &view, &envelope_editor);
+			view.HSplitBottom(size, &view, &envelope_editor);
 		}
 	}
 	
 	//	a little hack for now
-	if(editor.mode == MODE_LAYERS)
+	if(mode == MODE_LAYERS)
 		do_map_editor(view, toolbar);
 	
-	if(editor.gui_active)
+	if(gui_active)
 	{
 		float brightness = 0.25f;
 		render_background(menubar, background_texture, 128.0f, brightness*0);
-		ui_margin(&menubar, 2.0f, &menubar);
+		menubar.Margin(2.0f, &menubar);
 
 		render_background(toolbox, background_texture, 128.0f, brightness);
-		ui_margin(&toolbox, 2.0f, &toolbox);
+		toolbox.Margin(2.0f, &toolbox);
 		
 		render_background(toolbar, background_texture, 128.0f, brightness);
-		ui_margin(&toolbar, 2.0f, &toolbar);
-		ui_vsplit_l(&toolbar, 150.0f, &modebar, &toolbar);
+		toolbar.Margin(2.0f, &toolbar);
+		toolbar.VSplitLeft(150.0f, &modebar, &toolbar);
 
 		render_background(statusbar, background_texture, 128.0f, brightness);
-		ui_margin(&statusbar, 2.0f, &statusbar);
+		statusbar.Margin(2.0f, &statusbar);
 		
 		// do the toolbar
-		if(editor.mode == MODE_LAYERS)
+		if(mode == MODE_LAYERS)
 			do_toolbar(toolbar);
 		
-		if(editor.show_envelope_editor)
+		if(show_envelope_editor)
 		{
 			render_background(envelope_editor, background_texture, 128.0f, brightness);
-			ui_margin(&envelope_editor, 2.0f, &envelope_editor);
+			envelope_editor.Margin(2.0f, &envelope_editor);
 		}
 	}
 		
 	
-	if(editor.mode == MODE_LAYERS)
+	if(mode == MODE_LAYERS)
 		render_layers(toolbox, toolbar, view);
-	else if(editor.mode == MODE_IMAGES)
+	else if(mode == MODE_IMAGES)
 		render_images(toolbox, toolbar, view);
 
-	gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
+	Graphics()->MapScreen(UI()->Screen()->x, UI()->Screen()->y, UI()->Screen()->w, UI()->Screen()->h);
 
-	if(editor.gui_active)
+	if(gui_active)
 	{
 		render_menubar(menubar);
 		
 		render_modebar(modebar);
-		if(editor.show_envelope_editor)
+		if(show_envelope_editor)
 			render_envelopeeditor(envelope_editor);
 	}
 
-	if(editor.dialog == DIALOG_FILE)
+	if(dialog == DIALOG_FILE)
 	{
 		static int null_ui_target = 0;
-		ui_set_hot_item(&null_ui_target);
+		UI()->SetHotItem(&null_ui_target);
 		render_file_dialog();
 	}
 	
 	
 	ui_do_popup_menu();
 
-	if(editor.gui_active)
+	if(gui_active)
 		render_statusbar(statusbar);
 
 	//
 	if(config.ed_showkeys)
 	{
-		gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h);
+		Graphics()->MapScreen(UI()->Screen()->x, UI()->Screen()->y, UI()->Screen()->w, UI()->Screen()->h);
 		TEXT_CURSOR cursor;
 		gfx_text_set_cursor(&cursor, view.x+10, view.y+view.h-24-10, 24.0f, TEXTFLAG_RENDER);
 		
@@ -2569,28 +2730,28 @@ void EDITOR::render()
 		}
 	}
 	
-	if (editor.show_mouse_pointer)
+	if(show_mouse_pointer)
 	{
 		// render butt ugly mouse cursor
-		float mx = ui_mouse_x();
-		float my = ui_mouse_y();
-		gfx_texture_set(cursor_texture);
-		gfx_quads_begin();
-		if(ui_got_context == ui_hot_item())
-			gfx_setcolor(1,0,0,1);
-		gfx_quads_drawTL(mx,my, 16.0f, 16.0f);
-		gfx_quads_end();
+		float mx = UI()->MouseX();
+		float my = UI()->MouseY();
+		Graphics()->TextureSet(cursor_texture);
+		Graphics()->QuadsBegin();
+		if(ui_got_context == UI()->HotItem())
+			Graphics()->SetColor(1,0,0,1);
+		Graphics()->QuadsDrawTL(mx,my, 16.0f, 16.0f);
+		Graphics()->QuadsEnd();
 	}
 	
 }
 
 void EDITOR::reset(bool create_default)
 {
-	editor.map.clean();
+	map.clean();
 
 	// create default layers
 	if(create_default)
-		editor.map.create_default(entities_texture);
+		map.create_default(entities_texture);
 	
 	/*
 	{
@@ -2636,28 +2797,30 @@ void MAP::create_default(int entities_texture)
 	game_group->add_layer(game_layer);
 }
 
-extern "C" void editor_init()
+void EDITOR::Init(class IGraphics *pGraphics)
 {
-	checker_texture = gfx_load_texture("editor/checker.png", IMG_AUTO, 0);
-	background_texture = gfx_load_texture("editor/background.png", IMG_AUTO, 0);
-	cursor_texture = gfx_load_texture("editor/cursor.png", IMG_AUTO, 0);
-	entities_texture = gfx_load_texture("editor/entities.png", IMG_AUTO, 0);
+	m_pGraphics = pGraphics;
+	
+	checker_texture = Graphics()->LoadTexture("editor/checker.png", IMG_AUTO, 0);
+	background_texture = Graphics()->LoadTexture("editor/background.png", IMG_AUTO, 0);
+	cursor_texture = Graphics()->LoadTexture("editor/cursor.png", IMG_AUTO, 0);
+	entities_texture = Graphics()->LoadTexture("editor/entities.png", IMG_AUTO, 0);
 	
 	tileset_picker.make_palette();
 	tileset_picker.readonly = true;
 	
-	editor.reset();
+	reset();
 }
 
-extern "C" void editor_update_and_render()
+void EDITOR::UpdateAndRender()
 {
 	static int mouse_x = 0;
 	static int mouse_y = 0;
 	
-	if(editor.animate)
-		editor.animate_time = (time_get()-editor.animate_start)/(float)time_freq();
+	if(animate)
+		animate_time = (time_get()-animate_start)/(float)time_freq();
 	else
-		editor.animate_time = 0;
+		animate_time = 0;
 	ui_got_context = 0;
 
 	// handle mouse movement
@@ -2665,10 +2828,10 @@ extern "C" void editor_update_and_render()
 	int rx, ry;
 	{
 		inp_mouse_relative(&rx, &ry);
-		editor.mouse_delta_x = rx;
-		editor.mouse_delta_y = ry;
+		mouse_delta_x = rx;
+		mouse_delta_y = ry;
 		
-		if(!editor.lock_mouse)
+		if(!lock_mouse)
 		{
 			mouse_x += rx;
 			mouse_y += ry;
@@ -2676,8 +2839,8 @@ extern "C" void editor_update_and_render()
 		
 		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;
-		if(mouse_y > ui_screen()->h) mouse_y = (int)ui_screen()->h;
+		if(mouse_x > UI()->Screen()->w) mouse_x = (int)UI()->Screen()->w;
+		if(mouse_y > UI()->Screen()->h) mouse_y = (int)UI()->Screen()->h;
 
 		// update the ui
 		mx = mouse_x;
@@ -2686,7 +2849,7 @@ extern "C" void editor_update_and_render()
 		mwy = 0;
 		
 		// fix correct world x and y
-		LAYERGROUP *g = editor.get_selected_group();
+		LAYERGROUP *g = get_selected_group();
 		if(g)
 		{
 			float points[4];
@@ -2695,10 +2858,10 @@ extern "C" void editor_update_and_render()
 			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);
+			mwx = points[0] + world_width * (mouse_x/UI()->Screen()->w);
+			mwy = points[1] + world_height * (mouse_y/UI()->Screen()->h);
+			mouse_delta_wx = mouse_delta_x*(world_width / UI()->Screen()->w);
+			mouse_delta_wy = mouse_delta_y*(world_height / UI()->Screen()->h);
 		}
 		
 		int buttons = 0;
@@ -2706,33 +2869,34 @@ extern "C" void editor_update_and_render()
 		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);
+		UI()->Update(mx,my,mwx,mwy,buttons);
 	}
 	
 	// toggle gui
 	if(inp_key_down(KEY_TAB))
-		editor.gui_active = !editor.gui_active;
+		gui_active = !gui_active;
 
 	if(inp_key_down(KEY_F5))
-		editor.save("maps/debug_test2.map");
+		save("maps/debug_test2.map");
 
 	if(inp_key_down(KEY_F6))
-		editor.load("maps/debug_test2.map");
+		load("maps/debug_test2.map");
 	
 	if(inp_key_down(KEY_F8))
-		editor.load("maps/debug_test.map");
+		load("maps/debug_test.map");
 	
 	if(inp_key_down(KEY_F10))
-		editor.show_mouse_pointer = false;
+		show_mouse_pointer = false;
 	
-	editor.render();
+	render();
 	
 	if(inp_key_down(KEY_F10))
 	{
-		gfx_screenshot();
-		editor.show_mouse_pointer = true;
+		Graphics()->TakeScreenshot();
+		show_mouse_pointer = true;
 	}
 	
 	inp_clear_events();
 }
 
+IEditor *CreateEditor() { return new EDITOR; }
diff --git a/src/game/editor/ed_editor.hpp b/src/game/editor/ed_editor.hpp
index 313a381f..98d1d960 100644
--- a/src/game/editor/ed_editor.hpp
+++ b/src/game/editor/ed_editor.hpp
@@ -9,16 +9,17 @@
 #include "../mapitems.hpp"
 #include "../client/render.hpp"
 
-extern "C" {
-	#include <engine/e_client_interface.h>
-	#include <engine/e_datafile.h>
-	#include <engine/e_config.h>
-}
+#include <engine/e_client_interface.h>
+#include <engine/e_datafile.h>
+#include <engine/e_config.h>
+#include <engine/client/editor.h>
 
 #include <game/client/ui.hpp>
 
 typedef void (*INDEX_MODIFY_FUNC)(int *index);
 
+//CRenderTools m_RenderTools;
+
 // EDITOR SPECIFIC
 template<typename T>
 void swap(T &a, T &b)
@@ -96,7 +97,7 @@ public:
 	
 	int eval(float time, float *result)
 	{
-		render_eval_envelope(points.getptr(), points.len(), channels, time, result);
+		CRenderTools::render_eval_envelope(points.getptr(), points.len(), channels, time, result);
 		return channels;
 	}
 	
@@ -129,6 +130,9 @@ class MAP;
 class LAYER
 {
 public:
+	class EDITOR *editor;
+	class IGraphics *Graphics();
+
 	LAYER()
 	{
 		type = LAYERTYPE_INVALID;
@@ -136,6 +140,7 @@ public:
 		visible = true;
 		readonly = false;
 		flags = 0;
+		editor = 0;
 	}
 	
 	virtual ~LAYER()
@@ -143,8 +148,8 @@ public:
 	}
 	
 	
-	virtual void brush_selecting(RECT rect) {}
-	virtual int brush_grab(LAYERGROUP *brush, RECT rect) { return 0; }
+	virtual void brush_selecting(CUIRect rect) {}
+	virtual int brush_grab(LAYERGROUP *brush, CUIRect 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() {}
@@ -152,7 +157,7 @@ public:
 	virtual void brush_rotate(float amount) {}
 	
 	virtual void render() {}
-	virtual int render_properties(RECT *toolbox) { return 0; }
+	virtual int render_properties(CUIRect *toolbox) { return 0; }
 	
 	virtual void modify_image_index(INDEX_MODIFY_FUNC func) {}
 	virtual void modify_envelope_index(INDEX_MODIFY_FUNC func) {}
@@ -170,6 +175,8 @@ public:
 class LAYERGROUP
 {
 public:
+	class MAP *m_pMap;
+	
 	array<LAYER*> layers;
 	
 	int offset_x;
@@ -191,7 +198,7 @@ public:
 	LAYERGROUP();
 	~LAYERGROUP();
 	
-	void convert(RECT *rect);
+	void convert(CUIRect *rect);
 	void render();
 	void mapscreen();
 	void mapping(float *points);
@@ -221,8 +228,11 @@ public:
 class EDITOR_IMAGE : public IMAGE_INFO
 {
 public:
-	EDITOR_IMAGE()
+	EDITOR *editor;
+	
+	EDITOR_IMAGE(EDITOR *ed)
 	{
+		editor = editor;
 		tex_id = -1;
 		name[0] = 0;
 		external = 0;
@@ -232,10 +242,7 @@ public:
 		format = 0;
 	}
 	
-	~EDITOR_IMAGE()
-	{
-		gfx_unload_texture(tex_id);
-	}
+	~EDITOR_IMAGE();
 	
 	void analyse_tileflags();
 	
@@ -250,6 +257,8 @@ class MAP
 	void make_game_group(LAYERGROUP *group);
 	void make_game_layer(LAYER *layer);
 public:
+	EDITOR *editor;
+
 	MAP()
 	{
 		clean();
@@ -272,6 +281,7 @@ public:
 	LAYERGROUP *new_group()
 	{
 		LAYERGROUP *g = new LAYERGROUP;
+		g->m_pMap = this;
 		groups.add(g);
 		return g;
 	}
@@ -333,9 +343,17 @@ enum
 	PROPTYPE_ENVELOPE,
 };
 
-class EDITOR
+class EDITOR : public IEditor
 {
-public:	
+	class IGraphics *m_pGraphics;
+	CRenderTools m_RenderTools;
+	CUI m_UI;
+public:
+	
+	class IGraphics *Graphics() { return m_pGraphics; };
+	CUI *UI() { return &m_UI; }
+	CRenderTools *RenderTools() { return &m_RenderTools; }
+
 	EDITOR()
 	{
 		mode = MODE_LAYERS;
@@ -368,9 +386,12 @@ public:
 		show_envelope_editor = 0;
 	}
 	
+	virtual void Init(class IGraphics *pGraphics);
+	virtual void UpdateAndRender();
+	
 	void invoke_file_dialog(int listdir_type, const char *title, const char *button_text,
 		const char *basepath, const char *default_name,
-		void (*func)(const char *filename));
+		void (*func)(const char *filename, void *user), void *user);
 	
 	void reset(bool create_default=true);
 	int save(const char *filename);
@@ -383,7 +404,7 @@ public:
 	LAYER *get_selected_layer(int index);
 	LAYERGROUP *get_selected_group();
 	
-	int do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val);
+	int do_properties(CUIRect *toolbox, PROPERTY *props, int *ids, int *new_val);
 	
 	int mode;
 	int dialog;
@@ -420,9 +441,70 @@ public:
 	int selected_image;
 	
 	MAP map;
+	
+	int DoButton_Editor_Common(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
+	int DoButton_Editor(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
+
+	int DoButton_ButtonL(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
+	int DoButton_ButtonM(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
+	int DoButton_ButtonR(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
+	int DoButton_ButtonDec(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
+	int DoButton_ButtonInc(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
+
+	int DoButton_File(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
+	
+	int DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
+	int DoButton_MenuItem(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags=0, const char *pToolTip=0);
+	
+	int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden=false);
+	//static void draw_editor_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra);
+	//static void draw_editor_button_menuitem(const void *id, const char *text, int checked, const CUIRect *r, const void *extra);
+
+	void render_background(CUIRect view, int texture, float size, float brightness);
+
+	void ui_invoke_popup_menu(void *id, int flags, float x, float y, float w, float h, int (*func)(EDITOR *pEditor, CUIRect rect), void *extra=0);
+	void ui_do_popup_menu();
+	
+	int ui_do_value_selector(void *id, CUIRect *r, const char *label, int current, int min, int max, float scale);
+
+	static int popup_group(EDITOR *pEditor, CUIRect view);
+	static int popup_layer(EDITOR *pEditor, CUIRect view);
+	static int popup_quad(EDITOR *pEditor, CUIRect view);
+	static int popup_point(EDITOR *pEditor, CUIRect view);
+	static int popup_select_image(EDITOR *pEditor, CUIRect view);
+	static int popup_image(EDITOR *pEditor, CUIRect view);
+	static int popup_menu_file(EDITOR *pEditor, CUIRect view);
+
+
+	void popup_select_image_invoke(int current, float x, float y);
+	int popup_select_image_result();
+	
+	vec4 button_color_mul(const void *id);
+
+	void do_quad_point(QUAD *q, int quad_index, int v);
+	void do_map_editor(CUIRect view, CUIRect toolbar);
+	void do_toolbar(CUIRect toolbar);
+	void do_quad(QUAD *q, int index);
+	float ui_do_scrollbar_v(const void *id, const CUIRect *rect, float current);
+	vec4 get_button_color(const void *id, int checked);
+	
+	static void replace_image(const char *filename, void *user);
+	static void add_image(const char *filename, void *user);
+	
+	void render_images(CUIRect toolbox, CUIRect toolbar, CUIRect view);
+	void render_layers(CUIRect toolbox, CUIRect toolbar, CUIRect view);
+	void render_modebar(CUIRect view);
+	void render_statusbar(CUIRect view);
+	void render_envelopeeditor(CUIRect view);
+	
+	void render_menubar(CUIRect menubar);
+	void render_file_dialog();
 };
 
-extern EDITOR editor;
+// make sure to inline this function
+inline class IGraphics *LAYER::Graphics() { return editor->Graphics(); }
+
+//extern EDITOR editor;
 
 typedef struct
 {
@@ -443,17 +525,17 @@ public:
 
 	int convert_x(float x) const;
 	int convert_y(float y) const;
-	void convert(RECT rect, RECTi *out);
-	void snap(RECT *rect);
+	void convert(CUIRect rect, RECTi *out);
+	void snap(CUIRect *rect);
 	void clamp(RECTi *rect);
 
-	virtual void brush_selecting(RECT rect);
-	virtual int brush_grab(LAYERGROUP *brush, RECT rect);
+	virtual void brush_selecting(CUIRect rect);
+	virtual int brush_grab(LAYERGROUP *brush, CUIRect rect);
 	virtual void brush_draw(LAYER *brush, float wx, float wy);
 	virtual void brush_flip_x();
 	virtual void brush_flip_y();
 	
-	virtual int render_properties(RECT *toolbox);
+	virtual int render_properties(CUIRect *toolbox);
 
 	virtual void modify_image_index(INDEX_MODIFY_FUNC func);
 	virtual void modify_envelope_index(INDEX_MODIFY_FUNC func);
@@ -479,14 +561,14 @@ public:
 	virtual void render();
 	QUAD *new_quad();
 
-	virtual void brush_selecting(RECT rect);
-	virtual int brush_grab(LAYERGROUP *brush, RECT rect);
+	virtual void brush_selecting(CUIRect rect);
+	virtual int brush_grab(LAYERGROUP *brush, CUIRect rect);
 	virtual void brush_place(LAYER *brush, float wx, float wy);
 	virtual void brush_flip_x();
 	virtual void brush_flip_y();
 	virtual void brush_rotate(float amount);
 	
-	virtual int render_properties(RECT *toolbox);
+	virtual int render_properties(CUIRect *toolbox);
 
 	virtual void modify_image_index(INDEX_MODIFY_FUNC func);
 	virtual void modify_envelope_index(INDEX_MODIFY_FUNC func);
@@ -503,20 +585,5 @@ public:
 	LAYER_GAME(int w, int h);
 	~LAYER_GAME();
 
-	virtual int render_properties(RECT *toolbox);
+	virtual int render_properties(CUIRect *toolbox);
 };
-
-int do_editor_button(const void *id, const char *text, int checked, const RECT *r, ui_draw_button_func draw_func, int flags, const char *tooltip);
-void draw_editor_button(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-void draw_editor_button_menuitem(const void *id, const char *text, int checked, const RECT *r, const void *extra);
-
-void ui_invoke_popup_menu(void *id, int flags, float x, float y, float w, float h, int (*func)(RECT rect), void *extra=0);
-void ui_do_popup_menu();
-
-int popup_group(RECT view);
-int popup_layer(RECT view);
-int popup_quad(RECT view);
-int popup_point(RECT view);
-
-void popup_select_image_invoke(int current, float x, float y);
-int popup_select_image_result();
diff --git a/src/game/editor/ed_io.cpp b/src/game/editor/ed_io.cpp
index dfaa0e2c..b8c025fb 100644
--- a/src/game/editor/ed_io.cpp
+++ b/src/game/editor/ed_io.cpp
@@ -1,5 +1,6 @@
 #include <string.h>
 #include <stdio.h>
+#include <engine/client/graphics.h>
 #include "ed_editor.hpp"
 
 template<typename T>
@@ -7,6 +8,7 @@ static int make_version(int i, const T &v)
 { return (i<<16)+sizeof(T); }
 
 // backwards compatiblity
+/*
 void editor_load_old(DATAFILE *df, MAP *map)
 {
 	class mapres_image
@@ -98,7 +100,7 @@ void editor_load_old(DATAFILE *df, MAP *map)
 				// move game layer to correct position
 				for(int i = 0; i < map->groups[0]->layers.len()-1; i++)
 				{
-					if(map->groups[0]->layers[i] == editor.map.game_layer)
+					if(map->groups[0]->layers[i] == pEditor->map.game_layer)
 						map->groups[0]->swap_layers(i, i+1);
 				}
 				
@@ -141,7 +143,7 @@ void editor_load_old(DATAFILE *df, MAP *map)
 			// 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, 0);
+			img->tex_id = Graphics()->LoadTextureRaw(img->width, img->height, img->format, img->data, IMG_AUTO, 0);
 			map->images.add(img);
 			
 			// unload image
@@ -186,7 +188,7 @@ void editor_load_old(DATAFILE *df, MAP *map)
 			}
 		}
 	}
-}
+}*/
 
 int EDITOR::save(const char *filename)
 {
@@ -374,9 +376,10 @@ int MAP::load(const char *filename)
 	if(!item)
 	{
 		// import old map
-		MAP old_mapstuff;
-		editor.reset();
+		/*MAP old_mapstuff;
+		editor->reset();
 		editor_load_old(df, this);
+		*/
 	}
 	else if(item->version == 1)
 	{
@@ -392,7 +395,7 @@ int MAP::load(const char *filename)
 				char *name = (char *)datafile_get_data(df, item->image_name);
 
 				// copy base info				
-				EDITOR_IMAGE *img = new EDITOR_IMAGE;
+				EDITOR_IMAGE *img = new EDITOR_IMAGE(editor);
 				img->external = item->external;
 
 				if(item->external)
@@ -401,11 +404,11 @@ int MAP::load(const char *filename)
 					sprintf(buf, "mapres/%s.png", name);
 					
 					// load external
-					EDITOR_IMAGE imginfo;
-					if(gfx_load_png(&imginfo, buf))
+					EDITOR_IMAGE imginfo(editor);
+					if(editor->Graphics()->LoadPNG(&imginfo, buf))
 					{
 						*img = imginfo;
-						img->tex_id = gfx_load_texture_raw(imginfo.width, imginfo.height, imginfo.format, imginfo.data, IMG_AUTO, 0);
+						img->tex_id = editor->Graphics()->LoadTextureRaw(imginfo.width, imginfo.height, imginfo.format, imginfo.data, IMG_AUTO, 0);
 						img->external = 1;
 					}
 				}
@@ -419,7 +422,7 @@ int MAP::load(const char *filename)
 					void *data = datafile_get_data(df, item->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, 0);
+					img->tex_id = editor->Graphics()->LoadTextureRaw(img->width, img->height, img->format, img->data, IMG_AUTO, 0);
 				}
 
 				// copy image name
diff --git a/src/game/editor/ed_layer_game.cpp b/src/game/editor/ed_layer_game.cpp
index 60825ec3..9010bc71 100644
--- a/src/game/editor/ed_layer_game.cpp
+++ b/src/game/editor/ed_layer_game.cpp
@@ -12,7 +12,7 @@ LAYER_GAME::~LAYER_GAME()
 {
 }
 
-int LAYER_GAME::render_properties(RECT *toolbox)
+int LAYER_GAME::render_properties(CUIRect *toolbox)
 {
 	int r = LAYER_TILES::render_properties(toolbox);
 	image = -1;
diff --git a/src/game/editor/ed_layer_quads.cpp b/src/game/editor/ed_layer_quads.cpp
index bbe5fb6d..ce1ba4b6 100644
--- a/src/game/editor/ed_layer_quads.cpp
+++ b/src/game/editor/ed_layer_quads.cpp
@@ -1,5 +1,7 @@
 #include <base/math.hpp>
 
+#include <engine/client/graphics.h>
+
 #include "ed_editor.hpp"
 #include <game/generated/gc_data.hpp>
 #include <game/client/render.hpp>
@@ -15,9 +17,10 @@ LAYER_QUADS::~LAYER_QUADS()
 {
 }
 
-static void envelope_eval(float time_offset, int env, float *channels)
+static void envelope_eval(float time_offset, int env, float *channels, void *user)
 {
-	if(env < 0 || env > editor.map.envelopes.len())
+	EDITOR *pEditor = (EDITOR *)user;
+	if(env < 0 || env > pEditor->map.envelopes.len())
 	{
 		channels[0] = 0;
 		channels[1] = 0;
@@ -26,19 +29,19 @@ static void envelope_eval(float time_offset, int env, float *channels)
 		return;
 	}
 		
-	ENVELOPE *e = editor.map.envelopes[env];
-	float t = editor.animate_time+time_offset;
-	t *= editor.animate_speed;
+	ENVELOPE *e = pEditor->map.envelopes[env];
+	float t = pEditor->animate_time+time_offset;
+	t *= pEditor->animate_speed;
 	e->eval(t, channels);
 }
 
 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);
+	Graphics()->TextureSet(-1);
+	if(image >= 0 && image < editor->map.images.len())
+		Graphics()->TextureSet(editor->map.images[image]->tex_id);
 		
-	render_quads(quads.getptr(), quads.len(), envelope_eval, LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT);
+	editor->RenderTools()->render_quads(quads.getptr(), quads.len(), LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT, envelope_eval, editor);
 }
 
 QUAD *LAYER_QUADS::new_quad()
@@ -89,19 +92,19 @@ QUAD *LAYER_QUADS::new_quad()
 	return q;
 }
 
-void LAYER_QUADS::brush_selecting(RECT rect)
+void LAYER_QUADS::brush_selecting(CUIRect 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();
+	Graphics()->TextureSet(-1);
+	Graphics()->LinesBegin();
+	Graphics()->LinesDraw(rect.x, rect.y, rect.x+rect.w, rect.y);
+	Graphics()->LinesDraw(rect.x+rect.w, rect.y, rect.x+rect.w, rect.y+rect.h);
+	Graphics()->LinesDraw(rect.x+rect.w, rect.y+rect.h, rect.x, rect.y+rect.h);
+	Graphics()->LinesDraw(rect.x, rect.y+rect.h, rect.x, rect.y);
+	Graphics()->LinesEnd();
 }
 
-int LAYER_QUADS::brush_grab(LAYERGROUP *brush, RECT rect)
+int LAYER_QUADS::brush_grab(LAYERGROUP *brush, CUIRect rect)
 {
 	// create new layers
 	LAYER_QUADS *grabbed = new LAYER_QUADS();
@@ -204,7 +207,7 @@ void LAYER_QUADS::get_size(float *w, float *h)
 
 extern int selected_points;
 
-int LAYER_QUADS::render_properties(RECT *toolbox)
+int LAYER_QUADS::render_properties(CUIRect *toolbox)
 {
 	// layer props
 	enum
@@ -220,12 +223,12 @@ int LAYER_QUADS::render_properties(RECT *toolbox)
 	
 	static int ids[NUM_PROPS] = {0};
 	int new_val = 0;
-	int prop = editor.do_properties(toolbox, props, ids, &new_val);		
+	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();
+			image = new_val%editor->map.images.len();
 		else
 			image = -1;
 	}
diff --git a/src/game/editor/ed_layer_tiles.cpp b/src/game/editor/ed_layer_tiles.cpp
index 80ccaa3a..0d42cb78 100644
--- a/src/game/editor/ed_layer_tiles.cpp
+++ b/src/game/editor/ed_layer_tiles.cpp
@@ -1,5 +1,7 @@
 #include <base/math.hpp>
 
+#include <engine/client/graphics.h>
+
 #include <game/generated/gc_data.hpp>
 #include <game/client/render.hpp>
 #include "ed_editor.hpp"
@@ -33,7 +35,7 @@ void LAYER_TILES::prepare_for_save()
 	{
 		for(int y = 0; y < height; y++)
 			for(int x = 0; x < width; x++)
-				tiles[y*width+x].flags |= editor.map.images[image]->tileflags[tiles[y*width+x].index];
+				tiles[y*width+x].flags |= editor->map.images[image]->tileflags[tiles[y*width+x].index];
 	}
 }
 
@@ -46,16 +48,16 @@ void LAYER_TILES::make_palette()
 
 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, vec4(1,1,1,1), LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT);
+	if(image >= 0 && image < editor->map.images.len())
+		tex_id = editor->map.images[image]->tex_id;
+	Graphics()->TextureSet(tex_id);
+	editor->RenderTools()->render_tilemap(tiles, width, height, 32.0f, vec4(1,1,1,1), LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT);
 }
 
 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)
+void LAYER_TILES::convert(CUIRect rect, RECTi *out)
 {
 	out->x = convert_x(rect.x);
 	out->y = convert_y(rect.y);
@@ -63,7 +65,7 @@ void LAYER_TILES::convert(RECT rect, RECTi *out)
 	out->h = convert_y(rect.y+rect.h+31) - out->y;
 }
 
-void LAYER_TILES::snap(RECT *rect)
+void LAYER_TILES::snap(CUIRect *rect)
 {
 	RECTi out;
 	convert(*rect, &out);
@@ -99,20 +101,20 @@ void LAYER_TILES::clamp(RECTi *rect)
 		rect->w = 0;
 }
 
-void LAYER_TILES::brush_selecting(RECT rect)
+void LAYER_TILES::brush_selecting(CUIRect rect)
 {
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(1,1,1,0.4f);
+	Graphics()->TextureSet(-1);
+	editor->Graphics()->QuadsBegin();
+	editor->Graphics()->SetColor(1,1,1,0.4f);
 	snap(&rect);
-	gfx_quads_drawTL(rect.x, rect.y, rect.w, rect.h);
-	gfx_quads_end();
+	editor->Graphics()->QuadsDrawTL(rect.x, rect.y, rect.w, rect.h);
+	editor->Graphics()->QuadsEnd();
 	char buf[16];
 	str_format(buf, sizeof(buf), "%d,%d", convert_x(rect.w), convert_y(rect.h));
-	gfx_text(0, rect.x+3.0f, rect.y+3.0f, 15.0f*editor.world_zoom, buf, -1);
+	gfx_text(0, rect.x+3.0f, rect.y+3.0f, 15.0f*editor->world_zoom, buf, -1);
 }
 
-int LAYER_TILES::brush_grab(LAYERGROUP *brush, RECT rect)
+int LAYER_TILES::brush_grab(LAYERGROUP *brush, CUIRect rect)
 {
 	RECTi r;
 	convert(rect, &r);
@@ -204,17 +206,17 @@ void LAYER_TILES::resize(int new_w, int new_h)
 }
 
 
-int LAYER_TILES::render_properties(RECT *toolbox)
+int LAYER_TILES::render_properties(CUIRect *toolbox)
 {
-	RECT button;
-	ui_hsplit_b(toolbox, 12.0f, toolbox, &button);
-	bool in_gamegroup = editor.map.game_group->layers.find(this) != -1;
-	if(editor.map.game_layer == this)
+	CUIRect button;
+	toolbox->HSplitBottom(12.0f, toolbox, &button);
+	bool in_gamegroup = editor->map.game_group->layers.find(this) != -1;
+	if(editor->map.game_layer == this)
 		in_gamegroup = false;
 	static int colcl_button = 0;
-	if(do_editor_button(&colcl_button, "Clear Collision", in_gamegroup?0:-1, &button, draw_editor_button, 0, "Removes collision from this layer"))
+	if(editor->DoButton_Editor(&colcl_button, "Clear Collision", in_gamegroup?0:-1, &button, 0, "Removes collision from this layer"))
 	{
-		LAYER_TILES *gl = editor.map.game_layer;
+		LAYER_TILES *gl = editor->map.game_layer;
 		int w = min(gl->width, width);
 		int h = min(gl->height, height);
 		for(int y = 0; y < h; y++)
@@ -228,11 +230,11 @@ int LAYER_TILES::render_properties(RECT *toolbox)
 		return 1;
 	}
 	static int col_button = 0;
-	ui_hsplit_b(toolbox, 5.0f, toolbox, &button);
-	ui_hsplit_b(toolbox, 12.0f, toolbox, &button);
-	if(do_editor_button(&col_button, "Make Collision", in_gamegroup?0:-1, &button, draw_editor_button, 0, "Constructs collision from this layer"))
+	toolbox->HSplitBottom(5.0f, toolbox, &button);
+	toolbox->HSplitBottom(12.0f, toolbox, &button);
+	if(editor->DoButton_Editor(&col_button, "Make Collision", in_gamegroup?0:-1, &button, 0, "Constructs collision from this layer"))
 	{
-		LAYER_TILES *gl = editor.map.game_layer;
+		LAYER_TILES *gl = editor->map.game_layer;
 		int w = min(gl->width, width);
 		int h = min(gl->height, height);
 		for(int y = 0; y < h; y++)
@@ -260,12 +262,12 @@ int LAYER_TILES::render_properties(RECT *toolbox)
 		{0},
 	};
 	
-	if(editor.map.game_layer == this) // remove the image from the selection if this is the game layer
+	if(editor->map.game_layer == this) // remove the image from the selection if this is the game layer
 		props[2].name = 0;
 	
 	static int ids[NUM_PROPS] = {0};
 	int new_val = 0;
-	int prop = editor.do_properties(toolbox, props, ids, &new_val);		
+	int prop = editor->do_properties(toolbox, props, ids, &new_val);		
 	
 	if(prop == PROP_WIDTH && new_val > 1)
 		resize(new_val, height);
@@ -279,7 +281,7 @@ int LAYER_TILES::render_properties(RECT *toolbox)
 			image = -1;
 		}
 		else
-			image = new_val%editor.map.images.len();
+			image = new_val%editor->map.images.len();
 	}
 	
 	return 0;
diff --git a/src/game/editor/ed_popups.cpp b/src/game/editor/ed_popups.cpp
index 13bfe243..59140153 100644
--- a/src/game/editor/ed_popups.cpp
+++ b/src/game/editor/ed_popups.cpp
@@ -1,20 +1,21 @@
 #include <stdio.h>
+#include <engine/client/graphics.h>
 #include "ed_editor.hpp"
 
 
 // popup menu handling
 static struct
 {
-	RECT rect;
+	CUIRect rect;
 	void *id;
-	int (*func)(RECT rect);
+	int (*func)(EDITOR *pEditor, CUIRect rect);
 	int is_menu;
 	void *extra;
 } ui_popups[8];
 
 static int ui_num_popups = 0;
 
-void ui_invoke_popup_menu(void *id, int flags, float x, float y, float w, float h, int (*func)(RECT rect), void *extra)
+void EDITOR::ui_invoke_popup_menu(void *id, int flags, float x, float y, float w, float h, int (*func)(EDITOR *pEditor, CUIRect rect), void *extra)
 {
 	dbg_msg("", "invoked");
 	ui_popups[ui_num_popups].id = id;
@@ -28,39 +29,39 @@ void ui_invoke_popup_menu(void *id, int flags, float x, float y, float w, float
 	ui_num_popups++;
 }
 
-void ui_do_popup_menu()
+void EDITOR::ui_do_popup_menu()
 {
 	for(int i = 0; i < ui_num_popups; i++)
 	{
-		bool inside = ui_mouse_inside(&ui_popups[i].rect);
-		ui_set_hot_item(&ui_popups[i].id);
+		bool inside = UI()->MouseInside(&ui_popups[i].rect);
+		UI()->SetHotItem(&ui_popups[i].id);
 		
-		if(ui_active_item() == &ui_popups[i].id)
+		if(UI()->ActiveItem() == &ui_popups[i].id)
 		{
-			if(!ui_mouse_button(0))
+			if(!UI()->MouseButton(0))
 			{
 				if(!inside)
 					ui_num_popups--;
-				ui_set_active_item(0);
+				UI()->SetActiveItem(0);
 			}
 		}
-		else if(ui_hot_item() == &ui_popups[i].id)
+		else if(UI()->HotItem() == &ui_popups[i].id)
 		{
-			if(ui_mouse_button(0))
-				ui_set_active_item(&ui_popups[i].id);
+			if(UI()->MouseButton(0))
+				UI()->SetActiveItem(&ui_popups[i].id);
 		}
 		
-		int corners = CORNER_ALL;
+		int corners = CUI::CORNER_ALL;
 		if(ui_popups[i].is_menu)
-			corners = CORNER_R|CORNER_B;
+			corners = CUI::CORNER_R|CUI::CORNER_B;
 		
-		RECT r = ui_popups[i].rect;
-		ui_draw_rect(&r, vec4(0.5f,0.5f,0.5f,0.75f), corners, 3.0f);
-		ui_margin(&r, 1.0f, &r);
-		ui_draw_rect(&r, vec4(0,0,0,0.75f), corners, 3.0f);
-		ui_margin(&r, 4.0f, &r);
+		CUIRect r = ui_popups[i].rect;
+		RenderTools()->DrawUIRect(&r, vec4(0.5f,0.5f,0.5f,0.75f), corners, 3.0f);
+		r.Margin(1.0f, &r);
+		RenderTools()->DrawUIRect(&r, vec4(0,0,0,0.75f), corners, 3.0f);
+		r.Margin(4.0f, &r);
 		
-		if(ui_popups[i].func(r))
+		if(ui_popups[i].func(this, r))
 			ui_num_popups--;
 			
 		if(inp_key_down(KEY_ESCAPE))
@@ -69,42 +70,42 @@ void ui_do_popup_menu()
 }
 
 
-int popup_group(RECT view)
+int EDITOR::popup_group(EDITOR *pEditor, CUIRect view)
 {
 	// remove group button
-	RECT button;
-	ui_hsplit_b(&view, 12.0f, &view, &button);
+	CUIRect button;
+	view.HSplitBottom(12.0f, &view, &button);
 	static int delete_button = 0;
 	
 	// don't allow deletion of game group
-	if(editor.map.game_group != editor.get_selected_group() &&
-		do_editor_button(&delete_button, "Delete Group", 0, &button, draw_editor_button, 0, "Delete group"))
+	if(pEditor->map.game_group != pEditor->get_selected_group() &&
+		pEditor->DoButton_Editor(&delete_button, "Delete Group", 0, &button, 0, "Delete group"))
 	{
-		editor.map.delete_group(editor.selected_group);
+		pEditor->map.delete_group(pEditor->selected_group);
 		return 1;
 	}
 
 	// new tile layer
-	ui_hsplit_b(&view, 10.0f, &view, &button);
-	ui_hsplit_b(&view, 12.0f, &view, &button);
+	view.HSplitBottom(10.0f, &view, &button);
+	view.HSplitBottom(12.0f, &view, &button);
 	static int new_quad_layer_button = 0;
-	if(do_editor_button(&new_quad_layer_button, "Add Quads Layer", 0, &button, draw_editor_button, 0, "Creates a new quad layer"))
+	if(pEditor->DoButton_Editor(&new_quad_layer_button, "Add Quads Layer", 0, &button, 0, "Creates a new quad layer"))
 	{
 		LAYER *l = new LAYER_QUADS;
-		editor.map.groups[editor.selected_group]->add_layer(l);
-		editor.selected_layer = editor.map.groups[editor.selected_group]->layers.len()-1;
+		pEditor->map.groups[pEditor->selected_group]->add_layer(l);
+		pEditor->selected_layer = pEditor->map.groups[pEditor->selected_group]->layers.len()-1;
 		return 1;
 	}
 
 	// new quad layer
-	ui_hsplit_b(&view, 5.0f, &view, &button);
-	ui_hsplit_b(&view, 12.0f, &view, &button);
+	view.HSplitBottom(5.0f, &view, &button);
+	view.HSplitBottom(12.0f, &view, &button);
 	static int new_tile_layer_button = 0;
-	if(do_editor_button(&new_tile_layer_button, "Add Tile Layer", 0, &button, draw_editor_button, 0, "Creates a new tile layer"))
+	if(pEditor->DoButton_Editor(&new_tile_layer_button, "Add Tile Layer", 0, &button, 0, "Creates a new tile layer"))
 	{
 		LAYER *l = new LAYER_TILES(50, 50);
-		editor.map.groups[editor.selected_group]->add_layer(l);
-		editor.selected_layer = editor.map.groups[editor.selected_group]->layers.len()-1;
+		pEditor->map.groups[pEditor->selected_group]->add_layer(l);
+		pEditor->selected_layer = pEditor->map.groups[pEditor->selected_group]->layers.len()-1;
 		return 1;
 	}
 	
@@ -124,17 +125,17 @@ int popup_group(RECT view)
 	};
 	
 	PROPERTY props[] = {
-		{"Order", editor.selected_group, PROPTYPE_INT_STEP, 0, editor.map.groups.len()-1},
-		{"Pos X", -editor.map.groups[editor.selected_group]->offset_x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-		{"Pos Y", -editor.map.groups[editor.selected_group]->offset_y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-		{"Para X", editor.map.groups[editor.selected_group]->parallax_x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-		{"Para Y", editor.map.groups[editor.selected_group]->parallax_y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
+		{"Order", pEditor->selected_group, PROPTYPE_INT_STEP, 0, pEditor->map.groups.len()-1},
+		{"Pos X", -pEditor->map.groups[pEditor->selected_group]->offset_x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
+		{"Pos Y", -pEditor->map.groups[pEditor->selected_group]->offset_y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
+		{"Para X", pEditor->map.groups[pEditor->selected_group]->parallax_x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
+		{"Para Y", pEditor->map.groups[pEditor->selected_group]->parallax_y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
 
-		{"Use Clipping", editor.map.groups[editor.selected_group]->use_clipping, PROPTYPE_BOOL, 0, 1},
-		{"Clip X", editor.map.groups[editor.selected_group]->clip_x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-		{"Clip Y", editor.map.groups[editor.selected_group]->clip_y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-		{"Clip W", editor.map.groups[editor.selected_group]->clip_w, PROPTYPE_INT_SCROLL, -1000000, 1000000},
-		{"Clip H", editor.map.groups[editor.selected_group]->clip_h, PROPTYPE_INT_SCROLL, -1000000, 1000000},
+		{"Use Clipping", pEditor->map.groups[pEditor->selected_group]->use_clipping, PROPTYPE_BOOL, 0, 1},
+		{"Clip X", pEditor->map.groups[pEditor->selected_group]->clip_x, PROPTYPE_INT_SCROLL, -1000000, 1000000},
+		{"Clip Y", pEditor->map.groups[pEditor->selected_group]->clip_y, PROPTYPE_INT_SCROLL, -1000000, 1000000},
+		{"Clip W", pEditor->map.groups[pEditor->selected_group]->clip_w, PROPTYPE_INT_SCROLL, -1000000, 1000000},
+		{"Clip H", pEditor->map.groups[pEditor->selected_group]->clip_h, PROPTYPE_INT_SCROLL, -1000000, 1000000},
 		{0},
 	};
 	
@@ -142,49 +143,49 @@ int popup_group(RECT view)
 	int new_val = 0;
 	
 	// cut the properties that isn't needed
-	if(editor.get_selected_group()->game_group)
+	if(pEditor->get_selected_group()->game_group)
 		props[PROP_POS_X].name = 0;
 		
-	int prop = editor.do_properties(&view, props, ids, &new_val);
+	int prop = pEditor->do_properties(&view, props, ids, &new_val);
 	if(prop == PROP_ORDER)
-		editor.selected_group = editor.map.swap_groups(editor.selected_group, new_val);
+		pEditor->selected_group = pEditor->map.swap_groups(pEditor->selected_group, new_val);
 		
 	// these can not be changed on the game group
-	if(!editor.get_selected_group()->game_group)
+	if(!pEditor->get_selected_group()->game_group)
 	{
-		if(prop == PROP_PARA_X) editor.map.groups[editor.selected_group]->parallax_x = new_val;
-		else if(prop == PROP_PARA_Y) editor.map.groups[editor.selected_group]->parallax_y = new_val;
-		else if(prop == PROP_POS_X) editor.map.groups[editor.selected_group]->offset_x = -new_val;
-		else if(prop == PROP_POS_Y) editor.map.groups[editor.selected_group]->offset_y = -new_val;
-		else if(prop == PROP_USE_CLIPPING) editor.map.groups[editor.selected_group]->use_clipping = new_val;
-		else if(prop == PROP_CLIP_X) editor.map.groups[editor.selected_group]->clip_x = new_val;
-		else if(prop == PROP_CLIP_Y) editor.map.groups[editor.selected_group]->clip_y = new_val;
-		else if(prop == PROP_CLIP_W) editor.map.groups[editor.selected_group]->clip_w = new_val;
-		else if(prop == PROP_CLIP_H) editor.map.groups[editor.selected_group]->clip_h = new_val;
+		if(prop == PROP_PARA_X) pEditor->map.groups[pEditor->selected_group]->parallax_x = new_val;
+		else if(prop == PROP_PARA_Y) pEditor->map.groups[pEditor->selected_group]->parallax_y = new_val;
+		else if(prop == PROP_POS_X) pEditor->map.groups[pEditor->selected_group]->offset_x = -new_val;
+		else if(prop == PROP_POS_Y) pEditor->map.groups[pEditor->selected_group]->offset_y = -new_val;
+		else if(prop == PROP_USE_CLIPPING) pEditor->map.groups[pEditor->selected_group]->use_clipping = new_val;
+		else if(prop == PROP_CLIP_X) pEditor->map.groups[pEditor->selected_group]->clip_x = new_val;
+		else if(prop == PROP_CLIP_Y) pEditor->map.groups[pEditor->selected_group]->clip_y = new_val;
+		else if(prop == PROP_CLIP_W) pEditor->map.groups[pEditor->selected_group]->clip_w = new_val;
+		else if(prop == PROP_CLIP_H) pEditor->map.groups[pEditor->selected_group]->clip_h = new_val;
 	}
 	
 	return 0;
 }
 
-int popup_layer(RECT view)
+int EDITOR::popup_layer(EDITOR *pEditor, CUIRect view)
 {
 	// remove layer button
-	RECT button;
-	ui_hsplit_b(&view, 12.0f, &view, &button);
+	CUIRect button;
+	view.HSplitBottom(12.0f, &view, &button);
 	static int delete_button = 0;
 	
 	// don't allow deletion of game layer
-	if(editor.map.game_layer != editor.get_selected_layer(0) &&
-		do_editor_button(&delete_button, "Delete Layer", 0, &button, draw_editor_button, 0, "Deletes the layer"))
+	if(pEditor->map.game_layer != pEditor->get_selected_layer(0) &&
+		pEditor->DoButton_Editor(&delete_button, "Delete Layer", 0, &button, 0, "Deletes the layer"))
 	{
-		editor.map.groups[editor.selected_group]->delete_layer(editor.selected_layer);
+		pEditor->map.groups[pEditor->selected_group]->delete_layer(pEditor->selected_layer);
 		return 1;
 	}
 
-	ui_hsplit_b(&view, 10.0f, &view, 0);
+	view.HSplitBottom(10.0f, &view, 0);
 	
-	LAYERGROUP *current_group = editor.map.groups[editor.selected_group];
-	LAYER *current_layer = editor.get_selected_layer(0);
+	LAYERGROUP *current_group = pEditor->map.groups[pEditor->selected_group];
+	LAYER *current_layer = pEditor->get_selected_layer(0);
 	
 	enum
 	{
@@ -195,26 +196,26 @@ int popup_layer(RECT view)
 	};
 	
 	PROPERTY props[] = {
-		{"Group", editor.selected_group, PROPTYPE_INT_STEP, 0, editor.map.groups.len()-1},
-		{"Order", editor.selected_layer, PROPTYPE_INT_STEP, 0, current_group->layers.len()},
+		{"Group", pEditor->selected_group, PROPTYPE_INT_STEP, 0, pEditor->map.groups.len()-1},
+		{"Order", pEditor->selected_layer, PROPTYPE_INT_STEP, 0, current_group->layers.len()},
 		{"Detail", current_layer->flags&LAYERFLAG_DETAIL, PROPTYPE_BOOL, 0, 1},
 		{0},
 	};
 	
 	static int ids[NUM_PROPS] = {0};
 	int new_val = 0;
-	int prop = editor.do_properties(&view, props, ids, &new_val);		
+	int prop = pEditor->do_properties(&view, props, ids, &new_val);		
 	
 	if(prop == PROP_ORDER)
-		editor.selected_layer = current_group->swap_layers(editor.selected_layer, new_val);
+		pEditor->selected_layer = current_group->swap_layers(pEditor->selected_layer, new_val);
 	else if(prop == PROP_GROUP && current_layer->type != LAYERTYPE_GAME)
 	{
-		if(new_val >= 0 && new_val < editor.map.groups.len())
+		if(new_val >= 0 && new_val < pEditor->map.groups.len())
 		{
 			current_group->layers.remove(current_layer);
-			editor.map.groups[new_val]->layers.add(current_layer);
-			editor.selected_group = new_val;
-			editor.selected_layer = editor.map.groups[new_val]->layers.len()-1;
+			pEditor->map.groups[new_val]->layers.add(current_layer);
+			pEditor->selected_group = new_val;
+			pEditor->selected_layer = pEditor->map.groups[new_val]->layers.len()-1;
 		}
 	}
 	else if(prop == PROP_HQ)
@@ -227,31 +228,31 @@ int popup_layer(RECT view)
 	return current_layer->render_properties(&view);
 }
 
-int popup_quad(RECT view)
+int EDITOR::popup_quad(EDITOR *pEditor, CUIRect view)
 {
-	QUAD *quad = editor.get_selected_quad();
+	QUAD *quad = pEditor->get_selected_quad();
 
-	RECT button;
+	CUIRect button;
 	
 	// delete button
-	ui_hsplit_b(&view, 12.0f, &view, &button);
+	view.HSplitBottom(12.0f, &view, &button);
 	static int delete_button = 0;
-	if(do_editor_button(&delete_button, "Delete", 0, &button, draw_editor_button, 0, "Deletes the current quad"))
+	if(pEditor->DoButton_Editor(&delete_button, "Delete", 0, &button, 0, "Deletes the current quad"))
 	{
-		LAYER_QUADS *layer = (LAYER_QUADS *)editor.get_selected_layer_type(0, LAYERTYPE_QUADS);
+		LAYER_QUADS *layer = (LAYER_QUADS *)pEditor->get_selected_layer_type(0, LAYERTYPE_QUADS);
 		if(layer)
 		{
-			layer->quads.removebyindex(editor.selected_quad);
-			editor.selected_quad--;
+			layer->quads.removebyindex(pEditor->selected_quad);
+			pEditor->selected_quad--;
 		}
 		return 1;
 	}
 
 	// square button
-	ui_hsplit_b(&view, 10.0f, &view, &button);
-	ui_hsplit_b(&view, 12.0f, &view, &button);
+	view.HSplitBottom(10.0f, &view, &button);
+	view.HSplitBottom(12.0f, &view, &button);
 	static int sq_button = 0;
-	if(do_editor_button(&sq_button, "Square", 0, &button, draw_editor_button, 0, "Squares the current quad"))
+	if(pEditor->DoButton_Editor(&sq_button, "Square", 0, &button, 0, "Squares the current quad"))
 	{
 		int top = quad->points[0].y;
 		int left = quad->points[0].x;
@@ -284,9 +285,9 @@ int popup_quad(RECT view)
 	};
 	
 	PROPERTY props[] = {
-		{"Pos. Env", quad->pos_env, PROPTYPE_INT_STEP, -1, editor.map.envelopes.len()},
+		{"Pos. Env", quad->pos_env, PROPTYPE_INT_STEP, -1, pEditor->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 Env", quad->color_env, PROPTYPE_INT_STEP, -1, pEditor->map.envelopes.len()},
 		{"Color TO", quad->color_env_offset, PROPTYPE_INT_SCROLL, -1000000, 1000000},
 		
 		{0},
@@ -294,19 +295,19 @@ int popup_quad(RECT view)
 	
 	static int ids[NUM_PROPS] = {0};
 	int new_val = 0;
-	int prop = editor.do_properties(&view, props, ids, &new_val);		
+	int prop = pEditor->do_properties(&view, props, ids, &new_val);		
 	
-	if(prop == PROP_POS_ENV) quad->pos_env = clamp(new_val, -1, editor.map.envelopes.len()-1);
+	if(prop == PROP_POS_ENV) quad->pos_env = clamp(new_val, -1, pEditor->map.envelopes.len()-1);
 	if(prop == PROP_POS_ENV_OFFSET) quad->pos_env_offset = new_val;
-	if(prop == PROP_COLOR_ENV) quad->color_env = clamp(new_val, -1, editor.map.envelopes.len()-1);
+	if(prop == PROP_COLOR_ENV) quad->color_env = clamp(new_val, -1, pEditor->map.envelopes.len()-1);
 	if(prop == PROP_COLOR_ENV_OFFSET) quad->color_env_offset = new_val;
 	
 	return 0;
 }
 
-int popup_point(RECT view)
+int EDITOR::popup_point(EDITOR *pEditor, CUIRect view)
 {
-	QUAD *quad = editor.get_selected_quad();
+	QUAD *quad = pEditor->get_selected_quad();
 	
 	enum
 	{
@@ -318,7 +319,7 @@ int popup_point(RECT view)
 
 	for(int v = 0; v < 4; v++)
 	{
-		if(editor.selected_points&(1<<v))
+		if(pEditor->selected_points&(1<<v))
 		{
 			color = 0;
 			color |= quad->colors[v].r<<24;
@@ -330,18 +331,18 @@ int popup_point(RECT view)
 	
 	
 	PROPERTY props[] = {
-		{"Color", color, PROPTYPE_COLOR, -1, editor.map.envelopes.len()},
+		{"Color", color, PROPTYPE_COLOR, -1, pEditor->map.envelopes.len()},
 		{0},
 	};
 	
 	static int ids[NUM_PROPS] = {0};
 	int new_val = 0;
-	int prop = editor.do_properties(&view, props, ids, &new_val);		
+	int prop = pEditor->do_properties(&view, props, ids, &new_val);		
 	if(prop == PROP_COLOR)
 	{
 		for(int v = 0; v < 4; v++)
 		{
-			if(editor.selected_points&(1<<v))
+			if(pEditor->selected_points&(1<<v))
 			{
 				color = 0;
 				quad->colors[v].r = (new_val>>24)&0xff;
@@ -360,47 +361,47 @@ int popup_point(RECT view)
 static int select_image_selected = -100;
 static int select_image_current = -100;
 
-int popup_select_image(RECT view)
+int EDITOR::popup_select_image(EDITOR *pEditor, CUIRect view)
 {
-	RECT buttonbar, imageview;
-	ui_vsplit_l(&view, 80.0f, &buttonbar, &view);
-	ui_margin(&view, 10.0f, &imageview);
+	CUIRect buttonbar, imageview;
+	view.VSplitLeft(80.0f, &buttonbar, &view);
+	view.Margin(10.0f, &imageview);
 	
 	int show_image = select_image_current;
 	
-	for(int i = -1; i < editor.map.images.len(); i++)
+	for(int i = -1; i < pEditor->map.images.len(); i++)
 	{
-		RECT button;
-		ui_hsplit_t(&buttonbar, 12.0f, &button, &buttonbar);
-		ui_hsplit_t(&buttonbar, 2.0f, 0, &buttonbar);
+		CUIRect button;
+		buttonbar.HSplitTop(12.0f, &button, &buttonbar);
+		buttonbar.HSplitTop(2.0f, 0, &buttonbar);
 		
-		if(ui_mouse_inside(&button))
+		if(pEditor->UI()->MouseInside(&button))
 			show_image = i;
 			
 		if(i == -1)
 		{
-			if(do_editor_button(&editor.map.images[i], "None", i==select_image_current, &button, draw_editor_button_menuitem, 0, 0))
+			if(pEditor->DoButton_MenuItem(&pEditor->map.images[i], "None", i==select_image_current, &button))
 				select_image_selected = -1;
 		}
 		else
 		{
-			if(do_editor_button(&editor.map.images[i], editor.map.images[i]->name, i==select_image_current, &button, draw_editor_button_menuitem, 0, 0))
+			if(pEditor->DoButton_MenuItem(&pEditor->map.images[i], pEditor->map.images[i]->name, i==select_image_current, &button))
 				select_image_selected = i;
 		}
 	}
 	
-	if(show_image >= 0 && show_image < editor.map.images.len())
-		gfx_texture_set(editor.map.images[show_image]->tex_id);
+	if(show_image >= 0 && show_image < pEditor->map.images.len())
+		pEditor->Graphics()->TextureSet(pEditor->map.images[show_image]->tex_id);
 	else
-		gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_quads_drawTL(imageview.x, imageview.y, imageview.w, imageview.h);
-	gfx_quads_end();
+		pEditor->Graphics()->TextureSet(-1);
+	pEditor->Graphics()->QuadsBegin();
+	pEditor->Graphics()->QuadsDrawTL(imageview.x, imageview.y, imageview.w, imageview.h);
+	pEditor->Graphics()->QuadsEnd();
 
 	return 0;
 }
 
-void popup_select_image_invoke(int current, float x, float y)
+void EDITOR::popup_select_image_invoke(int current, float x, float y)
 {
 	static int select_image_popup_id = 0;
 	select_image_selected = -100;
@@ -408,7 +409,7 @@ void popup_select_image_invoke(int current, float x, float y)
 	ui_invoke_popup_menu(&select_image_popup_id, 0, x, y, 400, 300, popup_select_image);
 }
 
-int popup_select_image_result()
+int EDITOR::popup_select_image_result()
 {
 	if(select_image_selected == -100)
 		return -100;
diff --git a/src/game/localization.cpp b/src/game/localization.cpp
index 202e6ca0..3a1b0411 100644
--- a/src/game/localization.cpp
+++ b/src/game/localization.cpp
@@ -2,9 +2,7 @@
 #include "localization.hpp"
 #include <base/tl/algorithm.hpp>
 
-extern "C" {
 #include <engine/e_linereader.h>
-}
 
 const char *localize(const char *str)
 {
diff --git a/src/game/server/hooks.cpp b/src/game/server/hooks.cpp
index 1ae38ce2..89c95f79 100644
--- a/src/game/server/hooks.cpp
+++ b/src/game/server/hooks.cpp
@@ -7,10 +7,8 @@
 
 #include <engine/e_config.h>
 #include <engine/e_server_interface.h>
-extern "C"
-{
-	#include <engine/e_memheap.h>
-}
+#include <engine/e_memheap.h>
+
 #include <game/version.hpp>
 #include <game/collision.hpp>
 #include <game/layers.hpp>
@@ -597,5 +595,5 @@ void mods_postsnap()
 	game.events.clear();
 }
 
-extern "C" const char *mods_net_version() { return GAME_NETVERSION; }
-extern "C" const char *mods_version() { return GAME_VERSION; }
+const char *mods_net_version() { return GAME_NETVERSION; }
+const char *mods_version() { return GAME_VERSION; }