about summary refs log tree commit diff
path: root/src/game/client/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/client/components')
-rw-r--r--src/game/client/components/binds.cpp220
-rw-r--r--src/game/client/components/binds.h41
-rw-r--r--src/game/client/components/binds.hpp35
-rw-r--r--src/game/client/components/broadcast.cpp36
-rw-r--r--src/game/client/components/broadcast.h17
-rw-r--r--src/game/client/components/broadcast.hpp14
-rw-r--r--src/game/client/components/camera.cpp41
-rw-r--r--src/game/client/components/camera.h16
-rw-r--r--src/game/client/components/camera.hpp13
-rw-r--r--src/game/client/components/chat.cpp290
-rw-r--r--src/game/client/components/chat.h60
-rw-r--r--src/game/client/components/chat.hpp54
-rw-r--r--src/game/client/components/console.cpp606
-rw-r--r--src/game/client/components/console.h72
-rw-r--r--src/game/client/components/console.hpp68
-rw-r--r--src/game/client/components/controls.cpp251
-rw-r--r--src/game/client/components/controls.h25
-rw-r--r--src/game/client/components/controls.hpp22
-rw-r--r--src/game/client/components/damageind.cpp69
-rw-r--r--src/game/client/components/damageind.h34
-rw-r--r--src/game/client/components/damageind.hpp31
-rw-r--r--src/game/client/components/debughud.cpp105
-rw-r--r--src/game/client/components/debughud.h13
-rw-r--r--src/game/client/components/debughud.hpp10
-rw-r--r--src/game/client/components/effects.cpp340
-rw-r--r--src/game/client/components/effects.h27
-rw-r--r--src/game/client/components/effects.hpp24
-rw-r--r--src/game/client/components/emoticon.cpp178
-rw-r--r--src/game/client/components/emoticon.h31
-rw-r--r--src/game/client/components/emoticon.hpp28
-rw-r--r--src/game/client/components/flow.cpp99
-rw-r--r--src/game/client/components/flow.h28
-rw-r--r--src/game/client/components/flow.hpp25
-rw-r--r--src/game/client/components/hud.cpp330
-rw-r--r--src/game/client/components/hud.h27
-rw-r--r--src/game/client/components/hud.hpp24
-rw-r--r--src/game/client/components/items.cpp267
-rw-r--r--src/game/client/components/items.h16
-rw-r--r--src/game/client/components/items.hpp13
-rw-r--r--src/game/client/components/killmessages.cpp120
-rw-r--r--src/game/client/components/killmessages.h31
-rw-r--r--src/game/client/components/killmessages.hpp24
-rw-r--r--src/game/client/components/mapimages.cpp51
-rw-r--r--src/game/client/components/mapimages.h18
-rw-r--r--src/game/client/components/mapimages.hpp15
-rw-r--r--src/game/client/components/maplayers.cpp187
-rw-r--r--src/game/client/components/maplayers.h24
-rw-r--r--src/game/client/components/maplayers.hpp19
-rw-r--r--src/game/client/components/menus.cpp1052
-rw-r--r--src/game/client/components/menus.h223
-rw-r--r--src/game/client/components/menus.hpp216
-rw-r--r--src/game/client/components/menus_browser.cpp920
-rw-r--r--src/game/client/components/menus_demo.cpp545
-rw-r--r--src/game/client/components/menus_ingame.cpp394
-rw-r--r--src/game/client/components/menus_settings.cpp1205
-rw-r--r--src/game/client/components/motd.cpp78
-rw-r--r--src/game/client/components/motd.h21
-rw-r--r--src/game/client/components/motd.hpp18
-rw-r--r--src/game/client/components/nameplates.cpp71
-rw-r--r--src/game/client/components/nameplates.h17
-rw-r--r--src/game/client/components/nameplates.hpp14
-rw-r--r--src/game/client/components/particles.cpp161
-rw-r--r--src/game/client/components/particles.h94
-rw-r--r--src/game/client/components/particles.hpp91
-rw-r--r--src/game/client/components/players.cpp647
-rw-r--r--src/game/client/components/players.h25
-rw-r--r--src/game/client/components/players.hpp16
-rw-r--r--src/game/client/components/scoreboard.cpp311
-rw-r--r--src/game/client/components/scoreboard.h22
-rw-r--r--src/game/client/components/scoreboard.hpp19
-rw-r--r--src/game/client/components/skins.cpp169
-rw-r--r--src/game/client/components/skins.h39
-rw-r--r--src/game/client/components/skins.hpp36
-rw-r--r--src/game/client/components/sounds.cpp93
-rw-r--r--src/game/client/components/sounds.h36
-rw-r--r--src/game/client/components/sounds.hpp22
-rw-r--r--src/game/client/components/voting.cpp257
-rw-r--r--src/game/client/components/voting.h58
-rw-r--r--src/game/client/components/voting.hpp52
79 files changed, 5752 insertions, 5259 deletions
diff --git a/src/game/client/components/binds.cpp b/src/game/client/components/binds.cpp
index e4252656..533658f2 100644
--- a/src/game/client/components/binds.cpp
+++ b/src/game/client/components/binds.cpp
@@ -1,184 +1,188 @@
-#include <stdlib.h> // atoi
-#include <string.h> // strcmp
-#include <engine/e_client_interface.h>
-#include "binds.hpp"
+#include <engine/config.h>
+#include <engine/shared/config.h>
+#include "binds.h"
 
-bool BINDS::BINDS_SPECIAL::on_input(INPUT_EVENT e)
+bool CBinds::CBindsSpecial::OnInput(IInput::CEvent Event)
 {
 	// don't handle invalid events and keys that arn't set to anything
-	if(e.key >= KEY_F1 && e.key <= KEY_F15 && binds->keybindings[e.key][0] != 0)
+	if(Event.m_Key >= KEY_F1 && Event.m_Key <= KEY_F15 && m_pBinds->m_aaKeyBindings[Event.m_Key][0] != 0)
 	{
-		int stroke = 0;
-		if(e.flags&INPFLAG_PRESS)
-			stroke = 1;
-		console_execute_line_stroked(stroke, binds->keybindings[e.key]);
+		int Stroke = 0;
+		if(Event.m_Flags&IInput::FLAG_PRESS)
+			Stroke = 1;
+			
+		m_pBinds->GetConsole()->ExecuteLineStroked(Stroke, m_pBinds->m_aaKeyBindings[Event.m_Key]);
 		return true;
 	}
 	
 	return false;
 }
 
-BINDS::BINDS()
+CBinds::CBinds()
 {
-	mem_zero(keybindings, sizeof(keybindings));
-	special_binds.binds = this;
+	mem_zero(m_aaKeyBindings, sizeof(m_aaKeyBindings));
+	m_SpecialBinds.m_pBinds = this;
 }
 
-void BINDS::bind(int keyid, const char *str)
+void CBinds::Bind(int KeyId, const char *pStr)
 {
-	if(keyid < 0 || keyid >= KEY_LAST)
+	if(KeyId < 0 || KeyId >= KEY_LAST)
 		return;
 		
-	str_copy(keybindings[keyid], str, sizeof(keybindings[keyid]));
-	if(!keybindings[keyid][0])
-		dbg_msg("binds", "unbound %s (%d)", inp_key_name(keyid), keyid);
+	str_copy(m_aaKeyBindings[KeyId], pStr, sizeof(m_aaKeyBindings[KeyId]));
+	if(!m_aaKeyBindings[KeyId][0])
+		dbg_msg("binds", "unbound %s (%d)", Input()->KeyName(KeyId), KeyId);
 	else
-		dbg_msg("binds", "bound %s (%d) = %s", inp_key_name(keyid), keyid, keybindings[keyid]);
+		dbg_msg("binds", "bound %s (%d) = %s", Input()->KeyName(KeyId), KeyId, m_aaKeyBindings[KeyId]);
 }
 
 
-bool BINDS::on_input(INPUT_EVENT e)
+bool CBinds::OnInput(IInput::CEvent e)
 {
 	// don't handle invalid events and keys that arn't set to anything
-	if(e.key <= 0 || e.key >= KEY_LAST || keybindings[e.key][0] == 0)
+	if(e.m_Key <= 0 || e.m_Key >= KEY_LAST || m_aaKeyBindings[e.m_Key][0] == 0)
 		return false;
 
-	int stroke = 0;
-	if(e.flags&INPFLAG_PRESS)
-		stroke = 1;
-	console_execute_line_stroked(stroke, keybindings[e.key]);
+	int Stroke = 0;
+	if(e.m_Flags&IInput::FLAG_PRESS)
+		Stroke = 1;
+	Console()->ExecuteLineStroked(Stroke, m_aaKeyBindings[e.m_Key]);
 	return true;
 }
 
-void BINDS::unbindall()
+void CBinds::UnbindAll()
 {
 	for(int i = 0; i < KEY_LAST; i++)
-		keybindings[i][0] = 0;
+		m_aaKeyBindings[i][0] = 0;
 }
 
-const char *BINDS::get(int keyid)
+const char *CBinds::Get(int KeyId)
 {
-	if(keyid > 0 && keyid < KEY_LAST)
-		return keybindings[keyid];
+	if(KeyId > 0 && KeyId < KEY_LAST)
+		return m_aaKeyBindings[KeyId];
 	return "";
 }
 
-const char *BINDS::get_key(const char *bindstr)
+const char *CBinds::GetKey(const char *pBindStr)
 {
-	for(int keyid = 0; keyid < KEY_LAST; keyid++)
+	for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
 	{
-		const char *bind = get(keyid);
-		if(!bind[0])
+		const char *pBind = Get(KeyId);
+		if(!pBind[0])
 			continue;
 			
-		if(strcmp(bind, bindstr) == 0)
-			return inp_key_name(keyid);
+		if(str_comp(pBind, pBindStr) == 0)
+			return Input()->KeyName(KeyId);
 	}
 	
 	return "";
 }
 
-void BINDS::set_defaults()
+void CBinds::SetDefaults()
 {
 	// set default key bindings
-	unbindall();
-	bind(KEY_F1, "toggle_local_console");
-	bind(KEY_F2, "toggle_remote_console");
-	bind(KEY_TAB, "+scoreboard");
-	bind(KEY_F10, "screenshot");
-
-	bind('a', "+left");
-	bind('d', "+right");
-
-	bind(KEY_SPACE, "+jump");
-	bind(KEY_MOUSE_1, "+fire");
-	bind(KEY_MOUSE_2, "+hook");
-	bind(KEY_LSHIFT, "+emote");
-
-	bind('1', "+weapon1");
-	bind('2', "+weapon2");
-	bind('3', "+weapon3");
-	bind('4', "+weapon4");
-	bind('5', "+weapon5");
+	UnbindAll();
+	Bind(KEY_F1, "toggle_local_console");
+	Bind(KEY_F2, "toggle_remote_console");
+	Bind(KEY_TAB, "+scoreboard");
+	Bind(KEY_F10, "screenshot");
+
+	Bind('a', "+left");
+	Bind('d', "+right");
+
+	Bind(KEY_SPACE, "+jump");
+	Bind(KEY_MOUSE_1, "+fire");
+	Bind(KEY_MOUSE_2, "+hook");
+	Bind(KEY_LSHIFT, "+emote");
+
+	Bind('1', "+weapon1");
+	Bind('2', "+weapon2");
+	Bind('3', "+weapon3");
+	Bind('4', "+weapon4");
+	Bind('5', "+weapon5");
 	
-	bind(KEY_MOUSE_WHEEL_UP, "+prevweapon");
-	bind(KEY_MOUSE_WHEEL_DOWN, "+nextweapon");
+	Bind(KEY_MOUSE_WHEEL_UP, "+prevweapon");
+	Bind(KEY_MOUSE_WHEEL_DOWN, "+nextweapon");
 	
-	bind('t', "chat all");
-	bind('y', "chat team");	
+	Bind('t', "chat all");
+	Bind('y', "chat team");	
 
-	bind(KEY_F3, "vote yes");
-	bind(KEY_F4, "vote no");	
+	Bind(KEY_F3, "vote yes");
+	Bind(KEY_F4, "vote no");	
 }
 
-void BINDS::on_console_init()
+void CBinds::OnConsoleInit()
 {
 	// bindings
-	MACRO_REGISTER_COMMAND("bind", "sr", CFGFLAG_CLIENT, con_bind, this, "Bind key to execute the command");
-	MACRO_REGISTER_COMMAND("unbind", "s", CFGFLAG_CLIENT, con_unbind, this, "Unbind key");
-	MACRO_REGISTER_COMMAND("unbindall", "", CFGFLAG_CLIENT, con_unbindall, this, "Unbind all keys");
-	MACRO_REGISTER_COMMAND("dump_binds", "", CFGFLAG_CLIENT, con_dump_binds, this, "Dump binds");
+	IConfig *pConfig = Kernel()->RequestInterface<IConfig>();
+	if(pConfig)
+		pConfig->RegisterCallback(ConfigSaveCallback, this);
+	
+	Console()->Register("bind", "sr", CFGFLAG_CLIENT, ConBind, this, "Bind key to execute the command");
+	Console()->Register("unbind", "s", CFGFLAG_CLIENT, ConUnbind, this, "Unbind key");
+	Console()->Register("unbindall", "", CFGFLAG_CLIENT, ConUnbindAll, this, "Unbind all keys");
+	Console()->Register("dump_binds", "", CFGFLAG_CLIENT, ConDumpBinds, this, "Dump binds");
 	
 	// default bindings
-	set_defaults();
+	SetDefaults();
 }
 
-void BINDS::con_bind(void *result, void *user_data)
+void CBinds::ConBind(IConsole::IResult *pResult, void *pUserData)
 {
-	BINDS *binds = (BINDS *)user_data;
-	const char *key_name = console_arg_string(result, 0);
-	int id = binds->get_key_id(key_name);
+	CBinds *pBinds = (CBinds *)pUserData;
+	const char *pKeyName = pResult->GetString(0);
+	int id = pBinds->GetKeyId(pKeyName);
 	
 	if(!id)
 	{
-		dbg_msg("binds", "key %s not found", key_name);
+		dbg_msg("binds", "key %s not found", pKeyName);
 		return;
 	}
 	
-	binds->bind(id, console_arg_string(result, 1));
+	pBinds->Bind(id, pResult->GetString(1));
 }
 
 
-void BINDS::con_unbind(void *result, void *user_data)
+void CBinds::ConUnbind(IConsole::IResult *pResult, void *pUserData)
 {
-	BINDS *binds = (BINDS *)user_data;
-	const char *key_name = console_arg_string(result, 0);
-	int id = binds->get_key_id(key_name);
+	CBinds *pBinds = (CBinds *)pUserData;
+	const char *pKeyName = pResult->GetString(0);
+	int id = pBinds->GetKeyId(pKeyName);
 	
 	if(!id)
 	{
-		dbg_msg("binds", "key %s not found", key_name);
+		dbg_msg("binds", "key %s not found", pKeyName);
 		return;
 	}
 	
-	binds->bind(id, "");
+	pBinds->Bind(id, "");
 }
 
 
-void BINDS::con_unbindall(void *result, void *user_data)
+void CBinds::ConUnbindAll(IConsole::IResult *pResult, void *pUserData)
 {
-	BINDS *binds = (BINDS *)user_data;
-	binds->unbindall();
+	CBinds *pBinds = (CBinds *)pUserData;
+	pBinds->UnbindAll();
 }
 
 
-void BINDS::con_dump_binds(void *result, void *user_data)
+void CBinds::ConDumpBinds(IConsole::IResult *pResult, void *pUserData)
 {
-	BINDS *binds = (BINDS *)user_data;
+	CBinds *pBinds = (CBinds *)pUserData;
 	for(int i = 0; i < KEY_LAST; i++)
 	{
-		if(binds->keybindings[i][0] == 0)
+		if(pBinds->m_aaKeyBindings[i][0] == 0)
 			continue;
-		dbg_msg("binds", "%s (%d) = %s", inp_key_name(i), i, binds->keybindings[i]);
+		dbg_msg("binds", "%s (%d) = %s", pBinds->Input()->KeyName(i), i, pBinds->m_aaKeyBindings[i]);
 	}
 }
 
-int BINDS::get_key_id(const char *key_name)
+int CBinds::GetKeyId(const char *pKeyName)
 {
 	// check for numeric
-	if(key_name[0] == '&')
+	if(pKeyName[0] == '&')
 	{
-		int i = atoi(key_name+1);
+		int i = str_toint(pKeyName+1);
 		if(i > 0 && i < KEY_LAST)
 			return i; // numeric
 	}
@@ -186,37 +190,39 @@ int BINDS::get_key_id(const char *key_name)
 	// search for key
 	for(int i = 0; i < KEY_LAST; i++)
 	{
-		if(strcmp(key_name, inp_key_name(i)) == 0)
+		if(str_comp(pKeyName, Input()->KeyName(i)) == 0)
 			return i;
 	}
 	
 	return 0;
 }
 
-void BINDS::on_save()
+void CBinds::ConfigSaveCallback(IConfig *pConfig, void *pUserData)
 {
-	char buffer[256];
-	char *end = buffer+sizeof(buffer)-8;
-	client_save_line("unbindall");
+	CBinds *pSelf = (CBinds *)pUserData;
+	
+	char aBuffer[256];
+	char *pEnd = aBuffer+sizeof(aBuffer)-8;
+	pConfig->WriteLine("unbindall");
 	for(int i = 0; i < KEY_LAST; i++)
 	{
-		if(keybindings[i][0] == 0)
+		if(pSelf->m_aaKeyBindings[i][0] == 0)
 			continue;
-		str_format(buffer, sizeof(buffer), "bind %s ", inp_key_name(i));
+		str_format(aBuffer, sizeof(aBuffer), "bind %s ", pSelf->Input()->KeyName(i));
 		
 		// process the string. we need to escape some characters
-		const char *src = keybindings[i];
-		char *dst = buffer + strlen(buffer);
-		*dst++ = '"';
-		while(*src && dst < end)
+		const char *pSrc = pSelf->m_aaKeyBindings[i];
+		char *pDst = aBuffer + str_length(aBuffer);
+		*pDst++ = '"';
+		while(*pSrc && pDst < pEnd)
 		{
-			if(*src == '"' || *src == '\\') // escape \ and "
-				*dst++ = '\\';
-			*dst++ = *src++;
+			if(*pSrc == '"' || *pSrc == '\\') // escape \ and "
+				*pDst++ = '\\';
+			*pDst++ = *pSrc++;
 		}
-		*dst++ = '"';
-		*dst++ = 0;
+		*pDst++ = '"';
+		*pDst++ = 0;
 		
-		client_save_line(buffer);
+		pConfig->WriteLine(aBuffer);
 	}
 }
diff --git a/src/game/client/components/binds.h b/src/game/client/components/binds.h
new file mode 100644
index 00000000..e8393979
--- /dev/null
+++ b/src/game/client/components/binds.h
@@ -0,0 +1,41 @@
+#ifndef GAME_CLIENT_COMPONENTS_BINDS_H
+#define GAME_CLIENT_COMPONENTS_BINDS_H
+#include <game/client/component.h>
+#include <engine/keys.h>
+
+class CBinds : public CComponent
+{
+	char m_aaKeyBindings[KEY_LAST][128];
+
+	int GetKeyId(const char *pKeyName);
+
+	static void ConBind(IConsole::IResult *pResult, void *pUserData);
+	static void ConUnbind(IConsole::IResult *pResult, void *pUserData);
+	static void ConUnbindAll(IConsole::IResult *pResult, void *pUserData);
+	static void ConDumpBinds(IConsole::IResult *pResult, void *pUserData);
+	class IConsole *GetConsole() const { return Console(); }
+	
+	static void ConfigSaveCallback(class IConfig *pConfig, void *pUserData);
+	
+public:
+	CBinds();
+	
+	class CBindsSpecial : public CComponent
+	{
+	public:
+		CBinds *m_pBinds;
+		virtual bool OnInput(IInput::CEvent Event);
+	};
+	
+	CBindsSpecial m_SpecialBinds;
+	
+	void Bind(int KeyId, const char *pStr);
+	void SetDefaults();
+	void UnbindAll();
+	const char *Get(int KeyId);
+	const char *GetKey(const char *pBindStr);
+	
+	virtual void OnConsoleInit();
+	virtual bool OnInput(IInput::CEvent Event);
+};
+#endif
diff --git a/src/game/client/components/binds.hpp b/src/game/client/components/binds.hpp
deleted file mode 100644
index bdf242f9..00000000
--- a/src/game/client/components/binds.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <game/client/component.hpp>
-
-class BINDS : public COMPONENT
-{
-	char keybindings[KEY_LAST][128];
-
-	int get_key_id(const char *key_name);
-
-	static void con_bind(void *result, void *user_data);
-	static void con_unbind(void *result, void *user_data);
-	static void con_unbindall(void *result, void *user_data);
-	static void con_dump_binds(void *result, void *user_data);
-	
-public:
-	BINDS();
-	
-	class BINDS_SPECIAL : public COMPONENT
-	{
-	public:
-		BINDS *binds;
-		virtual bool on_input(INPUT_EVENT e);
-	};
-	
-	BINDS_SPECIAL special_binds;
-	
-	void bind(int keyid, const char *str);
-	void set_defaults();
-	void unbindall();
-	const char *get(int keyid);
-	const char *get_key(const char *bindstr);
-	
-	virtual void on_save();
-	virtual void on_console_init();
-	virtual bool on_input(INPUT_EVENT e);
-};
diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp
index b86ed658..c3eb3b56 100644
--- a/src/game/client/components/broadcast.cpp
+++ b/src/game/client/components/broadcast.cpp
@@ -1,36 +1,36 @@
-#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>
+#include <engine/shared/config.h>
+#include <engine/graphics.h>
+#include <engine/textrender.h>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
 
-#include <game/client/gameclient.hpp>
+#include <game/client/gameclient.h>
 
-#include "broadcast.hpp"
+#include "broadcast.h"
 	
-void BROADCAST::on_reset()
+void CBroadcast::OnReset()
 {
-	broadcast_time = 0;
+	m_BroadcastTime = 0;
 }
 
-void BROADCAST::on_render()
+void CBroadcast::OnRender()
 {
 	Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300);
 		
-	if(time_get() < broadcast_time)
+	if(time_get() < m_BroadcastTime)
 	{
-		float w = gfx_text_width(0, 14, broadcast_text, -1);
-		gfx_text(0, 150*Graphics()->ScreenAspect()-w/2, 35, 14, broadcast_text, -1);
+		float w = TextRender()->TextWidth(0, 14, m_aBroadcastText, -1);
+		TextRender()->Text(0, 150*Graphics()->ScreenAspect()-w/2, 35, 14, m_aBroadcastText, -1);
 	}
 }
 
-void BROADCAST::on_message(int msgtype, void *rawmsg)
+void CBroadcast::OnMessage(int MsgType, void *pRawMsg)
 {
-	if(msgtype == NETMSGTYPE_SV_BROADCAST)
+	if(MsgType == NETMSGTYPE_SV_BROADCAST)
 	{
-		NETMSG_SV_BROADCAST *msg = (NETMSG_SV_BROADCAST *)rawmsg;
-		str_copy(broadcast_text, msg->message, sizeof(broadcast_text));
-		broadcast_time = time_get()+time_freq()*10;
+		CNetMsg_Sv_Broadcast *pMsg = (CNetMsg_Sv_Broadcast *)pRawMsg;
+		str_copy(m_aBroadcastText, pMsg->m_pMessage, sizeof(m_aBroadcastText));
+		m_BroadcastTime = time_get()+time_freq()*10;
 	}
 }
 
diff --git a/src/game/client/components/broadcast.h b/src/game/client/components/broadcast.h
new file mode 100644
index 00000000..ed281a2f
--- /dev/null
+++ b/src/game/client/components/broadcast.h
@@ -0,0 +1,17 @@
+#ifndef GAME_CLIENT_COMPONENTS_BROADCAST_H
+#define GAME_CLIENT_COMPONENTS_BROADCAST_H
+#include <game/client/component.h>
+
+class CBroadcast : public CComponent
+{
+public:
+	// broadcasts
+	char m_aBroadcastText[1024];
+	int64 m_BroadcastTime;
+	
+	virtual void OnReset();
+	virtual void OnRender();
+	virtual void OnMessage(int MsgType, void *pRawMsg);
+};
+
+#endif
diff --git a/src/game/client/components/broadcast.hpp b/src/game/client/components/broadcast.hpp
deleted file mode 100644
index 102201cc..00000000
--- a/src/game/client/components/broadcast.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <game/client/component.hpp>
-
-class BROADCAST : public COMPONENT
-{
-public:
-	// broadcasts
-	char broadcast_text[1024];
-	int64 broadcast_time;
-	
-	virtual void on_reset();
-	virtual void on_render();
-	virtual void on_message(int msgtype, void *rawmsg);
-};
-
diff --git a/src/game/client/components/camera.cpp b/src/game/client/components/camera.cpp
index 7b188e00..96baf459 100644
--- a/src/game/client/components/camera.cpp
+++ b/src/game/client/components/camera.cpp
@@ -1,40 +1,37 @@
-extern "C" {
-	#include <engine/e_config.h>
-	#include <engine/e_client_interface.h>
-}
+#include <engine/shared/config.h>
 
-#include <base/math.hpp>
-#include <game/collision.hpp>
-#include <game/client/gameclient.hpp>
-#include <game/client/component.hpp>
+#include <base/math.h>
+#include <game/collision.h>
+#include <game/client/gameclient.h>
+#include <game/client/component.h>
 
-#include "camera.hpp"
-#include "controls.hpp"
+#include "camera.h"
+#include "controls.h"
 
-CAMERA::CAMERA()
+CCamera::CCamera()
 {
 }
 
-void CAMERA::on_render()
+void CCamera::OnRender()
 {
 	//vec2 center;
-	zoom = 1.0f;
+	m_Zoom = 1.0f;
 
 	// update camera center		
-	if(gameclient.snap.spectate)
-		center = gameclient.controls->mouse_pos;
+	if(m_pClient->m_Snap.m_Spectate)
+		m_Center = m_pClient->m_pControls->m_MousePos;
 	else
 	{
 
-		float l = length(gameclient.controls->mouse_pos);
-		float deadzone = config.cl_mouse_deadzone;
-		float follow_factor = config.cl_mouse_followfactor/100.0f;
-		vec2 camera_offset(0, 0);
+		float l = length(m_pClient->m_pControls->m_MousePos);
+		float DeadZone = g_Config.m_ClMouseDeadzone;
+		float FollowFactor = g_Config.m_ClMouseFollowfactor/100.0f;
+		vec2 CameraOffset(0, 0);
 
-		float offset_amount = max(l-deadzone, 0.0f) * follow_factor;
+		float OffsetAmount = max(l-DeadZone, 0.0f) * FollowFactor;
 		if(l > 0.0001f) // make sure that this isn't 0
-			camera_offset = normalize(gameclient.controls->mouse_pos)*offset_amount;
+			CameraOffset = normalize(m_pClient->m_pControls->m_MousePos)*OffsetAmount;
 		
-		center = gameclient.local_character_pos + camera_offset;
+		m_Center = m_pClient->m_LocalCharacterPos + CameraOffset;
 	}
 }
diff --git a/src/game/client/components/camera.h b/src/game/client/components/camera.h
new file mode 100644
index 00000000..9654bdf6
--- /dev/null
+++ b/src/game/client/components/camera.h
@@ -0,0 +1,16 @@
+#ifndef GAME_CLIENT_COMPONENTS_CAMERA_H
+#define GAME_CLIENT_COMPONENTS_CAMERA_H
+#include <base/vmath.h>
+#include <game/client/component.h>
+
+class CCamera : public CComponent
+{	
+public:
+	vec2 m_Center;
+	float m_Zoom;
+
+	CCamera();
+	virtual void OnRender();
+};
+
+#endif
diff --git a/src/game/client/components/camera.hpp b/src/game/client/components/camera.hpp
deleted file mode 100644
index 1cb05f5b..00000000
--- a/src/game/client/components/camera.hpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <base/vmath.hpp>
-#include <game/client/component.hpp>
-
-class CAMERA : public COMPONENT
-{	
-public:
-	vec2 center;
-	float zoom;
-
-	CAMERA();
-	virtual void on_render();
-};
-
diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp
index fdf1d21b..1a2c828d 100644
--- a/src/game/client/components/chat.cpp
+++ b/src/game/client/components/chat.cpp
@@ -1,227 +1,263 @@
-#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>
+#include <engine/graphics.h>
+#include <engine/textrender.h>
+#include <engine/keys.h>
+#include <engine/shared/config.h>
 
-#include <game/client/gameclient.hpp>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
 
-#include <game/client/components/sounds.hpp>
+#include <game/client/gameclient.h>
 
-#include "chat.hpp"
+#include <game/client/components/sounds.h>
+#include <game/localization.h>
 
-void CHAT::on_statechange(int new_state, int old_state)
+#include "chat.h"
+
+
+CChat::CChat()
 {
-	if(old_state <= CLIENTSTATE_CONNECTING)
+	OnReset();
+}
+
+void CChat::OnReset()
+{
+	for(int i = 0; i < MAX_LINES; i++)
 	{
-		mode = MODE_NONE;
+		m_aLines[i].m_Time = 0;
+		m_aLines[i].m_aText[0] = 0;
+		m_aLines[i].m_aName[0] = 0;
+	}
+}
+
+void CChat::OnStateChange(int NewState, int OldState)
+{
+	if(OldState <= IClient::STATE_CONNECTING)
+	{
+		m_Mode = MODE_NONE;
 		for(int i = 0; i < MAX_LINES; i++)
-			lines[i].time = 0;
-		current_line = 0;
+			m_aLines[i].m_Time = 0;
+		m_CurrentLine = 0;
 	}
 }
 
-void CHAT::con_say(void *result, void *user_data)
+void CChat::ConSay(IConsole::IResult *pResult, void *pUserData)
 {
-	((CHAT*)user_data)->say(0, console_arg_string(result, 0));
+	((CChat*)pUserData)->Say(0, pResult->GetString(0));
 }
 
-void CHAT::con_sayteam(void *result, void *user_data)
+void CChat::ConSayTeam(IConsole::IResult *pResult, void *pUserData)
 {
-	((CHAT*)user_data)->say(1, console_arg_string(result, 0));
+	((CChat*)pUserData)->Say(1, pResult->GetString(0));
 }
 
-void CHAT::con_chat(void *result, void *user_data)
+void CChat::ConChat(IConsole::IResult *pResult, void *pUserData)
 {
-	const char *mode = console_arg_string(result, 0);
-	if(strcmp(mode, "all") == 0)
-		((CHAT*)user_data)->enable_mode(0);
-	else if(strcmp(mode, "team") == 0)
-		((CHAT*)user_data)->enable_mode(1);
+	const char *pMode = pResult->GetString(0);
+	if(str_comp(pMode, "all") == 0)
+		((CChat*)pUserData)->EnableMode(0);
+	else if(str_comp(pMode, "team") == 0)
+		((CChat*)pUserData)->EnableMode(1);
 	else
 		dbg_msg("console", "expected all or team as mode");
 }
 
-void CHAT::on_console_init()
+void CChat::OnConsoleInit()
 {
-	MACRO_REGISTER_COMMAND("say", "r", CFGFLAG_CLIENT, con_say, this, "Say in chat");
-	MACRO_REGISTER_COMMAND("say_team", "r", CFGFLAG_CLIENT, con_sayteam, this, "Say in team chat");
-	MACRO_REGISTER_COMMAND("chat", "s", CFGFLAG_CLIENT, con_chat, this, "Enable chat with all/team mode");
+	Console()->Register("say", "r", CFGFLAG_CLIENT, ConSay, this, "Say in chat");
+	Console()->Register("say_team", "r", CFGFLAG_CLIENT, ConSayTeam, this, "Say in team chat");
+	Console()->Register("chat", "s", CFGFLAG_CLIENT, ConChat, this, "Enable chat with all/team mode");
 }
 
-bool CHAT::on_input(INPUT_EVENT e)
+bool CChat::OnInput(IInput::CEvent e)
 {
-	if(mode == MODE_NONE)
+	if(m_Mode == MODE_NONE)
 		return false;
 
-	if(e.flags&INPFLAG_PRESS && e.key == KEY_ESCAPE)
-		mode = MODE_NONE;
-	else if(e.flags&INPFLAG_PRESS && (e.key == KEY_RETURN || e.key == KEY_KP_ENTER))
+	if(e.m_Flags&IInput::FLAG_PRESS && e.m_Key == KEY_ESCAPE)
+		m_Mode = MODE_NONE;
+	else if(e.m_Flags&IInput::FLAG_PRESS && (e.m_Key == KEY_RETURN || e.m_Key == KEY_KP_ENTER))
 	{
-		if(input.get_string()[0])
-			gameclient.chat->say(mode == MODE_ALL ? 0 : 1, input.get_string());
-		mode = MODE_NONE;
+		if(m_Input.GetString()[0])
+			Say(m_Mode == MODE_ALL ? 0 : 1, m_Input.GetString());
+		m_Mode = MODE_NONE;
 	}
 	else
-		input.process_input(e);
+		m_Input.ProcessInput(e);
 	
 	return true;
 }
 
 
-void CHAT::enable_mode(int team)
+void CChat::EnableMode(int Team)
 {
-	if(mode == MODE_NONE)
+	if(m_Mode == MODE_NONE)
 	{
-		if(team)
-			mode = MODE_TEAM;
+		if(Team)
+			m_Mode = MODE_TEAM;
 		else
-			mode = MODE_ALL;
+			m_Mode = MODE_ALL;
 		
-		input.clear();
-		inp_clear_events();
+		m_Input.Clear();
+		Input()->ClearEvents();
 	}
 }
 
-void CHAT::on_message(int msgtype, void *rawmsg)
+void CChat::OnMessage(int MsgType, void *pRawMsg)
 {
-	if(msgtype == NETMSGTYPE_SV_CHAT)
+	if(MsgType == NETMSGTYPE_SV_CHAT)
 	{
-		NETMSG_SV_CHAT *msg = (NETMSG_SV_CHAT *)rawmsg;
-		add_line(msg->cid, msg->team, msg->message);
+		CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg;
+		AddLine(pMsg->m_Cid, pMsg->m_Team, pMsg->m_pMessage);
 	}
 }
 
-void CHAT::add_line(int client_id, int team, const char *line)
+void CChat::AddLine(int ClientId, int Team, const char *pLine)
 {
-	current_line = (current_line+1)%MAX_LINES;
-	lines[current_line].time = time_get();
-	lines[current_line].client_id = client_id;
-	lines[current_line].team = team;
-	lines[current_line].name_color = -2;
-
-	if(client_id == -1) // server message
+	char *p = const_cast<char*>(pLine);
+	while(*p)
 	{
-		str_copy(lines[current_line].name, "*** ", sizeof(lines[current_line].name));
-		str_format(lines[current_line].text, sizeof(lines[current_line].text), "%s", line);
-	}
-	else
-	{
-		if(gameclient.clients[client_id].team == -1)
-			lines[current_line].name_color = -1;
+		pLine = p;
+		// find line seperator and strip multiline
+		while(*p)
+		{
+			if(*p++ == '\n')
+			{
+				*(p-1) = 0;
+				break;
+			}
+		}
 
-		if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS)
+		m_CurrentLine = (m_CurrentLine+1)%MAX_LINES;
+		m_aLines[m_CurrentLine].m_Time = time_get();
+		m_aLines[m_CurrentLine].m_ClientId = ClientId;
+		m_aLines[m_CurrentLine].m_Team = Team;
+		m_aLines[m_CurrentLine].m_NameColor = -2;
+
+		if(ClientId == -1) // server message
+		{
+			str_copy(m_aLines[m_CurrentLine].m_aName, "*** ", sizeof(m_aLines[m_CurrentLine].m_aName));
+			str_format(m_aLines[m_CurrentLine].m_aText, sizeof(m_aLines[m_CurrentLine].m_aText), "%s", pLine);
+		}
+		else
 		{
-			if(gameclient.clients[client_id].team == 0)
-				lines[current_line].name_color = 0;
-			else if(gameclient.clients[client_id].team == 1)
-				lines[current_line].name_color = 1;
+			if(m_pClient->m_aClients[ClientId].m_Team == -1)
+				m_aLines[m_CurrentLine].m_NameColor = -1;
+
+			if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS)
+			{
+				if(m_pClient->m_aClients[ClientId].m_Team == 0)
+					m_aLines[m_CurrentLine].m_NameColor = 0;
+				else if(m_pClient->m_aClients[ClientId].m_Team == 1)
+					m_aLines[m_CurrentLine].m_NameColor = 1;
+			}
+			
+			str_copy(m_aLines[m_CurrentLine].m_aName, m_pClient->m_aClients[ClientId].m_aName, sizeof(m_aLines[m_CurrentLine].m_aName));
+			str_format(m_aLines[m_CurrentLine].m_aText, sizeof(m_aLines[m_CurrentLine].m_aText), ": %s", pLine);
 		}
 		
-		str_copy(lines[current_line].name, gameclient.clients[client_id].name, sizeof(lines[current_line].name));
-		str_format(lines[current_line].text, sizeof(lines[current_line].text), ": %s", line);
+		char aBuf[1024];
+		str_format(aBuf, sizeof(aBuf), "[chat]%s%s", m_aLines[m_CurrentLine].m_aName, m_aLines[m_CurrentLine].m_aText);
+		Console()->Print(aBuf);
 	}
-	
+
 	// play sound
-	if(client_id >= 0)
-		gameclient.sounds->play(SOUNDS::CHN_GUI, SOUND_CHAT_CLIENT, 0, vec2(0,0));
+	if(ClientId >= 0)
+		m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_CLIENT, 0, vec2(0,0));
 	else
-		gameclient.sounds->play(SOUNDS::CHN_GUI, SOUND_CHAT_SERVER, 0, vec2(0,0));
-	
-	dbg_msg("chat", "%s%s", lines[current_line].name, lines[current_line].text);
+		m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_SERVER, 0, vec2(0,0));
 }
 
-void CHAT::on_render()
+void CChat::OnRender()
 {
 	Graphics()->MapScreen(0,0,300*Graphics()->ScreenAspect(),300);
 	float x = 10.0f;
 	float y = 300.0f-20.0f;
-	if(mode != MODE_NONE)
+	if(m_Mode != MODE_NONE)
 	{
 		// render chat input
-		TEXT_CURSOR cursor;
-		gfx_text_set_cursor(&cursor, x, y, 8.0f, TEXTFLAG_RENDER);
-		cursor.line_width = 200.0f;
+		CTextCursor Cursor;
+		TextRender()->SetCursor(&Cursor, x, y, 8.0f, TEXTFLAG_RENDER);
+		Cursor.m_LineWidth = 200.0f;
 		
-		if(mode == MODE_ALL)
-			gfx_text_ex(&cursor, localize("All"), -1);
-		else if(mode == MODE_TEAM)
-			gfx_text_ex(&cursor, localize("Team"), -1);
+		if(m_Mode == MODE_ALL)
+			TextRender()->TextEx(&Cursor, Localize("All"), -1);
+		else if(m_Mode == MODE_TEAM)
+			TextRender()->TextEx(&Cursor, Localize("Team"), -1);
 		else
-			gfx_text_ex(&cursor, localize("Chat"), -1);
+			TextRender()->TextEx(&Cursor, Localize("Chat"), -1);
 
-		gfx_text_ex(&cursor, ": ", -1);
+		TextRender()->TextEx(&Cursor, ": ", -1);
 			
-		gfx_text_ex(&cursor, input.get_string(), input.cursor_offset());
-		TEXT_CURSOR marker = cursor;
-		gfx_text_ex(&marker, "|", -1);
-		gfx_text_ex(&cursor, input.get_string()+input.cursor_offset(), -1);
+		TextRender()->TextEx(&Cursor, m_Input.GetString(), m_Input.GetCursorOffset());
+		CTextCursor Marker = Cursor;
+		TextRender()->TextEx(&Marker, "|", -1);
+		TextRender()->TextEx(&Cursor, m_Input.GetString()+m_Input.GetCursorOffset(), -1);
 	}
 
 	y -= 8;
 
 	int i;
+	int64 Now = time_get();
 	for(i = 0; i < MAX_LINES; i++)
 	{
-		int r = ((current_line-i)+MAX_LINES)%MAX_LINES;
-		if(time_get() > lines[r].time+15*time_freq())
+		int r = ((m_CurrentLine-i)+MAX_LINES)%MAX_LINES;
+		if(Now > m_aLines[r].m_Time+15*time_freq())
 			break;
 
-		float begin = x;
-		float fontsize = 7.0f;
+		float Begin = x;
+		float FontSize = 7.0f;
 		
 		// get the y offset
-		TEXT_CURSOR cursor;
-		gfx_text_set_cursor(&cursor, begin, 0, fontsize, 0);
-		cursor.line_width = 200.0f;
-		gfx_text_ex(&cursor, lines[r].name, -1);
-		gfx_text_ex(&cursor, lines[r].text, -1);
-		y -= cursor.y + cursor.font_size;
+		CTextCursor Cursor;
+		TextRender()->SetCursor(&Cursor, Begin, 0, FontSize, 0);
+		Cursor.m_LineWidth = 200.0f;
+		TextRender()->TextEx(&Cursor, m_aLines[r].m_aName, -1);
+		TextRender()->TextEx(&Cursor, m_aLines[r].m_aText, -1);
+		y -= Cursor.m_Y + Cursor.m_FontSize;
 
 		// cut off if msgs waste too much space
 		if(y < 200.0f)
 			break;
 		
 		// reset the cursor
-		gfx_text_set_cursor(&cursor, begin, y, fontsize, TEXTFLAG_RENDER);
-		cursor.line_width = 200.0f;
+		TextRender()->SetCursor(&Cursor, Begin, y, FontSize, TEXTFLAG_RENDER);
+		Cursor.m_LineWidth = 200.0f;
 
 		// render name
-		gfx_text_color(0.8f,0.8f,0.8f,1);
-		if(lines[r].client_id == -1)
-			gfx_text_color(1,1,0.5f,1); // system
-		else if(lines[r].team)
-			gfx_text_color(0.45f,0.9f,0.45f,1); // team message
-		else if(lines[r].name_color == 0)
-			gfx_text_color(1.0f,0.5f,0.5f,1); // red
-		else if(lines[r].name_color == 1)
-			gfx_text_color(0.7f,0.7f,1.0f,1); // blue
-		else if(lines[r].name_color == -1)
-			gfx_text_color(0.75f,0.5f,0.75f, 1); // spectator
+		TextRender()->TextColor(0.8f,0.8f,0.8f,1);
+		if(m_aLines[r].m_ClientId == -1)
+			TextRender()->TextColor(1,1,0.5f,1); // system
+		else if(m_aLines[r].m_Team)
+			TextRender()->TextColor(0.45f,0.9f,0.45f,1); // team message
+		else if(m_aLines[r].m_NameColor == 0)
+			TextRender()->TextColor(1.0f,0.5f,0.5f,1); // red
+		else if(m_aLines[r].m_NameColor == 1)
+			TextRender()->TextColor(0.7f,0.7f,1.0f,1); // blue
+		else if(m_aLines[r].m_NameColor == -1)
+			TextRender()->TextColor(0.75f,0.5f,0.75f, 1); // spectator
 			
 		// render name
-		gfx_text_ex(&cursor, lines[r].name, -1);
+		TextRender()->TextEx(&Cursor, m_aLines[r].m_aName, -1);
 
 		// render line
-		gfx_text_color(1,1,1,1);
-		if(lines[r].client_id == -1)
-			gfx_text_color(1,1,0.5f,1); // system
-		else if(lines[r].team)
-			gfx_text_color(0.65f,1,0.65f,1); // team message
+		TextRender()->TextColor(1,1,1,1);
+		if(m_aLines[r].m_ClientId == -1)
+			TextRender()->TextColor(1,1,0.5f,1); // system
+		else if(m_aLines[r].m_Team)
+			TextRender()->TextColor(0.65f,1,0.65f,1); // team message
 
-		gfx_text_ex(&cursor, lines[r].text, -1);
+		TextRender()->TextEx(&Cursor, m_aLines[r].m_aText, -1);
 	}
 
-	gfx_text_color(1,1,1,1);
+	TextRender()->TextColor(1,1,1,1);
 }
 
-void CHAT::say(int team, const char *line)
+void CChat::Say(int Team, const char *pLine)
 {
 	// send chat message
-	NETMSG_CL_SAY msg;
-	msg.team = team;
-	msg.message = line;
-	msg.pack(MSGFLAG_VITAL);
-	client_send_msg();
+	CNetMsg_Cl_Say Msg;
+	Msg.m_Team = Team;
+	Msg.m_pMessage = pLine;
+	Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
 }
diff --git a/src/game/client/components/chat.h b/src/game/client/components/chat.h
new file mode 100644
index 00000000..8a33e9e8
--- /dev/null
+++ b/src/game/client/components/chat.h
@@ -0,0 +1,60 @@
+#ifndef GAME_CLIENT_COMPONENTS_CHAT_H
+#define GAME_CLIENT_COMPONENTS_CHAT_H
+#include <game/client/component.h>
+#include <game/client/lineinput.h>
+
+class CChat : public CComponent
+{
+	CLineInput m_Input;
+	
+	enum 
+	{
+		MAX_LINES = 10,
+	};
+
+	struct CLine
+	{
+		int64 m_Time;
+		int m_ClientId;
+		int m_Team;
+		int m_NameColor;
+		char m_aName[64];
+		char m_aText[512];
+	};
+
+	CLine m_aLines[MAX_LINES];
+	int m_CurrentLine;
+
+	// chat
+	enum
+	{
+		MODE_NONE=0,
+		MODE_ALL,
+		MODE_TEAM,
+	};
+
+	int m_Mode;
+	
+	static void ConSay(IConsole::IResult *pResult, void *pUserData);
+	static void ConSayTeam(IConsole::IResult *pResult, void *pUserData);
+	static void ConChat(IConsole::IResult *pResult, void *pUserData);
+	
+public:
+	CChat();
+
+	bool IsActive() const { return m_Mode != MODE_NONE; }
+	
+	void AddLine(int ClientId, int Team, const char *pLine);
+	
+	void EnableMode(int Team);
+	
+	void Say(int Team, const char *pLine);
+	
+	virtual void OnReset();
+	virtual void OnConsoleInit();
+	virtual void OnStateChange(int NewState, int OldState);
+	virtual void OnRender();
+	virtual void OnMessage(int MsgType, void *pRawMsg);
+	virtual bool OnInput(IInput::CEvent Event);
+};
+#endif
diff --git a/src/game/client/components/chat.hpp b/src/game/client/components/chat.hpp
deleted file mode 100644
index ca34237d..00000000
--- a/src/game/client/components/chat.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <game/client/component.hpp>
-#include <game/client/lineinput.hpp>
-
-class CHAT : public COMPONENT
-{
-	LINEINPUT input;
-	
-	enum 
-	{
-		MAX_LINES = 10,
-	};
-
-	struct LINE
-	{
-		int64 time;
-		int client_id;
-		int team;
-		int name_color;
-		char name[64];
-		char text[512];
-	};
-
-	LINE lines[MAX_LINES];
-	int current_line;
-
-	// chat
-	enum
-	{
-		MODE_NONE=0,
-		MODE_ALL,
-		MODE_TEAM,
-	};
-
-	int mode;
-	
-	static void con_say(void *result, void *user_data);
-	static void con_sayteam(void *result, void *user_data);
-	static void con_chat(void *result, void *user_data);
-	
-public:
-	bool is_active() const { return mode != MODE_NONE; }
-	
-	void add_line(int client_id, int team, const char *line);
-	
-	void enable_mode(int team);
-	
-	void say(int team, const char *line);
-	
-	virtual void on_console_init();
-	virtual void on_statechange(int new_state, int old_state);
-	virtual void on_render();
-	virtual void on_message(int msgtype, void *rawmsg);
-	virtual bool on_input(INPUT_EVENT e);
-};
diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp
index 382cb134..7de85f69 100644
--- a/src/game/client/components/console.cpp
+++ b/src/game/client/components/console.cpp
@@ -1,26 +1,29 @@
-//#include "gc_console.hpp"
+//#include "gc_console.h"
 #include <math.h>
 
-#include <game/generated/gc_data.hpp>
+#include <game/generated/client_data.h>
 
 #include <base/system.h>
 
-#include <engine/e_client_interface.h>
-#include <engine/client/graphics.h>
-
-#include <engine/e_ringbuffer.h>
+#include <engine/shared/ringbuffer.h>
+#include <engine/shared/config.h>
+#include <engine/graphics.h>
+#include <engine/textrender.h>
+#include <engine/keys.h>
+#include <engine/console.h>
 
 #include <cstring>
 #include <cstdio>
 
-#include <game/client/ui.hpp>
+#include <game/client/ui.h>
 
-#include <game/version.hpp>
+#include <game/version.h>
 
-#include <game/client/lineinput.hpp>
-#include <game/client/render.hpp>
+#include <game/client/lineinput.h>
+#include <game/client/render.h>
+#include <game/client/components/menus.h>
 
-#include "console.hpp"
+#include "console.h"
 
 enum
 {
@@ -30,479 +33,550 @@ enum
 	CONSOLE_CLOSING,
 };
 
-CONSOLE::INSTANCE::INSTANCE(int t)
+CGameConsole::CInstance::CInstance(CGameConsole *pGameConsole, int Type)
 {
+	m_pGameConsole = pGameConsole;
 	// 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_entry = 0x0;
+	m_pHistoryEntry = 0x0;
 	
-	type = t;
+	m_Type = Type;
 	
-	if(t == 0)
-		completion_flagmask = CFGFLAG_CLIENT;
+	if(Type == 0)
+		m_CompletionFlagmask = CFGFLAG_CLIENT;
 	else
-		completion_flagmask = CFGFLAG_SERVER;
+		m_CompletionFlagmask = CFGFLAG_SERVER;
 
-	completion_buffer[0] = 0;
-	completion_chosen = -1;
+	m_aCompletionBuffer[0] = 0;
+	m_CompletionChosen = -1;
 	
-	command = 0x0;
+	m_pCommand = 0x0;
 }
 
-void CONSOLE::INSTANCE::execute_line(const char *line)
+void CGameConsole::CInstance::ExecuteLine(const char *pLine)
 {
-	if(type == 0)
-		console_execute_line(line);
+	if(m_Type == 0)
+		m_pGameConsole->m_pConsole->ExecuteLine(pLine);
 	else
 	{
-		if(client_rcon_authed())
-			client_rcon(line);
+		if(m_pGameConsole->Client()->RconAuthed())
+			m_pGameConsole->Client()->Rcon(pLine);
 		else
-			client_rcon_auth("", line);
+			m_pGameConsole->Client()->RconAuth("", pLine);
 	}
 }
 
-void CONSOLE::INSTANCE::possible_commands_complete_callback(const char *str, void *user)
+void CGameConsole::CInstance::PossibleCommandsCompleteCallback(const char *pStr, void *pUser)
 {
-	CONSOLE::INSTANCE *instance = (CONSOLE::INSTANCE *)user;
-	if(instance->completion_chosen == instance->completion_enumeration_count)
-		instance->input.set(str);
-	instance->completion_enumeration_count++;
+	CGameConsole::CInstance *pInstance = (CGameConsole::CInstance *)pUser;
+	if(pInstance->m_CompletionChosen == pInstance->m_CompletionEnumerationCount)
+		pInstance->m_Input.Set(pStr);
+	pInstance->m_CompletionEnumerationCount++;
 }
 
-void CONSOLE::INSTANCE::on_input(INPUT_EVENT e)
+void CGameConsole::CInstance::OnInput(IInput::CEvent Event)
 {
-	bool handled = false;
+	bool Handled = false;
 	
-	if(e.flags&INPFLAG_PRESS)
+	if(Event.m_Flags&IInput::FLAG_PRESS)
 	{
-		if(e.key == KEY_RETURN || e.key == KEY_KP_ENTER)
+		if(Event.m_Key == KEY_RETURN || Event.m_Key == KEY_KP_ENTER)
 		{
-			if(input.get_string()[0])
+			if(m_Input.GetString()[0])
 			{
-				char *entry = history.Allocate(input.get_length()+1);
-				mem_copy(entry, input.get_string(), input.get_length()+1);
-				
-				execute_line(input.get_string());
-				input.clear();
-				history_entry = 0x0;
+				char *pEntry = m_History.Allocate(m_Input.GetLength()+1);
+				mem_copy(pEntry, m_Input.GetString(), m_Input.GetLength()+1);				
+				ExecuteLine(m_Input.GetString());
+				m_Input.Clear();
+				m_pHistoryEntry = 0x0;
 			}
 			
-			handled = true;
+			Handled = true;
 		}
-		else if (e.key == KEY_UP)
+		else if (Event.m_Key == KEY_UP)
 		{
-			if (history_entry)
+			if (m_pHistoryEntry)
 			{
-				char *test = history.Prev(history_entry);
+				char *pTest = m_History.Prev(m_pHistoryEntry);
 
-				if (test)
-					history_entry = test;
+				if (pTest)
+					m_pHistoryEntry = pTest;
 			}
 			else
-				history_entry = history.Last();
+				m_pHistoryEntry = m_History.Last();
 
-			if (history_entry)
+			if (m_pHistoryEntry)
 			{
-				unsigned int len = strlen(history_entry);
-				if (len < sizeof(input) - 1)
-					input.set(history_entry);
+				unsigned int Len = str_length(m_pHistoryEntry);
+				if (Len < sizeof(m_Input) - 1) // TODO: WTF?
+					m_Input.Set(m_pHistoryEntry);
 			}
-			handled = true;
+			Handled = true;
 		}
-		else if (e.key == KEY_DOWN)
+		else if (Event.m_Key == KEY_DOWN)
 		{
-			if (history_entry)
-				history_entry = history.Next(history_entry);
+			if (m_pHistoryEntry)
+				m_pHistoryEntry = m_History.Next(m_pHistoryEntry);
 
-			if (history_entry)
+			if (m_pHistoryEntry)
 			{
-				unsigned int len = strlen(history_entry);
-				if (len < sizeof(input) - 1)
-					input.set(history_entry);
+				unsigned int Len = str_length(m_pHistoryEntry);
+				if (Len < sizeof(m_Input) - 1) // TODO: WTF?
+					m_Input.Set(m_pHistoryEntry);
 			}
 			else
-				input.clear();
-			handled = true;
+				m_Input.Clear();
+			Handled = true;
 		}
-		else if(e.key == KEY_TAB)
+		else if(Event.m_Key == KEY_TAB)
 		{
-			completion_chosen++;
-			completion_enumeration_count = 0;
-			console_possible_commands(completion_buffer, completion_flagmask, possible_commands_complete_callback, this);
-
-			// handle wrapping
-			if(completion_enumeration_count && completion_chosen >= completion_enumeration_count)
+			if(m_Type == 0 || m_pGameConsole->Client()->RconAuthed())
 			{
-				completion_chosen %= completion_enumeration_count;
-				completion_enumeration_count = 0;
-				console_possible_commands(completion_buffer, completion_flagmask, possible_commands_complete_callback, this);
+				m_CompletionChosen++;
+				m_CompletionEnumerationCount = 0;
+				m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, PossibleCommandsCompleteCallback, this);
+
+				// handle wrapping
+				if(m_CompletionEnumerationCount && m_CompletionChosen >= m_CompletionEnumerationCount)
+				{
+					m_CompletionChosen %= m_CompletionEnumerationCount;
+					m_CompletionEnumerationCount = 0;
+					m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, PossibleCommandsCompleteCallback, this);
+				}
 			}
 		}
-		
-		if(e.key != KEY_TAB)
+		else if(Event.m_Key == KEY_PAGEUP)
+		{
+			++m_BacklogActPage;
+		}
+		else if(Event.m_Key == KEY_PAGEDOWN)
 		{
-			completion_chosen = -1;
-			str_copy(completion_buffer, input.get_string(), sizeof(completion_buffer));
+			--m_BacklogActPage;
+			if(m_BacklogActPage < 0)
+				m_BacklogActPage = 0;
+		}
+	}
+
+	if(!Handled)
+		m_Input.ProcessInput(Event);
+
+	if(Event.m_Flags&IInput::FLAG_PRESS)
+	{
+		if(Event.m_Key != KEY_TAB)
+		{
+			m_CompletionChosen = -1;
+			str_copy(m_aCompletionBuffer, m_Input.GetString(), sizeof(m_aCompletionBuffer));
 		}
 
 		// find the current command
 		{
-			char buf[64] = {0};
-			const char *src = get_string();
+			char aBuf[64] = {0};
+			const char *pSrc = GetString();
 			int i = 0;
-			for(; i < (int)sizeof(buf) && *src && *src != ' '  && *src != ' '; i++, src++)
-				buf[i] = *src;
-			buf[i] = 0;
+			for(; i < (int)sizeof(aBuf) && *pSrc && *pSrc != ' '  && *pSrc != ' '; i++, pSrc++)
+				aBuf[i] = *pSrc;
+			aBuf[i] = 0;
 			
-			command = console_get_command(buf);
+			m_pCommand = m_pGameConsole->m_pConsole->GetCommandInfo(aBuf);
 		}
 	}
-	
-	if(!handled)
-		input.process_input(e);
 }
 
-void CONSOLE::INSTANCE::print_line(const char *line)
+void CGameConsole::CInstance::PrintLine(const char *pLine)
 {
-	int len = strlen(line);
+	int Len = str_length(pLine);
 
-	if (len > 255)
-		len = 255;
+	if (Len > 255)
+		Len = 255;
 
-	char *entry = backlog.Allocate(len+1);
-	mem_copy(entry, line, len+1);
+	char *pEntry = m_Backlog.Allocate(Len+1);
+	mem_copy(pEntry, pLine, Len);
+	pEntry[Len] = 0;
 }
 
-CONSOLE::CONSOLE()
-: local_console(0), remote_console(1)
+CGameConsole::CGameConsole()
+: m_LocalConsole(this, 0), m_RemoteConsole(this, 1)
 {
-	console_type = 0;
-	console_state = CONSOLE_CLOSED;
-	state_change_end = 0.0f;
-	state_change_duration = 0.1f;
+	m_ConsoleType = 0;
+	m_ConsoleState = CONSOLE_CLOSED;
+	m_StateChangeEnd = 0.0f;
+	m_StateChangeDuration = 0.1f;
 }
 
-float CONSOLE::time_now()
+float CGameConsole::TimeNow()
 {
-	static long long time_start = time_get();
-	return float(time_get()-time_start)/float(time_freq());
+	static long long s_TimeStart = time_get();
+	return float(time_get()-s_TimeStart)/float(time_freq());
 }
 
-CONSOLE::INSTANCE *CONSOLE::current_console()
+CGameConsole::CInstance *CGameConsole::CurrentConsole()
 {
-    if(console_type != 0)
-    	return &remote_console;
-    return &local_console;
+    if(m_ConsoleType != 0)
+    	return &m_RemoteConsole;
+    return &m_LocalConsole;
 }
 
-void CONSOLE::on_reset()
+void CGameConsole::OnReset()
 {
 }
 
 // only defined for 0<=t<=1
-static float console_scale_func(float t)
+static float ConsoleScaleFunc(float t)
 {
 	//return t;
 	return sinf(acosf(1.0f-t));
 }
 
-struct RENDERINFO
+struct CRenderInfo
 {
-	CONSOLE *self;
-	TEXT_CURSOR cursor;
-	const char *current_cmd;
-	int wanted_completion;
-	int enum_count;
+	CGameConsole *m_pSelf;
+	CTextCursor m_Cursor;
+	const char *m_pCurrentCmd;
+	int m_WantedCompletion;
+	int m_EnumCount;
 };
 
-void CONSOLE::possible_commands_render_callback(const char *str, void *user)
+void CGameConsole::PossibleCommandsRenderCallback(const char *pStr, void *pUser)
 {
-	RENDERINFO *info = (RENDERINFO *)user;
+	CRenderInfo *pInfo = static_cast<CRenderInfo *>(pUser);
 	
-	if(info->enum_count == info->wanted_completion)
+	if(pInfo->m_EnumCount == pInfo->m_WantedCompletion)
 	{
-		float tw = gfx_text_width(info->cursor.font, info->cursor.font_size, str, -1);
-		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();
+		float tw = pInfo->m_pSelf->TextRender()->TextWidth(pInfo->m_Cursor.m_pFont, pInfo->m_Cursor.m_FontSize, pStr, -1);
+		pInfo->m_pSelf->Graphics()->TextureSet(-1);
+		pInfo->m_pSelf->Graphics()->QuadsBegin();
+			pInfo->m_pSelf->Graphics()->SetColor(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,0.85f);
+			pInfo->m_pSelf->RenderTools()->DrawRoundRect(pInfo->m_Cursor.m_X-3, pInfo->m_Cursor.m_Y, tw+5, pInfo->m_Cursor.m_FontSize+4, pInfo->m_Cursor.m_FontSize/3);
+		pInfo->m_pSelf->Graphics()->QuadsEnd();
 		
-		gfx_text_color(0.05f, 0.05f, 0.05f,1);
-		gfx_text_ex(&info->cursor, str, -1);
+		pInfo->m_pSelf->TextRender()->TextColor(0.05f, 0.05f, 0.05f,1);
+		pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pStr, -1);
 	}
 	else
 	{
-		const char *match_start = str_find_nocase(str, info->current_cmd);
+		const char *pMatchStart = str_find_nocase(pStr, pInfo->m_pCurrentCmd);
 		
-		if(match_start)
+		if(pMatchStart)
 		{
-			gfx_text_color(0.5f,0.5f,0.5f,1);
-			gfx_text_ex(&info->cursor, str, match_start-str);
-			gfx_text_color(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,1);
-			gfx_text_ex(&info->cursor, match_start, strlen(info->current_cmd));
-			gfx_text_color(0.5f,0.5f,0.5f,1);
-			gfx_text_ex(&info->cursor, match_start+strlen(info->current_cmd), -1);
+			pInfo->m_pSelf->TextRender()->TextColor(0.5f,0.5f,0.5f,1);
+			pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pStr, pMatchStart-pStr);
+			pInfo->m_pSelf->TextRender()->TextColor(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,1);
+			pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pMatchStart, str_length(pInfo->m_pCurrentCmd));
+			pInfo->m_pSelf->TextRender()->TextColor(0.5f,0.5f,0.5f,1);
+			pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pMatchStart+str_length(pInfo->m_pCurrentCmd), -1);
 		}
 		else
 		{
-			gfx_text_color(0.75f,0.75f,0.75f,1);
-			gfx_text_ex(&info->cursor, str, -1);
+			pInfo->m_pSelf->TextRender()->TextColor(0.75f,0.75f,0.75f,1);
+			pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pStr, -1);
 		}
 	}
 	
-	info->enum_count++;
-	info->cursor.x += 7.0f;
+	pInfo->m_EnumCount++;
+	pInfo->m_Cursor.m_X += 7.0f;
 }
 
-void CONSOLE::on_render()
+void CGameConsole::OnRender()
 {
-    CUIRect screen = *UI()->Screen();
-	float console_max_height = screen.h*3/5.0f;
-	float console_height;
+    CUIRect Screen = *UI()->Screen();
+	float ConsoleMaxHeight = Screen.h*3/5.0f;
+	float ConsoleHeight;
 
-	float progress = (time_now()-(state_change_end-state_change_duration))/float(state_change_duration);
+	float Progress = (TimeNow()-(m_StateChangeEnd-m_StateChangeDuration))/float(m_StateChangeDuration);
 
-	if (progress >= 1.0f)
+	if (Progress >= 1.0f)
 	{
-		if (console_state == CONSOLE_CLOSING)
-			console_state = CONSOLE_CLOSED;
-		else if (console_state == CONSOLE_OPENING)
-			console_state = CONSOLE_OPEN;
+		if (m_ConsoleState == CONSOLE_CLOSING)
+			m_ConsoleState = CONSOLE_CLOSED;
+		else if (m_ConsoleState == CONSOLE_OPENING)
+			m_ConsoleState = CONSOLE_OPEN;
 
-		progress = 1.0f;
+		Progress = 1.0f;
 	}
 
-	if (console_state == CONSOLE_OPEN && config.cl_editor)
-		toggle(0);	
+	if (m_ConsoleState == CONSOLE_OPEN && g_Config.m_ClEditor)
+		Toggle(0);	
 		
-	if (console_state == CONSOLE_CLOSED)
+	if (m_ConsoleState == CONSOLE_CLOSED)
 		return;
 		
-	if (console_state == CONSOLE_OPEN)
-		inp_mouse_mode_absolute();
+	if (m_ConsoleState == CONSOLE_OPEN)
+		Input()->MouseModeAbsolute();
 
-	float console_height_scale;
+	float ConsoleHeightScale;
 
-	if (console_state == CONSOLE_OPENING)
-		console_height_scale = console_scale_func(progress);
-	else if (console_state == CONSOLE_CLOSING)
-		console_height_scale = console_scale_func(1.0f-progress);
+	if (m_ConsoleState == CONSOLE_OPENING)
+		ConsoleHeightScale = ConsoleScaleFunc(Progress);
+	else if (m_ConsoleState == CONSOLE_CLOSING)
+		ConsoleHeightScale = ConsoleScaleFunc(1.0f-Progress);
 	else //if (console_state == CONSOLE_OPEN)
-		console_height_scale = console_scale_func(1.0f);
+		ConsoleHeightScale = ConsoleScaleFunc(1.0f);
 
-	console_height = console_height_scale*console_max_height;
+	ConsoleHeight = ConsoleHeightScale*ConsoleMaxHeight;
 
-	Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);
+	Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
 
 	// do console shadow
 	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);
+	IGraphics::CColorVertex Array[4] = {
+    	IGraphics::CColorVertex(0, 0,0,0, 0.5f),
+    	IGraphics::CColorVertex(1, 0,0,0, 0.5f),
+    	IGraphics::CColorVertex(2, 0,0,0, 0.0f),
+		IGraphics::CColorVertex(3, 0,0,0, 0.0f)};
+	Graphics()->SetColorVertex(Array, 4);
+	IGraphics::CQuadItem QuadItem(0, ConsoleHeight, Screen.w, 10.0f);
+	Graphics()->QuadsDrawTL(&QuadItem, 1);
     Graphics()->QuadsEnd();
 
 	// do background
-	Graphics()->TextureSet(data->images[IMAGE_CONSOLE_BG].id);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CONSOLE_BG].m_Id);
     Graphics()->QuadsBegin();
     Graphics()->SetColor(0.2f, 0.2f, 0.2f,0.9f);
-    if(console_type != 0)
+    if(m_ConsoleType != 0)
 	    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()->QuadsSetSubset(0,-ConsoleHeight*0.075f,Screen.w*0.075f*0.5f,0);
+	QuadItem = IGraphics::CQuadItem(0, 0, Screen.w, ConsoleHeight);
+	Graphics()->QuadsDrawTL(&QuadItem, 1);
     Graphics()->QuadsEnd();
 
 	// do small bar shadow
 	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);
+	Array[0] = IGraphics::CColorVertex(0, 0,0,0, 0.0f);
+	Array[1] = IGraphics::CColorVertex(1, 0,0,0, 0.0f);
+	Array[2] = IGraphics::CColorVertex(2, 0,0,0, 0.25f);
+	Array[3] = IGraphics::CColorVertex(3, 0,0,0, 0.25f);
+	Graphics()->SetColorVertex(Array, 4);
+	QuadItem = IGraphics::CQuadItem(0, ConsoleHeight-20, Screen.w, 10);
+	Graphics()->QuadsDrawTL(&QuadItem, 1);
     Graphics()->QuadsEnd();
 
 	// do the lower bar
-	Graphics()->TextureSet(data->images[IMAGE_CONSOLE_BAR].id);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CONSOLE_BAR].m_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()->QuadsSetSubset(0,0.1f,Screen.w*0.015f,1-0.1f);
+	QuadItem = IGraphics::CQuadItem(0,ConsoleHeight-10.0f,Screen.w,10.0f);
+	Graphics()->QuadsDrawTL(&QuadItem, 1);
     Graphics()->QuadsEnd();
     
-    console_height -= 22.0f;
+    ConsoleHeight -= 22.0f;
     
-    INSTANCE *console = current_console();
+    CInstance *pConsole = CurrentConsole();
 
 	{
-		float font_size = 10.0f;
-		float row_height = font_size*1.25f;
+		float FontSize = 10.0f;
+		float RowHeight = FontSize*1.25f;
 		float x = 3;
-		float y = console_height - row_height - 2;
+		float y = ConsoleHeight - RowHeight - 2;
 
 		// render prompt		
-		TEXT_CURSOR cursor;
-		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;
-		gfx_text_set_cursor(&info.cursor, x, y+12.0f, font_size, TEXTFLAG_RENDER);
-
-		const char *prompt = "> ";
-		if(console_type)
+		CTextCursor Cursor;
+		TextRender()->SetCursor(&Cursor, x, y, FontSize, TEXTFLAG_RENDER);
+
+		CRenderInfo Info;
+		Info.m_pSelf = this;
+		Info.m_WantedCompletion = pConsole->m_CompletionChosen;
+		Info.m_EnumCount = 0;
+		Info.m_pCurrentCmd = pConsole->m_aCompletionBuffer;
+		TextRender()->SetCursor(&Info.m_Cursor, x, y+12.0f, FontSize, TEXTFLAG_RENDER);
+
+		const char *pPrompt = "> ";
+		if(m_ConsoleType)
 		{
-			if(client_state() == CLIENTSTATE_ONLINE)
+			if(Client()->State() == IClient::STATE_ONLINE)
 			{
-				if(client_rcon_authed())
-					prompt = "rcon> ";
+				if(Client()->RconAuthed())
+					pPrompt = "rcon> ";
 				else
-					prompt = "ENTER PASSWORD> ";
+					pPrompt = "ENTER PASSWORD> ";
 			}
 			else
-				prompt = "NOT CONNECTED> ";
+				pPrompt = "NOT CONNECTED> ";
 		}
 
-		gfx_text_ex(&cursor, prompt, -1);
-		
-		// render console input
-		gfx_text_ex(&cursor, console->input.get_string(), console->input.cursor_offset());
-		TEXT_CURSOR marker = cursor;
-		gfx_text_ex(&marker, "|", -1);
-		gfx_text_ex(&cursor, console->input.get_string()+console->input.cursor_offset(), -1);
+		TextRender()->TextEx(&Cursor, pPrompt, -1);
+		x = Cursor.m_X;
 		
 		// render version
-		char buf[128];
-		str_format(buf, sizeof(buf), "v%s", GAME_VERSION);
-		float version_width = gfx_text_width(0, font_size, buf, -1);
-		gfx_text(0, screen.w-version_width-5, y, font_size, buf, -1);
-
-		// render possible commands
-		if(console->input.get_string()[0] != 0)
+		char aBuf[128];
+		str_format(aBuf, sizeof(aBuf), "v%s", GAME_VERSION);
+		float VersionWidth = TextRender()->TextWidth(0, FontSize, aBuf, -1);
+		TextRender()->Text(0, Screen.w-VersionWidth-5, y, FontSize, aBuf, -1);
+
+		// render console input (wrap line)
+		int Lines = TextRender()->TextLineCount(0, FontSize, pConsole->m_Input.GetString(), Screen.w - (VersionWidth + 10 + x));
+		y -= (Lines - 1) * FontSize;
+		TextRender()->SetCursor(&Cursor, x, y, FontSize, TEXTFLAG_RENDER);
+		Cursor.m_LineWidth = Screen.w - (VersionWidth + 10 + x);
+		
+		//hide rcon password
+		char aInputString[256];
+		str_copy(aInputString, pConsole->m_Input.GetString(), sizeof(aInputString));
+		if(m_ConsoleType && Client()->State() == IClient::STATE_ONLINE && !Client()->RconAuthed())
 		{
-			console_possible_commands(console->completion_buffer, console->completion_flagmask, possible_commands_render_callback, &info);
+			for(int i = 0; i < pConsole->m_Input.GetLength(); ++i)
+				aInputString[i] = '*';
+		}
 			
-			if(info.enum_count <= 0)
+		TextRender()->TextEx(&Cursor, aInputString, pConsole->m_Input.GetCursorOffset());
+		CTextCursor Marker = Cursor;
+		TextRender()->TextEx(&Marker, "|", -1);
+		TextRender()->TextEx(&Cursor, aInputString+pConsole->m_Input.GetCursorOffset(), -1);
+		
+		// render possible commands
+		if(m_ConsoleType == 0 || Client()->RconAuthed())
+		{
+			if(pConsole->m_Input.GetString()[0] != 0)
 			{
-				if(console->command)
+				m_pConsole->PossibleCommands(pConsole->m_aCompletionBuffer, pConsole->m_CompletionFlagmask, PossibleCommandsRenderCallback, &Info);
+				
+				if(Info.m_EnumCount <= 0)
 				{
-					
-					char buf[512];
-					str_format(buf, sizeof(buf), "Help: %s ", console->command->help);
-					gfx_text_ex(&info.cursor, buf, -1);
-					gfx_text_color(0.75f, 0.75f, 0.75f, 1);
-					str_format(buf, sizeof(buf), "Syntax: %s %s", console->command->name, console->command->params);
-					gfx_text_ex(&info.cursor, buf, -1);
+					if(pConsole->m_pCommand)
+					{
+						
+						char aBuf[512];
+						str_format(aBuf, sizeof(aBuf), "Help: %s ", pConsole->m_pCommand->m_pHelp);
+						TextRender()->TextEx(&Info.m_Cursor, aBuf, -1);
+						TextRender()->TextColor(0.75f, 0.75f, 0.75f, 1);
+						str_format(aBuf, sizeof(aBuf), "Syntax: %s %s", pConsole->m_pCommand->m_pName, pConsole->m_pCommand->m_pParams);
+						TextRender()->TextEx(&Info.m_Cursor, aBuf, -1);
+					}
 				}
 			}
 		}
-		gfx_text_color(1,1,1,1);
+		TextRender()->TextColor(1,1,1,1);
 
-		// render log
-		y -= row_height;
-		char *entry = console->backlog.Last();
-		while (y > 0.0f && entry)
+		//	render log (actual page, wrap lines)
+		char *pEntry = pConsole->m_Backlog.Last();
+		for(int Page = 0, Lines = 0; Page <= pConsole->m_BacklogActPage; ++Page, Lines = 0)
 		{
-			gfx_text(0, x, y, font_size, entry, -1);
-			y -= row_height;
+			//	next page when lines reach the top
+			while(y - Lines * RowHeight > RowHeight && pEntry)
+			{
+				Lines += TextRender()->TextLineCount(0, FontSize, pEntry, Screen.w-10);
+				//	just render output from actual backlog page (render bottom up)
+				if(Page == pConsole->m_BacklogActPage)
+				{
+					TextRender()->SetCursor(&Cursor, 0, y - Lines * RowHeight, FontSize, TEXTFLAG_RENDER);
+					Cursor.m_LineWidth = Screen.w-10;
+					TextRender()->TextEx(&Cursor, pEntry, -1);
+				}
+				pEntry = pConsole->m_Backlog.Prev(pEntry);
+			}
 
-			entry = console->backlog.Prev(entry);
+			//	actual backlog page number is too high, render last available page (current checked one, render top down)
+			if(!pEntry && Page < pConsole->m_BacklogActPage)
+			{
+				pConsole->m_BacklogActPage = Page;
+				pEntry = pConsole->m_Backlog.First();
+				while(Lines > 0 && pEntry)
+				{
+					TextRender()->SetCursor(&Cursor, 0, y - Lines * RowHeight, FontSize, TEXTFLAG_RENDER);
+					Cursor.m_LineWidth = Screen.w-10;
+					Cursor.m_LineCount = 1;
+					TextRender()->TextEx(&Cursor, pEntry, -1);
+					Lines -= Cursor.m_LineCount;
+					pEntry = pConsole->m_Backlog.Next(pEntry);
+				}
+				break;
+			}
 		}
 	}	
 }
 
-void CONSOLE::on_message(int msgtype, void *rawmsg)
+void CGameConsole::OnMessage(int MsgType, void *pRawMsg)
 {
 }
 
-bool CONSOLE::on_input(INPUT_EVENT e)
+bool CGameConsole::OnInput(IInput::CEvent Event)
 {
-	if(console_state == CONSOLE_CLOSED)
+	if(m_ConsoleState == CONSOLE_CLOSED)
 		return false;
-	if(e.key >= KEY_F1 && e.key <= KEY_F15)
+	if(Event.m_Key >= KEY_F1 && Event.m_Key <= KEY_F15)
 		return false;
 
-	if(e.key == KEY_ESCAPE && (e.flags&INPFLAG_PRESS))
-		toggle(console_type);
+	if(Event.m_Key == KEY_ESCAPE && (Event.m_Flags&IInput::FLAG_PRESS))
+		Toggle(m_ConsoleType);
 	else
-		current_console()->on_input(e);
+		CurrentConsole()->OnInput(Event);
 		
 	return true;
 }
 
-void CONSOLE::toggle(int type)
+void CGameConsole::Toggle(int Type)
 {
-	if(console_type != type && (console_state == CONSOLE_OPEN || console_state == CONSOLE_OPENING))
+	if(m_ConsoleType != Type && (m_ConsoleState == CONSOLE_OPEN || m_ConsoleState == CONSOLE_OPENING))
 	{
 		// don't toggle console, just switch what console to use
 	}
 	else
 	{	
-		if (console_state == CONSOLE_CLOSED || console_state == CONSOLE_OPEN)
+		if (m_ConsoleState == CONSOLE_CLOSED || m_ConsoleState == CONSOLE_OPEN)
 		{
-			state_change_end = time_now()+state_change_duration;
+			m_StateChangeEnd = TimeNow()+m_StateChangeDuration;
 		}
 		else
 		{
-			float progress = state_change_end-time_now();
-			float reversed_progress = state_change_duration-progress;
+			float Progress = m_StateChangeEnd-TimeNow();
+			float ReversedProgress = m_StateChangeDuration-Progress;
 
-			state_change_end = time_now()+reversed_progress;
+			m_StateChangeEnd = TimeNow()+ReversedProgress;
 		}
 
-		if (console_state == CONSOLE_CLOSED || console_state == CONSOLE_CLOSING)
+		if (m_ConsoleState == CONSOLE_CLOSED || m_ConsoleState == CONSOLE_CLOSING)
 		{
-			inp_mouse_mode_absolute();
-			console_state = CONSOLE_OPENING;
+			Input()->MouseModeAbsolute();
+			m_pClient->m_pMenus->UseMouseButtons(false);
+			m_ConsoleState = CONSOLE_OPENING;
 		}
 		else
 		{
-			inp_mouse_mode_relative();
-			console_state = CONSOLE_CLOSING;
+			Input()->MouseModeRelative();
+			m_pClient->m_pMenus->UseMouseButtons(true);
+			m_ConsoleState = CONSOLE_CLOSING;
 		}
 	}
 
-	console_type = type;
+	m_ConsoleType = Type;
 }
 
-void CONSOLE::con_toggle_local_console(void *result, void *user_data)
+void CGameConsole::ConToggleLocalConsole(IConsole::IResult *pResult, void *pUserData)
 {
-	((CONSOLE *)user_data)->toggle(0);
+	((CGameConsole *)pUserData)->Toggle(0);
 }
 
-void CONSOLE::con_toggle_remote_console(void *result, void *user_data)
+void CGameConsole::ConToggleRemoteConsole(IConsole::IResult *pResult, void *pUserData)
 {
-	((CONSOLE *)user_data)->toggle(1);
+	((CGameConsole *)pUserData)->Toggle(1);
 }
 
-void CONSOLE::client_console_print_callback(const char *str, void *user_data)
+void CGameConsole::ClientConsolePrintCallback(const char *pStr, void *pUserData)
 {
-	((CONSOLE *)user_data)->local_console.print_line(str);
+	((CGameConsole *)pUserData)->m_LocalConsole.PrintLine(pStr);
 }
 
-void CONSOLE::print_line(int type, const char *line)
+void CGameConsole::PrintLine(int Type, const char *pLine)
 {
-	if(type == 0)
-		local_console.print_line(line);
-	else if(type == 1)
-		remote_console.print_line(line);
+	if(Type == 0)
+		m_LocalConsole.PrintLine(pLine);
+	else if(Type == 1)
+		m_RemoteConsole.PrintLine(pLine);
 }
 
-void CONSOLE::on_console_init()
+void CGameConsole::OnConsoleInit()
 {
+	m_pConsole = Kernel()->RequestInterface<IConsole>();
+	
 	//
-	console_register_print_callback(client_console_print_callback, this);
+	Console()->RegisterPrintCallback(ClientConsolePrintCallback, this);
 	
-	MACRO_REGISTER_COMMAND("toggle_local_console", "", CFGFLAG_CLIENT, con_toggle_local_console, this, "Toggle local console");
-	MACRO_REGISTER_COMMAND("toggle_remote_console", "", CFGFLAG_CLIENT, con_toggle_remote_console, this, "Toggle remote console");
+	Console()->Register("toggle_local_console", "", CFGFLAG_CLIENT, ConToggleLocalConsole, this, "Toggle local console");
+	Console()->Register("toggle_remote_console", "", CFGFLAG_CLIENT, ConToggleRemoteConsole, this, "Toggle remote console");
 }
 
 /*
diff --git a/src/game/client/components/console.h b/src/game/client/components/console.h
new file mode 100644
index 00000000..b88c6349
--- /dev/null
+++ b/src/game/client/components/console.h
@@ -0,0 +1,72 @@
+#ifndef GAME_CLIENT_COMPONENTS_CONSOLE_H
+#define GAME_CLIENT_COMPONENTS_CONSOLE_H
+#include <engine/shared/ringbuffer.h>
+#include <game/client/component.h>
+#include <game/client/lineinput.h>
+
+class CGameConsole : public CComponent
+{
+	class CInstance
+	{
+	public:
+		TStaticRingBuffer<char, 64*1024, CRingBufferBase::FLAG_RECYCLE> m_Backlog;
+		TStaticRingBuffer<char, 64*1024, CRingBufferBase::FLAG_RECYCLE> m_History;
+		char *m_pHistoryEntry;
+
+		CLineInput m_Input;
+		int m_Type;
+		int m_CompletionEnumerationCount;
+		int m_BacklogActPage;
+		
+	public:
+		CGameConsole *m_pGameConsole;
+		
+		char m_aCompletionBuffer[128];
+		int m_CompletionChosen;
+		int m_CompletionFlagmask;
+		
+		IConsole::CCommandInfo *m_pCommand;
+
+		CInstance(CGameConsole *pGameConsole, int t);
+
+		void ExecuteLine(const char *pLine);
+		
+		void OnInput(IInput::CEvent Event);
+		void PrintLine(const char *pLine);
+		
+		const char *GetString() const { return m_Input.GetString(); }
+		static void PossibleCommandsCompleteCallback(const char *pStr, void *pUser);
+	};
+	
+	class IConsole *m_pConsole;
+	
+	CInstance m_LocalConsole;
+	CInstance m_RemoteConsole;
+	
+	CInstance *CurrentConsole();
+	float TimeNow();
+	
+	int m_ConsoleType;
+	int m_ConsoleState;
+	float m_StateChangeEnd;
+	float m_StateChangeDuration;
+
+	void Toggle(int Type);
+
+	static void PossibleCommandsRenderCallback(const char *pStr, void *pUser);
+	static void ClientConsolePrintCallback(const char *pStr, void *pUserData);
+	static void ConToggleLocalConsole(IConsole::IResult *pResult, void *pUserData);
+	static void ConToggleRemoteConsole(IConsole::IResult *pResult, void *pUserData);
+	
+public:
+	CGameConsole();
+
+	void PrintLine(int Type, const char *pLine);
+
+	virtual void OnConsoleInit();
+	virtual void OnReset();
+	virtual void OnRender();
+	virtual void OnMessage(int MsgType, void *pRawMsg);
+	virtual bool OnInput(IInput::CEvent Events);
+};
+#endif
diff --git a/src/game/client/components/console.hpp b/src/game/client/components/console.hpp
deleted file mode 100644
index 78da98b8..00000000
--- a/src/game/client/components/console.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <engine/e_client_interface.h>
-#include <engine/e_ringbuffer.h>
-#include <game/client/component.hpp>
-#include <game/client/lineinput.hpp>
-
-class CONSOLE : public COMPONENT
-{
-	class INSTANCE
-	{
-	public:
-		TStaticRingBuffer<char, 64*1024, CRingBufferBase::FLAG_RECYCLE> backlog;
-		TStaticRingBuffer<char, 64*1024, CRingBufferBase::FLAG_RECYCLE> history;
-		char *history_entry;
-
-		LINEINPUT input;
-		
-		int type;
-		int completion_enumeration_count;
-		
-	public:
-		char completion_buffer[128];
-		int completion_chosen;
-		int completion_flagmask;
-		
-		COMMAND *command;
-
-		INSTANCE(int t);
-
-		void execute_line(const char *line);
-		
-		void on_input(INPUT_EVENT e);
-		void print_line(const char *line);
-		
-		const char *get_string() const { return input.get_string(); }
-
-		static void possible_commands_complete_callback(const char *str, void *user);
-	};
-	
-	INSTANCE local_console;
-	INSTANCE remote_console;
-	
-	INSTANCE *current_console();
-	float time_now();
-	
-	int console_type;
-	int console_state;
-	float state_change_end;
-	float state_change_duration;
-
-
-	void toggle(int type);
-
-	static void possible_commands_render_callback(const char *str, void *user);
-	static void client_console_print_callback(const char *str, void *user_data);
-	static void con_toggle_local_console(void *result, void *user_data);
-	static void con_toggle_remote_console(void *result, void *user_data);
-	
-public:
-	CONSOLE();
-
-	void print_line(int type, const char *line);
-
-	virtual void on_console_init();
-	virtual void on_reset();
-	virtual void on_render();
-	virtual void on_message(int msgtype, void *rawmsg);
-	virtual bool on_input(INPUT_EVENT e);
-};
diff --git a/src/game/client/components/controls.cpp b/src/game/client/components/controls.cpp
index b48fb198..714f8b0c 100644
--- a/src/game/client/components/controls.cpp
+++ b/src/game/client/components/controls.cpp
@@ -1,210 +1,215 @@
-#include <engine/e_client_interface.h>
-#include <base/math.hpp>
-#include <game/collision.hpp>
-#include <game/client/gameclient.hpp>
-#include <game/client/component.hpp>
-#include <game/client/components/chat.hpp>
-#include <game/client/components/menus.hpp>
+#include <base/math.h>
 
-#include "controls.hpp"
+#include <engine/shared/config.h>
 
-CONTROLS::CONTROLS()
+#include <game/collision.h>
+#include <game/client/gameclient.h>
+#include <game/client/component.h>
+#include <game/client/components/chat.h>
+#include <game/client/components/menus.h>
+
+#include "controls.h"
+
+CControls::CControls()
 {
 }
 
-static void con_key_input_state(void *result, void *user_data)
+static void ConKeyInputState(IConsole::IResult *pResult, void *pUserData)
 {
-	((int *)user_data)[0] = console_arg_int(result, 0);
+	((int *)pUserData)[0] = pResult->GetInteger(0);
 }
 
-static void con_key_input_counter(void *result, void *user_data)
+static void ConKeyInputCounter(IConsole::IResult *pResult, void *pUserData)
 {
-	int *v = (int *)user_data;
-	if(((*v)&1) != console_arg_int(result, 0))
+	int *v = (int *)pUserData;
+	if(((*v)&1) != pResult->GetInteger(0))
 		(*v)++;
 	*v &= INPUT_STATE_MASK;
 }
 
-struct INPUTSET
+struct CInputSet
 {
-	CONTROLS *controls;
-	int *variable;
-	int value;
+	CControls *m_pControls;
+	int *m_pVariable;
+	int m_Value;
 };
 
-static void con_key_input_set(void *result, void *user_data)
+static void ConKeyInputSet(IConsole::IResult *pResult, void *pUserData)
 {
-	INPUTSET *set = (INPUTSET *)user_data;
-	if(console_arg_int(result, 0))
-		*set->variable = set->value;
+	CInputSet *pSet = (CInputSet *)pUserData;
+	if(pResult->GetInteger(0))
+		*pSet->m_pVariable = pSet->m_Value;
 }
 
-static void con_key_input_nextprev_weapon(void *result, void *user_data)
+static void ConKeyInputNextPrevWeapon(IConsole::IResult *pResult, void *pUserData)
 {
-	INPUTSET *set = (INPUTSET *)user_data;
-	con_key_input_counter(result, set->variable);
-	set->controls->input_data.wanted_weapon = 0;
+	CInputSet *pSet = (CInputSet *)pUserData;
+	ConKeyInputCounter(pResult, pSet->m_pVariable);
+	pSet->m_pControls->m_InputData.m_WantedWeapon = 0;
 }
 
-void CONTROLS::on_console_init()
+void CControls::OnConsoleInit()
 {
 	// game commands
-	MACRO_REGISTER_COMMAND("+left", "", CFGFLAG_CLIENT, con_key_input_state, &input_direction_left, "Move left");
-	MACRO_REGISTER_COMMAND("+right", "", CFGFLAG_CLIENT, con_key_input_state, &input_direction_right, "Move right");
-	MACRO_REGISTER_COMMAND("+jump", "", CFGFLAG_CLIENT, con_key_input_state, &input_data.jump, "Jump");
-	MACRO_REGISTER_COMMAND("+hook", "", CFGFLAG_CLIENT, con_key_input_state, &input_data.hook, "Hook");
-	MACRO_REGISTER_COMMAND("+fire", "", CFGFLAG_CLIENT, con_key_input_counter, &input_data.fire, "Fire");
-
-	{ static INPUTSET set = {this, &input_data.wanted_weapon, 1};  MACRO_REGISTER_COMMAND("+weapon1", "", CFGFLAG_CLIENT, con_key_input_set, (void *)&set, "Switch to hammer"); }
-	{ static INPUTSET set = {this, &input_data.wanted_weapon, 2};  MACRO_REGISTER_COMMAND("+weapon2", "", CFGFLAG_CLIENT, con_key_input_set, (void *)&set, "Switch to gun"); }
-	{ static INPUTSET set = {this, &input_data.wanted_weapon, 3};  MACRO_REGISTER_COMMAND("+weapon3", "", CFGFLAG_CLIENT, con_key_input_set, (void *)&set, "Switch to shotgun"); }
-	{ static INPUTSET set = {this, &input_data.wanted_weapon, 4};  MACRO_REGISTER_COMMAND("+weapon4", "", CFGFLAG_CLIENT, con_key_input_set, (void *)&set, "Switch to grenade"); }
-	{ static INPUTSET set = {this, &input_data.wanted_weapon, 5};  MACRO_REGISTER_COMMAND("+weapon5", "", CFGFLAG_CLIENT, con_key_input_set, (void *)&set, "Switch to rifle"); }
-
-	{ static INPUTSET set = {this, &input_data.next_weapon, 0};  MACRO_REGISTER_COMMAND("+nextweapon", "", CFGFLAG_CLIENT, con_key_input_nextprev_weapon, (void *)&set, "Switch to next weapon"); }
-	{ static INPUTSET set = {this, &input_data.prev_weapon, 0};  MACRO_REGISTER_COMMAND("+prevweapon", "", CFGFLAG_CLIENT, con_key_input_nextprev_weapon, (void *)&set, "Switch to previous weapon"); }
+	Console()->Register("+left", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputDirectionLeft, "Move left");
+	Console()->Register("+right", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputDirectionRight, "Move right");
+	Console()->Register("+jump", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputData.m_Jump, "Jump");
+	Console()->Register("+hook", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputData.m_Hook, "Hook");
+	Console()->Register("+fire", "", CFGFLAG_CLIENT, ConKeyInputCounter, &m_InputData.m_Fire, "Fire");
+
+	{ static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 1};  Console()->Register("+weapon1", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to hammer"); }
+	{ static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 2};  Console()->Register("+weapon2", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to gun"); }
+	{ static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 3};  Console()->Register("+weapon3", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to shotgun"); }
+	{ static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 4};  Console()->Register("+weapon4", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to grenade"); }
+	{ static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 5};  Console()->Register("+weapon5", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to rifle"); }
+
+	{ static CInputSet s_Set = {this, &m_InputData.m_NextWeapon, 0};  Console()->Register("+nextweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to next weapon"); }
+	{ static CInputSet s_Set = {this, &m_InputData.m_PrevWeapon, 0};  Console()->Register("+prevweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to previous weapon"); }
 }
 
-void CONTROLS::on_message(int msg, void *rawmsg)
+void CControls::OnMessage(int Msg, void *pRawMsg)
 {
-    if(msg == NETMSGTYPE_SV_WEAPONPICKUP)
+    if(Msg == NETMSGTYPE_SV_WEAPONPICKUP)
     {
-    	NETMSG_SV_WEAPONPICKUP *msg = (NETMSG_SV_WEAPONPICKUP *)rawmsg;
-        if(config.cl_autoswitch_weapons)
-        	input_data.wanted_weapon = msg->weapon+1;
+    	CNetMsg_Sv_WeaponPickup *pMsg = (CNetMsg_Sv_WeaponPickup *)pRawMsg;
+        if(g_Config.m_ClAutoswitchWeapons)
+        	m_InputData.m_WantedWeapon = pMsg->m_Weapon+1;
     }
 }
 
-int CONTROLS::snapinput(int *data)
+int CControls::SnapInput(int *pData)
 {
-	static NETOBJ_PLAYER_INPUT last_data = {0};
-	static int64 last_send_time = 0;
-	bool send = false;
+	static CNetObj_PlayerInput LastData = {0};
+	static int64 LastSendTime = 0;
+	bool Send = false;
 	
 	// update player state
-	if(gameclient.chat->is_active())
-		input_data.player_state = PLAYERSTATE_CHATTING;
-	else if(gameclient.menus->is_active())
-		input_data.player_state = PLAYERSTATE_IN_MENU;
+	if(m_pClient->m_pChat->IsActive())
+		m_InputData.m_PlayerState = PLAYERSTATE_CHATTING;
+	else if(m_pClient->m_pMenus->IsActive())
+		m_InputData.m_PlayerState = PLAYERSTATE_IN_MENU;
 	else
-		input_data.player_state = PLAYERSTATE_PLAYING;
+		m_InputData.m_PlayerState = PLAYERSTATE_PLAYING;
 	
-	if(last_data.player_state != input_data.player_state)
-		send = true;
+	if(LastData.m_PlayerState != m_InputData.m_PlayerState)
+		Send = true;
 		
-	last_data.player_state = input_data.player_state;
+	LastData.m_PlayerState = m_InputData.m_PlayerState;
 	
 	// we freeze the input if chat or menu is activated
-	if(input_data.player_state != PLAYERSTATE_PLAYING)
+	if(m_InputData.m_PlayerState != PLAYERSTATE_PLAYING)
 	{
-		last_data.direction = 0;
-		last_data.hook = 0;
-		last_data.jump = 0;
-		input_data = last_data;
+		LastData.m_Direction = 0;
+		LastData.m_Hook = 0;
+		LastData.m_Jump = 0;
+		m_InputData = LastData;
 		
-		input_direction_left = 0;
-		input_direction_right = 0;
+		m_InputDirectionLeft = 0;
+		m_InputDirectionRight = 0;
 			
-		mem_copy(data, &input_data, sizeof(input_data));
+		mem_copy(pData, &m_InputData, sizeof(m_InputData));
 
 		// send once a second just to be sure
-		if(time_get() > last_send_time + time_freq())
-			send = true;
+		if(time_get() > LastSendTime + time_freq())
+			Send = true;
 	}
 	else
 	{
 		
-		input_data.target_x = (int)mouse_pos.x;
-		input_data.target_y = (int)mouse_pos.y;
-		if(!input_data.target_x && !input_data.target_y)
-			input_data.target_y = 1;
+		m_InputData.m_TargetX = (int)m_MousePos.x;
+		m_InputData.m_TargetY = (int)m_MousePos.y;
+		if(!m_InputData.m_TargetX && !m_InputData.m_TargetY)
+		{
+			m_InputData.m_TargetX = 1;
+			m_MousePos.x = 1;
+		}
 			
 		// set direction
-		input_data.direction = 0;
-		if(input_direction_left && !input_direction_right)
-			input_data.direction = -1;
-		if(!input_direction_left && input_direction_right)
-			input_data.direction = 1;
+		m_InputData.m_Direction = 0;
+		if(m_InputDirectionLeft && !m_InputDirectionRight)
+			m_InputData.m_Direction = -1;
+		if(!m_InputDirectionLeft && m_InputDirectionRight)
+			m_InputData.m_Direction = 1;
 
 		// stress testing
-		if(config.dbg_stress)
+		if(g_Config.m_DbgStress)
 		{
-			float t = client_localtime();
-			mem_zero(&input_data, sizeof(input_data));
-
-			input_data.direction = ((int)t/2)&1;
-			input_data.jump = ((int)t);
-			input_data.fire = ((int)(t*10));
-			input_data.hook = ((int)(t*2))&1;
-			input_data.wanted_weapon = ((int)t)%NUM_WEAPONS;
-			input_data.target_x = (int)(sinf(t*3)*100.0f);
-			input_data.target_y = (int)(cosf(t*3)*100.0f);
+			float t = Client()->LocalTime();
+			mem_zero(&m_InputData, sizeof(m_InputData));
+
+			m_InputData.m_Direction = ((int)t/2)&1;
+			m_InputData.m_Jump = ((int)t);
+			m_InputData.m_Fire = ((int)(t*10));
+			m_InputData.m_Hook = ((int)(t*2))&1;
+			m_InputData.m_WantedWeapon = ((int)t)%NUM_WEAPONS;
+			m_InputData.m_TargetX = (int)(sinf(t*3)*100.0f);
+			m_InputData.m_TargetY = (int)(cosf(t*3)*100.0f);
 		}
 
 		// check if we need to send input
-		if(input_data.direction != last_data.direction) send = true;
-		else if(input_data.jump != last_data.jump) send = true;
-		else if(input_data.fire != last_data.fire) send = true;
-		else if(input_data.hook != last_data.hook) send = true;
-		else if(input_data.player_state != last_data.player_state) send = true;
-		else if(input_data.wanted_weapon != last_data.wanted_weapon) send = true;
-		else if(input_data.next_weapon != last_data.next_weapon) send = true;
-		else if(input_data.prev_weapon != last_data.prev_weapon) send = true;
+		if(m_InputData.m_Direction != LastData.m_Direction) Send = true;
+		else if(m_InputData.m_Jump != LastData.m_Jump) Send = true;
+		else if(m_InputData.m_Fire != LastData.m_Fire) Send = true;
+		else if(m_InputData.m_Hook != LastData.m_Hook) Send = true;
+		else if(m_InputData.m_PlayerState != LastData.m_PlayerState) Send = true;
+		else if(m_InputData.m_WantedWeapon != LastData.m_WantedWeapon) Send = true;
+		else if(m_InputData.m_NextWeapon != LastData.m_NextWeapon) Send = true;
+		else if(m_InputData.m_PrevWeapon != LastData.m_PrevWeapon) Send = true;
 
 		// send at at least 10hz
-		if(time_get() > last_send_time + time_freq()/25)
-			send = true;
+		if(time_get() > LastSendTime + time_freq()/25)
+			Send = true;
 	}
 	
 	// copy and return size	
-	last_data = input_data;
+	LastData = m_InputData;
 	
-	if(!send)
+	if(!Send)
 		return 0;
 		
-	last_send_time = time_get();
-	mem_copy(data, &input_data, sizeof(input_data));
-	return sizeof(input_data);	
+	LastSendTime = time_get();
+	mem_copy(pData, &m_InputData, sizeof(m_InputData));
+	return sizeof(m_InputData);	
 }
 
-void CONTROLS::on_render()
+void CControls::OnRender()
 {
 	// update target pos
-	if(gameclient.snap.gameobj && !(gameclient.snap.gameobj->paused || gameclient.snap.spectate))
-		target_pos = gameclient.local_character_pos + mouse_pos;
+	if(m_pClient->m_Snap.m_pGameobj && !(m_pClient->m_Snap.m_pGameobj->m_Paused || m_pClient->m_Snap.m_Spectate))
+		m_TargetPos = m_pClient->m_LocalCharacterPos + m_MousePos;
 }
 
-bool CONTROLS::on_mousemove(float x, float y)
+bool CControls::OnMouseMove(float x, float y)
 {
-	if(gameclient.snap.gameobj && gameclient.snap.gameobj->paused)
+	if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Paused)
 		return false;
-	mouse_pos += vec2(x, y); // TODO: ugly
+	m_MousePos += vec2(x, y); // TODO: ugly
 
 	//
-	float camera_max_distance = 200.0f;
-	float follow_factor = config.cl_mouse_followfactor/100.0f;
-	float deadzone = config.cl_mouse_deadzone;
-	float mouse_max = min(camera_max_distance/follow_factor + deadzone, (float)config.cl_mouse_max_distance);
+	float CameraMaxDistance = 200.0f;
+	float FollowFactor = g_Config.m_ClMouseFollowfactor/100.0f;
+	float DeadZone = g_Config.m_ClMouseDeadzone;
+	float MouseMax = min(CameraMaxDistance/FollowFactor + DeadZone, (float)g_Config.m_ClMouseMaxDistance);
 	
 	//vec2 camera_offset(0, 0);
 
-	if(gameclient.snap.spectate)
+	if(m_pClient->m_Snap.m_Spectate)
 	{
-		if(mouse_pos.x < 200.0f) mouse_pos.x = 200.0f;
-		if(mouse_pos.y < 200.0f) mouse_pos.y = 200.0f;
-		if(mouse_pos.x > col_width()*32-200.0f) mouse_pos.x = col_width()*32-200.0f;
-		if(mouse_pos.y > col_height()*32-200.0f) mouse_pos.y = col_height()*32-200.0f;
+		if(m_MousePos.x < 200.0f) m_MousePos.x = 200.0f;
+		if(m_MousePos.y < 200.0f) m_MousePos.y = 200.0f;
+		if(m_MousePos.x > Collision()->GetWidth()*32-200.0f) m_MousePos.x = Collision()->GetWidth()*32-200.0f;
+		if(m_MousePos.y > Collision()->GetHeight()*32-200.0f) m_MousePos.y = Collision()->GetHeight()*32-200.0f;
 		
-		target_pos = mouse_pos;
+		m_TargetPos = m_MousePos;
 	}
 	else
 	{
-		float l = length(mouse_pos);
+		float l = length(m_MousePos);
 		
-		if(l > mouse_max)
+		if(l > MouseMax)
 		{
-			mouse_pos = normalize(mouse_pos)*mouse_max;
-			l = mouse_max;
+			m_MousePos = normalize(m_MousePos)*MouseMax;
+			l = MouseMax;
 		}
 		
 		//float offset_amount = max(l-deadzone, 0.0f) * follow_factor;
diff --git a/src/game/client/components/controls.h b/src/game/client/components/controls.h
new file mode 100644
index 00000000..7453d5d7
--- /dev/null
+++ b/src/game/client/components/controls.h
@@ -0,0 +1,25 @@
+#ifndef GAME_CLIENT_COMPONENTS_CONTROLS_H
+#define GAME_CLIENT_COMPONENTS_CONTROLS_H
+#include <base/vmath.h>
+#include <game/client/component.h>
+
+class CControls : public CComponent
+{	
+public:
+	vec2 m_MousePos;
+	vec2 m_TargetPos;
+
+	CNetObj_PlayerInput m_InputData;
+	int m_InputDirectionLeft;
+	int m_InputDirectionRight;
+
+	CControls();
+	
+	virtual void OnRender();
+	virtual void OnMessage(int MsgType, void *pRawMsg);
+	virtual bool OnMouseMove(float x, float y);
+	virtual void OnConsoleInit();
+	
+	int SnapInput(int *pData);
+};
+#endif
diff --git a/src/game/client/components/controls.hpp b/src/game/client/components/controls.hpp
deleted file mode 100644
index e33d24f5..00000000
--- a/src/game/client/components/controls.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <base/vmath.hpp>
-#include <game/client/component.hpp>
-
-class CONTROLS : public COMPONENT
-{	
-public:
-	vec2 mouse_pos;
-	vec2 target_pos;
-
-	NETOBJ_PLAYER_INPUT input_data;
-	int input_direction_left;
-	int input_direction_right;
-
-	CONTROLS();
-	
-	virtual void on_render();
-	virtual void on_message(int msg, void *rawmsg);
-	virtual bool on_mousemove(float x, float y);
-	virtual void on_console_init();
-	
-	int snapinput(int *data);
-};
diff --git a/src/game/client/components/damageind.cpp b/src/game/client/components/damageind.cpp
index 7f1991dc..8dfbf022 100644
--- a/src/game/client/components/damageind.cpp
+++ b/src/game/client/components/damageind.cpp
@@ -1,65 +1,64 @@
-#include <engine/e_client_interface.h>
-#include <engine/client/graphics.h>
-#include <game/generated/g_protocol.hpp>
-#include <game/generated/gc_data.hpp>
+#include <engine/graphics.h>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
 
-#include <game/gamecore.hpp> // get_angle
-#include <game/client/ui.hpp>
-#include <game/client/render.hpp>
-#include "damageind.hpp"
+#include <game/gamecore.h> // get_angle
+#include <game/client/ui.h>
+#include <game/client/render.h>
+#include "damageind.h"
 
-DAMAGEIND::DAMAGEIND()
+CDamageInd::CDamageInd()
 {
-	lastupdate = 0;
-	num_items = 0;
+	m_Lastupdate = 0;
+	m_NumItems = 0;
 }
 
-DAMAGEIND::ITEM *DAMAGEIND::create_i()
+CDamageInd::CItem *CDamageInd::CreateI()
 {
-	if (num_items < MAX_ITEMS)
+	if (m_NumItems < MAX_ITEMS)
 	{
-		ITEM *p = &items[num_items];
-		num_items++;
+		CItem *p = &m_aItems[m_NumItems];
+		m_NumItems++;
 		return p;
 	}
 	return 0;
 }
 
-void DAMAGEIND::destroy_i(DAMAGEIND::ITEM *i)
+void CDamageInd::DestroyI(CDamageInd::CItem *i)
 {
-	num_items--;
-	*i = items[num_items];
+	m_NumItems--;
+	*i = m_aItems[m_NumItems];
 }
 
-void DAMAGEIND::create(vec2 pos, vec2 dir)
+void CDamageInd::Create(vec2 Pos, vec2 Dir)
 {
-	ITEM *i = create_i();
+	CItem *i = CreateI();
 	if (i)
 	{
-		i->pos = pos;
-		i->life = 0.75f;
-		i->dir = dir*-1;
-		i->startangle = (( (float)rand()/(float)RAND_MAX) - 1.0f) * 2.0f * pi;
+		i->m_Pos = Pos;
+		i->m_Life = 0.75f;
+		i->m_Dir = Dir*-1;
+		i->m_StartAngle = (( (float)rand()/(float)RAND_MAX) - 1.0f) * 2.0f * pi;
 	}
 }
 
-void DAMAGEIND::on_render()
+void CDamageInd::OnRender()
 {
-	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 	Graphics()->QuadsBegin();
-	for(int i = 0; i < num_items;)
+	for(int i = 0; i < m_NumItems;)
 	{
-		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));
+		vec2 Pos = mix(m_aItems[i].m_Pos+m_aItems[i].m_Dir*75.0f, m_aItems[i].m_Pos, clamp((m_aItems[i].m_Life-0.60f)/0.15f, 0.0f, 1.0f));
 
-		items[i].life -= client_frametime();
-		if(items[i].life < 0.0f)
-			destroy_i(&items[i]);
+		m_aItems[i].m_Life -= Client()->FrameTime();
+		if(m_aItems[i].m_Life < 0.0f)
+			DestroyI(&m_aItems[i]);
 		else
 		{
-			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);
+			Graphics()->SetColor(1.0f,1.0f,1.0f, m_aItems[i].m_Life/0.1f);
+			Graphics()->QuadsSetRotation(m_aItems[i].m_StartAngle + m_aItems[i].m_Life * 2.0f);
+			RenderTools()->SelectSprite(SPRITE_STAR1);
+			RenderTools()->DrawSprite(Pos.x, Pos.y, 48.0f);
 			i++;
 		}
 	}
diff --git a/src/game/client/components/damageind.h b/src/game/client/components/damageind.h
new file mode 100644
index 00000000..b6e0bb47
--- /dev/null
+++ b/src/game/client/components/damageind.h
@@ -0,0 +1,34 @@
+#ifndef GAME_CLIENT_COMPONENTS_DAMAGEIND_H
+#define GAME_CLIENT_COMPONENTS_DAMAGEIND_H
+#include <base/vmath.h>
+#include <game/client/component.h>
+
+class CDamageInd : public CComponent
+{
+	int64 m_Lastupdate;
+	struct CItem
+	{
+		vec2 m_Pos;
+		vec2 m_Dir;
+		float m_Life;
+		float m_StartAngle;
+	};
+
+	enum
+	{
+		MAX_ITEMS=64,
+	};
+
+	CItem m_aItems[MAX_ITEMS];
+	int m_NumItems;
+
+	CItem *CreateI();
+	void DestroyI(CItem *i);
+
+public:	
+	CDamageInd();
+
+	void Create(vec2 Pos, vec2 Dir);
+	virtual void OnRender();
+};
+#endif
diff --git a/src/game/client/components/damageind.hpp b/src/game/client/components/damageind.hpp
deleted file mode 100644
index c74af9ca..00000000
--- a/src/game/client/components/damageind.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <base/vmath.hpp>
-#include <game/client/component.hpp>
-
-class DAMAGEIND : public COMPONENT
-{
-	int64 lastupdate;
-	struct ITEM
-	{
-		vec2 pos;
-		vec2 dir;
-		float life;
-		float startangle;
-	};
-
-	enum
-	{
-		MAX_ITEMS=64,
-	};
-
-	ITEM items[MAX_ITEMS];
-	int num_items;
-
-	ITEM *create_i();
-	void destroy_i(ITEM *i);
-
-public:	
-	DAMAGEIND();
-
-	void create(vec2 pos, vec2 dir);
-	virtual void on_render();
-};
diff --git a/src/game/client/components/debughud.cpp b/src/game/client/components/debughud.cpp
index c7cc559b..0fa004cb 100644
--- a/src/game/client/components/debughud.cpp
+++ b/src/game/client/components/debughud.cpp
@@ -1,27 +1,23 @@
-#include <memory.h> // memcmp
+#include <engine/shared/config.h>
+#include <engine/graphics.h>
+#include <engine/textrender.h>
 
-extern "C" {
-	#include <engine/e_config.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/generated/protocol.h>
+#include <game/generated/client_data.h>
 
-#include <game/layers.hpp>
+#include <game/layers.h>
 
-#include <game/client/gameclient.hpp>
-#include <game/client/animstate.hpp>
-#include <game/client/render.hpp>
+#include <game/client/gameclient.h>
+#include <game/client/animstate.h>
+#include <game/client/render.h>
 
-//#include "controls.hpp"
-//#include "camera.hpp"
-#include "debughud.hpp"
+//#include "controls.h"
+//#include "camera.h"
+#include "debughud.h"
 
-void DEBUGHUD::render_netcorrections()
+void CDebugHud::RenderNetCorrections()
 {
-	if(!config.debug || !gameclient.snap.local_character || !gameclient.snap.local_prev_character)
+	if(!g_Config.m_Debug || !m_pClient->m_Snap.m_pLocalCharacter || !m_pClient->m_Snap.m_pLocalPrevCharacter)
 		return;
 
 	Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300);
@@ -29,7 +25,8 @@ void DEBUGHUD::render_netcorrections()
 	/*float speed = distance(vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y),
 		vec2(netobjects.local_character->x, netobjects.local_character->y));*/
 
-	float velspeed = length(vec2(gameclient.snap.local_character->vx/256.0f, gameclient.snap.local_character->vy/256.0f))*50;
+/*
+	float velspeed = length(vec2(gameclient.snap.local_character->m_VelX/256.0f, gameclient.snap.local_character->m_VelY/256.0f))*50;
 	
 	float ramp = velocity_ramp(velspeed, gameclient.tuning.velramp_start, gameclient.tuning.velramp_range, gameclient.tuning.velramp_curvature);
 	
@@ -37,77 +34,79 @@ void DEBUGHUD::render_netcorrections()
 	str_format(buf, sizeof(buf), "%.0f\n%.0f\n%.2f\n%d %s\n%d %d",
 		velspeed, velspeed*ramp, ramp,
 		netobj_num_corrections(), netobj_corrected_on(),
-		gameclient.snap.local_character->x,
-		gameclient.snap.local_character->y
+		gameclient.snap.local_character->m_X,
+		gameclient.snap.local_character->m_Y
 	);
-	gfx_text(0, 150, 50, 12, buf, -1);
+	TextRender()->Text(0, 150, 50, 12, buf, -1);*/
 }
 
-void DEBUGHUD::render_tuning()
+void CDebugHud::RenderTuning()
 {
 	// render tuning debugging
-	if(!config.dbg_tuning)
+	if(!g_Config.m_DbgTuning)
 		return;
 		
-	TUNING_PARAMS standard_tuning;
+	CTuningParams StandardTuning;
 		
 	Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300);
 	
 	float y = 50.0f;
-	int count = 0;
-	for(int i = 0; i < gameclient.tuning.num(); i++)
+	int Count = 0;
+	for(int i = 0; i < m_pClient->m_Tuning.Num(); i++)
 	{
-		char buf[128];
-		float current, standard;
-		gameclient.tuning.get(i, &current);
-		standard_tuning.get(i, &standard);
+		char aBuf[128];
+		float Current, Standard;
+		m_pClient->m_Tuning.Get(i, &Current);
+		StandardTuning.Get(i, &Standard);
 		
-		if(standard == current)
-			gfx_text_color(1,1,1,1.0f);
+		if(Standard == Current)
+			TextRender()->TextColor(1,1,1,1.0f);
 		else
-			gfx_text_color(1,0.25f,0.25f,1.0f);
+			TextRender()->TextColor(1,0.25f,0.25f,1.0f);
 
 		float w;
 		float x = 5.0f;
 		
-		str_format(buf, sizeof(buf), "%.2f", standard);
+		str_format(aBuf, sizeof(aBuf), "%.2f", Standard);
 		x += 20.0f;
-		w = gfx_text_width(0, 5, buf, -1);
-		gfx_text(0x0, x-w, y+count*6, 5, buf, -1);
+		w = TextRender()->TextWidth(0, 5, aBuf, -1);
+		TextRender()->Text(0x0, x-w, y+Count*6, 5, aBuf, -1);
 
-		str_format(buf, sizeof(buf), "%.2f", current);
+		str_format(aBuf, sizeof(aBuf), "%.2f", Current);
 		x += 20.0f;
-		w = gfx_text_width(0, 5, buf, -1);
-		gfx_text(0x0, x-w, y+count*6, 5, buf, -1);
+		w = TextRender()->TextWidth(0, 5, aBuf, -1);
+		TextRender()->Text(0x0, x-w, y+Count*6, 5, aBuf, -1);
 
 		x += 5.0f;
-		gfx_text(0x0, x, y+count*6, 5, gameclient.tuning.names[i], -1);
+		TextRender()->Text(0x0, x, y+Count*6, 5, m_pClient->m_Tuning.m_apNames[i], -1);
 		
-		count++;
+		Count++;
 	}
 	
-	y = y+count*6;
+	y = y+Count*6;
 	
 	Graphics()->TextureSet(-1);
 	Graphics()->BlendNormal();
 	Graphics()->LinesBegin();
-	float height = 50.0f;
+	float Height = 50.0f;
 	float pv = 1;
+	IGraphics::CLineItem Array[100];
 	for(int i = 0; i < 100; i++)
 	{
-		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;
-		Graphics()->LinesDraw((i-1)*2, y+height-pv*height, i*2, y+height-rampedspeed*height);
+		float Speed = i/100.0f * 3000;
+		float Ramp = VelocityRamp(Speed, m_pClient->m_Tuning.m_VelrampStart, m_pClient->m_Tuning.m_VelrampRange, m_pClient->m_Tuning.m_VelrampCurvature);
+		float RampedSpeed = (Speed * Ramp)/1000.0f;
+		Array[i] = IGraphics::CLineItem((i-1)*2, y+Height-pv*Height, i*2, y+Height-RampedSpeed*Height);
 		//Graphics()->LinesDraw((i-1)*2, 200, i*2, 200);
-		pv = rampedspeed;
+		pv = RampedSpeed;
 	}
+	Graphics()->LinesDraw(Array, 100);
 	Graphics()->LinesEnd();
-	gfx_text_color(1,1,1,1);
+	TextRender()->TextColor(1,1,1,1);
 }
 
-void DEBUGHUD::on_render()
+void CDebugHud::OnRender()
 {
-	render_tuning();
-	render_netcorrections();
+	RenderTuning();
+	RenderNetCorrections();
 }
diff --git a/src/game/client/components/debughud.h b/src/game/client/components/debughud.h
new file mode 100644
index 00000000..ae1c17ef
--- /dev/null
+++ b/src/game/client/components/debughud.h
@@ -0,0 +1,13 @@
+#ifndef GAME_CLIENT_COMPONENTS_DEBUGHUD_H
+#define GAME_CLIENT_COMPONENTS_DEBUGHUD_H
+#include <game/client/component.h>
+
+class CDebugHud : public CComponent
+{	
+	void RenderNetCorrections();
+	void RenderTuning();
+public:
+	virtual void OnRender();
+};
+
+#endif
diff --git a/src/game/client/components/debughud.hpp b/src/game/client/components/debughud.hpp
deleted file mode 100644
index 473b2ce2..00000000
--- a/src/game/client/components/debughud.hpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <game/client/component.hpp>
-
-class DEBUGHUD : public COMPONENT
-{	
-	void render_netcorrections();
-	void render_tuning();
-public:
-	virtual void on_render();
-};
-
diff --git a/src/game/client/components/effects.cpp b/src/game/client/components/effects.cpp
index c9c47a8d..91cea107 100644
--- a/src/game/client/components/effects.cpp
+++ b/src/game/client/components/effects.cpp
@@ -1,183 +1,181 @@
-#include <engine/e_client_interface.h>
-//#include <gc_client.hpp>
-#include <game/generated/gc_data.hpp>
+#include <game/generated/client_data.h>
 
-#include <game/client/components/particles.hpp>
-#include <game/client/components/skins.hpp>
-#include <game/client/components/flow.hpp>
-#include <game/client/components/damageind.hpp>
-#include <game/client/components/sounds.hpp>
-#include <game/client/gameclient.hpp>
+#include <game/client/components/particles.h>
+#include <game/client/components/skins.h>
+#include <game/client/components/flow.h>
+#include <game/client/components/damageind.h>
+#include <game/client/components/sounds.h>
+#include <game/client/gameclient.h>
 
-#include "effects.hpp"
+#include "effects.h"
 
-inline vec2 random_dir() { return normalize(vec2(frandom()-0.5f, frandom()-0.5f)); }
+inline vec2 RandomDir() { return normalize(vec2(frandom()-0.5f, frandom()-0.5f)); }
 
-EFFECTS::EFFECTS()
+CEffects::CEffects()
 {
-	add_50hz = false;
-	add_100hz = false;
+	m_Add50hz = false;
+	m_Add100hz = false;
 }
 
-void EFFECTS::air_jump(vec2 pos)
+void CEffects::AirJump(vec2 Pos)
 {
-	PARTICLE p;
-	p.set_default();
-	p.spr = SPRITE_PART_AIRJUMP;
-	p.pos = pos + vec2(-6.0f, 16.0f);
-	p.vel = vec2(0, -200);
-	p.life_span = 0.5f;
-	p.start_size = 48.0f;
-	p.end_size = 0;
-	p.rot = frandom()*pi*2;
-	p.rotspeed = pi*2;
-	p.gravity = 500;
-	p.friction = 0.7f;
-	p.flow_affected = 0.0f;
-	gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p);
+	CParticle p;
+	p.SetDefault();
+	p.m_Spr = SPRITE_PART_AIRJUMP;
+	p.m_Pos = Pos + vec2(-6.0f, 16.0f);
+	p.m_Vel = vec2(0, -200);
+	p.m_LifeSpan = 0.5f;
+	p.m_StartSize = 48.0f;
+	p.m_EndSize = 0;
+	p.m_Rot = frandom()*pi*2;
+	p.m_Rotspeed = pi*2;
+	p.m_Gravity = 500;
+	p.m_Friction = 0.7f;
+	p.m_FlowAffected = 0.0f;
+	m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p);
 
-	p.pos = pos + vec2(6.0f, 16.0f);
-	gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p);
+	p.m_Pos = Pos + vec2(6.0f, 16.0f);
+	m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p);
 	
-	gameclient.sounds->play(SOUNDS::CHN_WORLD, SOUND_PLAYER_AIRJUMP, 1.0f, pos);
+	m_pClient->m_pSounds->Play(CSounds::CHN_WORLD, SOUND_PLAYER_AIRJUMP, 1.0f, Pos);
 }
 
-void EFFECTS::damage_indicator(vec2 pos, vec2 dir)
+void CEffects::DamageIndicator(vec2 Pos, vec2 Dir)
 {
-	gameclient.damageind->create(pos, dir);
+	m_pClient->m_pDamageind->Create(Pos, Dir);
 }
 
-void EFFECTS::powerupshine(vec2 pos, vec2 size)
+void CEffects::PowerupShine(vec2 Pos, vec2 size)
 {
-	if(!add_50hz)
+	if(!m_Add50hz)
 		return;
 		
-	PARTICLE p;
-	p.set_default();
-	p.spr = SPRITE_PART_SLICE;
-	p.pos = pos + vec2((frandom()-0.5f)*size.x, (frandom()-0.5f)*size.y);
-	p.vel = vec2(0, 0);
-	p.life_span = 0.5f;
-	p.start_size = 16.0f;
-	p.end_size = 0;
-	p.rot = frandom()*pi*2;
-	p.rotspeed = pi*2;
-	p.gravity = 500;
-	p.friction = 0.9f;
-	p.flow_affected = 0.0f;
-	gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p);
+	CParticle p;
+	p.SetDefault();
+	p.m_Spr = SPRITE_PART_SLICE;
+	p.m_Pos = Pos + vec2((frandom()-0.5f)*size.x, (frandom()-0.5f)*size.y);
+	p.m_Vel = vec2(0, 0);
+	p.m_LifeSpan = 0.5f;
+	p.m_StartSize = 16.0f;
+	p.m_EndSize = 0;
+	p.m_Rot = frandom()*pi*2;
+	p.m_Rotspeed = pi*2;
+	p.m_Gravity = 500;
+	p.m_Friction = 0.9f;
+	p.m_FlowAffected = 0.0f;
+	m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p);
 }
 
-void EFFECTS::smoketrail(vec2 pos, vec2 vel)
+void CEffects::SmokeTrail(vec2 Pos, vec2 Vel)
 {
-	if(!add_50hz)
+	if(!m_Add50hz)
 		return;
 		
-	PARTICLE p;
-	p.set_default();
-	p.spr = SPRITE_PART_SMOKE;
-	p.pos = pos;
-	p.vel = vel + random_dir()*50.0f;
-	p.life_span = 0.5f + frandom()*0.5f;
-	p.start_size = 12.0f + frandom()*8;
-	p.end_size = 0;
-	p.friction = 0.7;
-	p.gravity = frandom()*-500.0f;
-	gameclient.particles->add(PARTICLES::GROUP_PROJECTILE_TRAIL, &p);
+	CParticle p;
+	p.SetDefault();
+	p.m_Spr = SPRITE_PART_SMOKE;
+	p.m_Pos = Pos;
+	p.m_Vel = Vel + RandomDir()*50.0f;
+	p.m_LifeSpan = 0.5f + frandom()*0.5f;
+	p.m_StartSize = 12.0f + frandom()*8;
+	p.m_EndSize = 0;
+	p.m_Friction = 0.7;
+	p.m_Gravity = frandom()*-500.0f;
+	m_pClient->m_pParticles->Add(CParticles::GROUP_PROJECTILE_TRAIL, &p);
 }
 
 
-void EFFECTS::skidtrail(vec2 pos, vec2 vel)
+void CEffects::SkidTrail(vec2 Pos, vec2 Vel)
 {
-	if(!add_100hz)
+	if(!m_Add100hz)
 		return;
 	
-	PARTICLE p;
-	p.set_default();
-	p.spr = SPRITE_PART_SMOKE;
-	p.pos = pos;
-	p.vel = vel + random_dir()*50.0f;
-	p.life_span = 0.5f + frandom()*0.5f;
-	p.start_size = 24.0f + frandom()*12;
-	p.end_size = 0;
-	p.friction = 0.7f;
-	p.gravity = frandom()*-500.0f;
-	p.color = vec4(0.75f,0.75f,0.75f,1.0f);
-	gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p);	
+	CParticle p;
+	p.SetDefault();
+	p.m_Spr = SPRITE_PART_SMOKE;
+	p.m_Pos = Pos;
+	p.m_Vel = Vel + RandomDir()*50.0f;
+	p.m_LifeSpan = 0.5f + frandom()*0.5f;
+	p.m_StartSize = 24.0f + frandom()*12;
+	p.m_EndSize = 0;
+	p.m_Friction = 0.7f;
+	p.m_Gravity = frandom()*-500.0f;
+	p.m_Color = vec4(0.75f,0.75f,0.75f,1.0f);
+	m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p);	
 }
 
-void EFFECTS::bullettrail(vec2 pos)
+void CEffects::BulletTrail(vec2 Pos)
 {
-	if(!add_100hz)
+	if(!m_Add100hz)
 		return;
 		
-	PARTICLE p;
-	p.set_default();
-	p.spr = SPRITE_PART_BALL;
-	p.pos = pos;
-	p.life_span = 0.25f + frandom()*0.25f;
-	p.start_size = 8.0f;
-	p.end_size = 0;
-	p.friction = 0.7f;
-	gameclient.particles->add(PARTICLES::GROUP_PROJECTILE_TRAIL, &p);
+	CParticle p;
+	p.SetDefault();
+	p.m_Spr = SPRITE_PART_BALL;
+	p.m_Pos = Pos;
+	p.m_LifeSpan = 0.25f + frandom()*0.25f;
+	p.m_StartSize = 8.0f;
+	p.m_EndSize = 0;
+	p.m_Friction = 0.7f;
+	m_pClient->m_pParticles->Add(CParticles::GROUP_PROJECTILE_TRAIL, &p);
 }
 
-void EFFECTS::playerspawn(vec2 pos)
+void CEffects::PlayerSpawn(vec2 Pos)
 {
 	for(int i = 0; i < 32; i++)
 	{
-		PARTICLE p;
-		p.set_default();
-		p.spr = SPRITE_PART_SHELL;
-		p.pos = pos;
-		p.vel = random_dir() * (pow(frandom(), 3)*600.0f);
-		p.life_span = 0.3f + frandom()*0.3f;
-		p.start_size = 64.0f + frandom()*32;
-		p.end_size = 0;
-		p.rot = frandom()*pi*2;
-		p.rotspeed = frandom();
-		p.gravity = frandom()*-400.0f;
-		p.friction = 0.7f;
-		p.color = vec4(0xb5/255.0f, 0x50/255.0f, 0xcb/255.0f, 1.0f);
-		gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p);
+		CParticle p;
+		p.SetDefault();
+		p.m_Spr = SPRITE_PART_SHELL;
+		p.m_Pos = Pos;
+		p.m_Vel = RandomDir() * (powf(frandom(), 3)*600.0f);
+		p.m_LifeSpan = 0.3f + frandom()*0.3f;
+		p.m_StartSize = 64.0f + frandom()*32;
+		p.m_EndSize = 0;
+		p.m_Rot = frandom()*pi*2;
+		p.m_Rotspeed = frandom();
+		p.m_Gravity = frandom()*-400.0f;
+		p.m_Friction = 0.7f;
+		p.m_Color = vec4(0xb5/255.0f, 0x50/255.0f, 0xcb/255.0f, 1.0f);
+		m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p);
 		
 	}
-	gameclient.sounds->play(SOUNDS::CHN_WORLD, SOUND_PLAYER_SPAWN, 1.0f, pos);
+	m_pClient->m_pSounds->Play(CSounds::CHN_WORLD, SOUND_PLAYER_SPAWN, 1.0f, Pos);
 }
 
-void EFFECTS::playerdeath(vec2 pos, int cid)
+void CEffects::PlayerDeath(vec2 Pos, int Cid)
 {
-	vec3 blood_color(1.0f,1.0f,1.0f);
+	vec3 BloodColor(1.0f,1.0f,1.0f);
 
-	if(cid >= 0)	
+	if(Cid >= 0)	
 	{
-		const SKINS::SKIN *s = gameclient.skins->get(gameclient.clients[cid].skin_id);
+		const CSkins::CSkin *s = m_pClient->m_pSkins->Get(m_pClient->m_aClients[Cid].m_SkinId);
 		if(s)
-			blood_color = s->blood_color;
+			BloodColor = s->m_BloodColor;
 	}
 	
 	for(int i = 0; i < 64; i++)
 	{
-		PARTICLE p;
-		p.set_default();
-		p.spr = SPRITE_PART_SPLAT01 + (rand()%3);
-		p.pos = pos;
-		p.vel = random_dir() * ((frandom()+0.1f)*900.0f);
-		p.life_span = 0.3f + frandom()*0.3f;
-		p.start_size = 24.0f + frandom()*16;
-		p.end_size = 0;
-		p.rot = frandom()*pi*2;
-		p.rotspeed = (frandom()-0.5f) * pi;
-		p.gravity = 800.0f;
-		p.friction = 0.8f;
-		vec3 c = blood_color * (0.75f + frandom()*0.25f);
-		p.color = vec4(c.r, c.g, c.b, 0.75f);
-		gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p);
+		CParticle p;
+		p.SetDefault();
+		p.m_Spr = SPRITE_PART_SPLAT01 + (rand()%3);
+		p.m_Pos = Pos;
+		p.m_Vel = RandomDir() * ((frandom()+0.1f)*900.0f);
+		p.m_LifeSpan = 0.3f + frandom()*0.3f;
+		p.m_StartSize = 24.0f + frandom()*16;
+		p.m_EndSize = 0;
+		p.m_Rot = frandom()*pi*2;
+		p.m_Rotspeed = (frandom()-0.5f) * pi;
+		p.m_Gravity = 800.0f;
+		p.m_Friction = 0.8f;
+		vec3 c = BloodColor * (0.75f + frandom()*0.25f);
+		p.m_Color = vec4(c.r, c.g, c.b, 0.75f);
+		m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p);
 	}
 }
 
 
-void EFFECTS::explosion(vec2 pos)
+void CEffects::Explosion(vec2 Pos)
 {
 	// add to flow
 	for(int y = -8; y <= 8; y++)
@@ -187,75 +185,75 @@ void EFFECTS::explosion(vec2 pos)
 				continue;
 			
 			float a = 1 - (length(vec2(x,y)) / length(vec2(8,8)));
-			gameclient.flow->add(pos+vec2(x,y)*16, normalize(vec2(x,y))*5000.0f*a, 10.0f);
+			m_pClient->m_pFlow->Add(Pos+vec2(x,y)*16, normalize(vec2(x,y))*5000.0f*a, 10.0f);
 		}
 		
 	// add the explosion
-	PARTICLE p;
-	p.set_default();
-	p.spr = SPRITE_PART_EXPL01;
-	p.pos = pos;
-	p.life_span = 0.4f;
-	p.start_size = 150.0f;
-	p.end_size = 0;
-	p.rot = frandom()*pi*2;
-	gameclient.particles->add(PARTICLES::GROUP_EXPLOSIONS, &p);
+	CParticle p;
+	p.SetDefault();
+	p.m_Spr = SPRITE_PART_EXPL01;
+	p.m_Pos = Pos;
+	p.m_LifeSpan = 0.4f;
+	p.m_StartSize = 150.0f;
+	p.m_EndSize = 0;
+	p.m_Rot = frandom()*pi*2;
+	m_pClient->m_pParticles->Add(CParticles::GROUP_EXPLOSIONS, &p);
 	
 	// add the smoke
 	for(int i = 0; i < 24; i++)
 	{
-		PARTICLE p;
-		p.set_default();
-		p.spr = SPRITE_PART_SMOKE;
-		p.pos = pos;
-		p.vel = random_dir() * ((1.0f + frandom()*0.2f) * 1000.0f);
-		p.life_span = 0.5f + frandom()*0.4f;
-		p.start_size = 32.0f + frandom()*8;
-		p.end_size = 0;
-		p.gravity = frandom()*-800.0f;
-		p.friction = 0.4f;
-		p.color = mix(vec4(0.75f,0.75f,0.75f,1.0f), vec4(0.5f,0.5f,0.5f,1.0f), frandom());
-		gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p);
+		CParticle p;
+		p.SetDefault();
+		p.m_Spr = SPRITE_PART_SMOKE;
+		p.m_Pos = Pos;
+		p.m_Vel = RandomDir() * ((1.0f + frandom()*0.2f) * 1000.0f);
+		p.m_LifeSpan = 0.5f + frandom()*0.4f;
+		p.m_StartSize = 32.0f + frandom()*8;
+		p.m_EndSize = 0;
+		p.m_Gravity = frandom()*-800.0f;
+		p.m_Friction = 0.4f;
+		p.m_Color = mix(vec4(0.75f,0.75f,0.75f,1.0f), vec4(0.5f,0.5f,0.5f,1.0f), frandom());
+		m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p);
 	}
 }
 
 
-void EFFECTS::hammerhit(vec2 pos)
+void CEffects::HammerHit(vec2 Pos)
 {
 	// add the explosion
-	PARTICLE p;
-	p.set_default();
-	p.spr = SPRITE_PART_EXPL01;
-	p.pos = pos;
-	p.life_span = 0.4f;
-	p.start_size = 150.0f;
-	p.end_size = 0;
-	p.rot = frandom()*pi*2;
-	gameclient.particles->add(PARTICLES::GROUP_EXPLOSIONS, &p);	
-	gameclient.sounds->play(SOUNDS::CHN_WORLD, SOUND_HAMMER_HIT, 1.0f, pos);
+	CParticle p;
+	p.SetDefault();
+	p.m_Spr = SPRITE_PART_EXPL01;
+	p.m_Pos = Pos;
+	p.m_LifeSpan = 0.4f;
+	p.m_StartSize = 150.0f;
+	p.m_EndSize = 0;
+	p.m_Rot = frandom()*pi*2;
+	m_pClient->m_pParticles->Add(CParticles::GROUP_EXPLOSIONS, &p);	
+	m_pClient->m_pSounds->Play(CSounds::CHN_WORLD, SOUND_HAMMER_HIT, 1.0f, Pos);
 }
 
-void EFFECTS::on_render()
+void CEffects::OnRender()
 {
-	static int64 last_update_100hz = 0;
-	static int64 last_update_50hz = 0;
+	static int64 LastUpdate100hz = 0;
+	static int64 LastUpdate50hz = 0;
 
-	if(time_get()-last_update_100hz > time_freq()/100)
+	if(time_get()-LastUpdate100hz > time_freq()/100)
 	{
-		add_100hz = true;
-		last_update_100hz = time_get();
+		m_Add100hz = true;
+		LastUpdate100hz = time_get();
 	}
 	else
-		add_100hz = false;
+		m_Add100hz = false;
 
-	if(time_get()-last_update_50hz > time_freq()/100)
+	if(time_get()-LastUpdate50hz > time_freq()/100)
 	{
-		add_50hz = true;
-		last_update_50hz = time_get();
+		m_Add50hz = true;
+		LastUpdate50hz = time_get();
 	}
 	else
-		add_50hz = false;
+		m_Add50hz = false;
 		
-	if(add_50hz)
-		gameclient.flow->update();
+	if(m_Add50hz)
+		m_pClient->m_pFlow->Update();
 }
diff --git a/src/game/client/components/effects.h b/src/game/client/components/effects.h
new file mode 100644
index 00000000..e8345500
--- /dev/null
+++ b/src/game/client/components/effects.h
@@ -0,0 +1,27 @@
+#ifndef GAME_CLIENT_COMPONENTS_EFFECTS_H
+#define GAME_CLIENT_COMPONENTS_EFFECTS_H
+#include <game/client/component.h>
+
+class CEffects : public CComponent
+{	
+	bool m_Add50hz;
+	bool m_Add100hz;
+public:
+	CEffects();
+
+	virtual void OnRender();
+
+	void BulletTrail(vec2 Pos);
+	void SmokeTrail(vec2 Pos, vec2 Vel);
+	void SkidTrail(vec2 Pos, vec2 Vel);
+	void Explosion(vec2 Pos);
+	void HammerHit(vec2 Pos);
+	void AirJump(vec2 Pos);
+	void DamageIndicator(vec2 Pos, vec2 Dir);
+	void PlayerSpawn(vec2 Pos);
+	void PlayerDeath(vec2 Pos, int ClientId);
+	void PowerupShine(vec2 Pos, vec2 Size);
+
+	void Update();
+};
+#endif
diff --git a/src/game/client/components/effects.hpp b/src/game/client/components/effects.hpp
deleted file mode 100644
index 8574bf60..00000000
--- a/src/game/client/components/effects.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <game/client/component.hpp>
-
-class EFFECTS : public COMPONENT
-{	
-	bool add_50hz;
-	bool add_100hz;
-public:
-	EFFECTS();
-
-	virtual void on_render();
-
-	void bullettrail(vec2 pos);
-	void smoketrail(vec2 pos, vec2 vel);
-	void skidtrail(vec2 pos, vec2 vel);
-	void explosion(vec2 pos);
-	void hammerhit(vec2 pos);
-	void air_jump(vec2 pos);
-	void damage_indicator(vec2 pos, vec2 dir);
-	void playerspawn(vec2 pos);
-	void playerdeath(vec2 pos, int cid);
-	void powerupshine(vec2 pos, vec2 size);
-
-	void update();
-};
diff --git a/src/game/client/components/emoticon.cpp b/src/game/client/components/emoticon.cpp
index 8001a306..6d03f88d 100644
--- a/src/game/client/components/emoticon.cpp
+++ b/src/game/client/components/emoticon.cpp
@@ -1,157 +1,161 @@
-#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/gamecore.hpp> // get_angle
-#include <game/client/gameclient.hpp>
-#include <game/client/ui.hpp>
-#include <game/client/render.hpp>
-#include "emoticon.hpp"
-
-EMOTICON::EMOTICON()
+#include <engine/graphics.h>
+#include <engine/shared/config.h>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
+
+#include <game/gamecore.h> // get_angle
+#include <game/client/gameclient.h>
+#include <game/client/ui.h>
+#include <game/client/render.h>
+#include "emoticon.h"
+
+CEmoticon::CEmoticon()
 {
-	on_reset();
+	OnReset();
 }
 
-void EMOTICON::con_key_emoticon(void *result, void *user_data)
+void CEmoticon::ConKeyEmoticon(IConsole::IResult *pResult, void *pUserData)
 {
-	((EMOTICON *)user_data)->active = console_arg_int(result, 0) != 0;
+	((CEmoticon *)pUserData)->m_Active = pResult->GetInteger(0) != 0;
 }
 
-void EMOTICON::con_emote(void *result, void *user_data)
+void CEmoticon::ConEmote(IConsole::IResult *pResult, void *pUserData)
 {
-	((EMOTICON *)user_data)->emote(console_arg_int(result, 0));
+	((CEmoticon *)pUserData)->Emote(pResult->GetInteger(0));
 }
 
-void EMOTICON::on_console_init()
+void CEmoticon::OnConsoleInit()
 {
-	MACRO_REGISTER_COMMAND("+emote", "", CFGFLAG_CLIENT, con_key_emoticon, this, "Open emote selector");
-	MACRO_REGISTER_COMMAND("emote", "i", CFGFLAG_CLIENT, con_emote, this, "Use emote");
+	Console()->Register("+emote", "", CFGFLAG_CLIENT, ConKeyEmoticon, this, "Open emote selector");
+	Console()->Register("emote", "i", CFGFLAG_CLIENT, ConEmote, this, "Use emote");
 }
 
-void EMOTICON::on_reset()
+void CEmoticon::OnReset()
 {
-	was_active = false;
-	active = false;
-	selected_emote = -1;
+	m_WasActive = false;
+	m_Active = false;
+	m_SelectedEmote = -1;
 }
 
-void EMOTICON::on_message(int msgtype, void *rawmsg)
+void CEmoticon::OnMessage(int MsgType, void *pRawMsg)
 {
-	if(msgtype == NETMSGTYPE_SV_EMOTICON)
-	{
-		NETMSG_SV_EMOTICON *msg = (NETMSG_SV_EMOTICON *)rawmsg;
-		gameclient.clients[msg->cid].emoticon = msg->emoticon;
-		gameclient.clients[msg->cid].emoticon_start = client_tick();
-	}	
 }
 
-bool EMOTICON::on_mousemove(float x, float y)
+bool CEmoticon::OnMouseMove(float x, float y)
 {
-	if(!active)
+	if(!m_Active)
 		return false;
 	
-	selector_mouse += vec2(x,y);
+	m_SelectorMouse += vec2(x,y);
 	return true;
 }
 
-void EMOTICON::draw_circle(float x, float y, float r, int segments)
+void CEmoticon::DrawCircle(float x, float y, float r, int Segments)
 {
-	float f_segments = (float)segments;
-	for(int i = 0; i < segments; i+=2)
+	IGraphics::CFreeformItem Array[32];
+	int NumItems = 0;
+	float FSegments = (float)Segments;
+	for(int i = 0; i < Segments; i+=2)
 	{
-		float a1 = i/f_segments * 2*pi;
-		float a2 = (i+1)/f_segments * 2*pi;
-		float a3 = (i+2)/f_segments * 2*pi;
-		float ca1 = cosf(a1);
-		float ca2 = cosf(a2);
-		float ca3 = cosf(a3);
-		float sa1 = sinf(a1);
-		float sa2 = sinf(a2);
-		float sa3 = sinf(a3);
-
-		client->Graphics()->QuadsDrawFreeform(
+		float a1 = i/FSegments * 2*pi;
+		float a2 = (i+1)/FSegments * 2*pi;
+		float a3 = (i+2)/FSegments * 2*pi;
+		float Ca1 = cosf(a1);
+		float Ca2 = cosf(a2);
+		float Ca3 = cosf(a3);
+		float Sa1 = sinf(a1);
+		float Sa2 = sinf(a2);
+		float Sa3 = sinf(a3);
+
+		Array[NumItems++] = IGraphics::CFreeformItem(
 			x, y,
-			x+ca1*r, y+sa1*r,
-			x+ca3*r, y+sa3*r,
-			x+ca2*r, y+sa2*r);
+			x+Ca1*r, y+Sa1*r,
+			x+Ca3*r, y+Sa3*r,
+			x+Ca2*r, y+Sa2*r);
+		if(NumItems == 32)
+		{
+			m_pClient->Graphics()->QuadsDrawFreeform(Array, 32);
+			NumItems = 0;
+		}
 	}
+	if(NumItems)
+		m_pClient->Graphics()->QuadsDrawFreeform(Array, NumItems);
 }
 
 	
-void EMOTICON::on_render()
+void CEmoticon::OnRender()
 {
-	if(!active)
+	if(!m_Active)
 	{
-		if(was_active && selected_emote != -1)
-			emote(selected_emote);
-		was_active = false;
+		if(m_WasActive && m_SelectedEmote != -1)
+			Emote(m_SelectedEmote);
+		m_WasActive = false;
 		return;
 	}
 	
-	was_active = true;
+	m_WasActive = true;
 	
 	int x, y;
-	inp_mouse_relative(&x, &y);
+	Input()->MouseRelative(&x, &y);
 
-	selector_mouse.x += x;
-	selector_mouse.y += y;
+	m_SelectorMouse.x += x;
+	m_SelectorMouse.y += y;
 
-	if (length(selector_mouse) > 140)
-		selector_mouse = normalize(selector_mouse) * 140;
+	if (length(m_SelectorMouse) > 140)
+		m_SelectorMouse = normalize(m_SelectorMouse) * 140;
 
-	float selected_angle = get_angle(selector_mouse) + 2*pi/24;
-	if (selected_angle < 0)
-		selected_angle += 2*pi;
+	float SelectedAngle = GetAngle(m_SelectorMouse) + 2*pi/24;
+	if (SelectedAngle < 0)
+		SelectedAngle += 2*pi;
 
-	if (length(selector_mouse) > 100)
-		selected_emote = (int)(selected_angle / (2*pi) * 12.0f);
+	if (length(m_SelectorMouse) > 100)
+		m_SelectedEmote = (int)(SelectedAngle / (2*pi) * 12.0f);
 
-    CUIRect screen = *UI()->Screen();
+    CUIRect Screen = *UI()->Screen();
 
-	Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);
+	Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
 
 	Graphics()->BlendNormal();
 
 	Graphics()->TextureSet(-1);
 	Graphics()->QuadsBegin();
 	Graphics()->SetColor(0,0,0,0.3f);
-	draw_circle(screen.w/2, screen.h/2, 160, 64);
+	DrawCircle(Screen.w/2, Screen.h/2, 160, 64);
 	Graphics()->QuadsEnd();
 
-	Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
 	Graphics()->QuadsBegin();
 
 	for (int i = 0; i < 12; i++)
 	{
-		float angle = 2*pi*i/12.0;
-		if (angle > pi)
-			angle -= 2*pi;
+		float Angle = 2*pi*i/12.0;
+		if (Angle > pi)
+			Angle -= 2*pi;
 
-		bool selected = selected_emote == i;
+		bool Selected = m_SelectedEmote == i;
 
-		float size = selected ? 96 : 64;
+		float Size = Selected ? 96 : 64;
 
-		float nudge_x = 120 * cos(angle);
-		float nudge_y = 120 * sin(angle);
-		RenderTools()->select_sprite(SPRITE_OOP + i);
-		Graphics()->QuadsDraw(screen.w/2 + nudge_x, screen.h/2 + nudge_y, size, size);
+		float NudgeX = 120 * cosf(Angle);
+		float NudgeY = 120 * sinf(Angle);
+		RenderTools()->SelectSprite(SPRITE_OOP + i);
+		IGraphics::CQuadItem QuadItem(Screen.w/2 + NudgeX, Screen.h/2 + NudgeY, Size, Size);
+		Graphics()->QuadsDraw(&QuadItem, 1);
 	}
 
 	Graphics()->QuadsEnd();
 
-    Graphics()->TextureSet(data->images[IMAGE_CURSOR].id);
+    Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_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);
+	IGraphics::CQuadItem QuadItem(m_SelectorMouse.x+Screen.w/2,m_SelectorMouse.y+Screen.h/2,24,24);
+	Graphics()->QuadsDrawTL(&QuadItem, 1);
     Graphics()->QuadsEnd();
 }
 
-void EMOTICON::emote(int emoticon)
+void CEmoticon::Emote(int Emoticon)
 {
-	NETMSG_CL_EMOTICON msg;
-	msg.emoticon = emoticon;
-	msg.pack(MSGFLAG_VITAL);
-	client_send_msg();
+	CNetMsg_Cl_Emoticon Msg;
+	Msg.m_Emoticon = Emoticon;
+	Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
 }
diff --git a/src/game/client/components/emoticon.h b/src/game/client/components/emoticon.h
new file mode 100644
index 00000000..e10b57da
--- /dev/null
+++ b/src/game/client/components/emoticon.h
@@ -0,0 +1,31 @@
+#ifndef GAME_CLIENT_COMPONENTS_EMOTICON_H
+#define GAME_CLIENT_COMPONENTS_EMOTICON_H
+#include <base/vmath.h>
+#include <game/client/component.h>
+
+class CEmoticon : public CComponent
+{
+	void DrawCircle(float x, float y, float r, int Segments);
+	
+	bool m_WasActive;
+	bool m_Active;
+	
+	vec2 m_SelectorMouse;
+	int m_SelectedEmote;
+
+	static void ConKeyEmoticon(IConsole::IResult *pResult, void *pUserData);
+	static void ConEmote(IConsole::IResult *pResult, void *pUserData);
+	
+public:
+	CEmoticon();
+	
+	virtual void OnReset();
+	virtual void OnConsoleInit();
+	virtual void OnRender();
+	virtual void OnMessage(int MsgType, void *pRawMsg);
+	virtual bool OnMouseMove(float x, float y);
+
+	void Emote(int Emoticon);
+};
+
+#endif
diff --git a/src/game/client/components/emoticon.hpp b/src/game/client/components/emoticon.hpp
deleted file mode 100644
index 446b4b00..00000000
--- a/src/game/client/components/emoticon.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <base/vmath.hpp>
-#include <game/client/component.hpp>
-
-class EMOTICON : public COMPONENT
-{
-	void draw_circle(float x, float y, float r, int segments);
-	
-	bool was_active;
-	bool active;
-	
-	vec2 selector_mouse;
-	int selected_emote;
-
-	static void con_key_emoticon(void *result, void *user_data);
-	static void con_emote(void *result, void *user_data);
-	
-public:
-	EMOTICON();
-	
-	virtual void on_reset();
-	virtual void on_console_init();
-	virtual void on_render();
-	virtual void on_message(int msgtype, void *rawmsg);
-	virtual bool on_mousemove(float x, float y);
-
-	void emote(int emoticon);
-};
-
diff --git a/src/game/client/components/flow.cpp b/src/game/client/components/flow.cpp
index 9ecd4b5c..d2ba704c 100644
--- a/src/game/client/components/flow.cpp
+++ b/src/game/client/components/flow.cpp
@@ -1,85 +1,94 @@
-#include <engine/client/graphics.h>
-#include <game/mapitems.hpp>
-#include <game/layers.hpp>
-#include "flow.hpp"
+#include <engine/graphics.h>
+#include <game/mapitems.h>
+#include <game/layers.h>
+#include "flow.h"
 
-FLOW::FLOW()
+CFlow::CFlow()
 {
-	cells = 0;
-	height = 0;
-	width = 0;
-	spacing = 16;
+	m_pCells = 0;
+	m_Height = 0;
+	m_Width = 0;
+	m_Spacing = 16;
 }
 	
-void FLOW::dbg_render()
+void CFlow::DbgRender()
 {
-	if(!cells)
+	if(!m_pCells)
 		return;
 
+	IGraphics::CLineItem Array[1024];
+	int NumItems = 0;
 	Graphics()->TextureSet(-1);
 	Graphics()->LinesBegin();
-	for(int y = 0; y < height; y++)
-		for(int x = 0; x < width; x++)
+	for(int y = 0; y < m_Height; y++)
+		for(int x = 0; x < m_Width; x++)
 		{
-			vec2 pos(x*spacing, y*spacing);
-			vec2 vel = cells[y*width+x].vel * 0.01f;
-			Graphics()->LinesDraw(pos.x, pos.y, pos.x+vel.x, pos.y+vel.y);
+			vec2 Pos(x*m_Spacing, y*m_Spacing);
+			vec2 Vel = m_pCells[y*m_Width+x].m_Vel * 0.01f;
+			Array[NumItems++] = IGraphics::CLineItem(Pos.x, Pos.y, Pos.x+Vel.x, Pos.y+Vel.y);
+			if(NumItems == 1024)
+			{
+				Graphics()->LinesDraw(Array, 1024);
+				NumItems = 0;
+			}
 		}
-		
+	
+	if(NumItems)
+		Graphics()->LinesDraw(Array, NumItems);
 	Graphics()->LinesEnd();
 }
 
-void FLOW::init()
+void CFlow::Init()
 {
-	if(cells)
+	if(m_pCells)
 	{
-		mem_free(cells);
-		cells = 0;
+		mem_free(m_pCells);
+		m_pCells = 0;
 	}
 	
-	MAPITEM_LAYER_TILEMAP *tilemap = layers_game_layer();
-	width = tilemap->width*32/spacing;
-	height = tilemap->height*32/spacing;
+	CMapItemLayerTilemap *pTilemap = Layers()->GameLayer();
+	m_Width = pTilemap->m_Width*32/m_Spacing;
+	m_Height = pTilemap->m_Height*32/m_Spacing;
 
 	// allocate and clear	
-	cells = (CELL *)mem_alloc(sizeof(CELL)*width*height, 1);
-	for(int y = 0; y < height; y++)
-		for(int x = 0; x < width; x++)
-			cells[y*width+x].vel = vec2(0.0f, 0.0f);
+	m_pCells = (CCell *)mem_alloc(sizeof(CCell)*m_Width*m_Height, 1);
+	for(int y = 0; y < m_Height; y++)
+		for(int x = 0; x < m_Width; x++)
+			m_pCells[y*m_Width+x].m_Vel = vec2(0.0f, 0.0f);
 }
 
-void FLOW::update()
+void CFlow::Update()
 {
-	if(!cells)
+	if(!m_pCells)
 		return;
 		
-	for(int y = 0; y < height; y++)
-		for(int x = 0; x < width; x++)
-			cells[y*width+x].vel *= 0.85f;
+	for(int y = 0; y < m_Height; y++)
+		for(int x = 0; x < m_Width; x++)
+			m_pCells[y*m_Width+x].m_Vel *= 0.85f;
 }
 
-vec2 FLOW::get(vec2 pos)
+vec2 CFlow::Get(vec2 Pos)
 {
-	if(!cells)
+	if(!m_pCells)
 		return vec2(0,0);
 	
-	int x = (int)(pos.x / spacing);
-	int y = (int)(pos.y / spacing);
-	if(x < 0 || y < 0 || x >= width || y >= height)
+	int x = (int)(Pos.x / m_Spacing);
+	int y = (int)(Pos.y / m_Spacing);
+	if(x < 0 || y < 0 || x >= m_Width || y >= m_Height)
 		return vec2(0,0);
 	
-	return cells[y*width+x].vel;	
+	return m_pCells[y*m_Width+x].m_Vel;	
 }
 
-void FLOW::add(vec2 pos, vec2 vel, float size)
+void CFlow::Add(vec2 Pos, vec2 Vel, float Size)
 {
-	if(!cells)
+	if(!m_pCells)
 		return;
 		
-	int x = (int)(pos.x / spacing);
-	int y = (int)(pos.y / spacing);
-	if(x < 0 || y < 0 || x >= width || y >= height)
+	int x = (int)(Pos.x / m_Spacing);
+	int y = (int)(Pos.y / m_Spacing);
+	if(x < 0 || y < 0 || x >= m_Width || y >= m_Height)
 		return;
 	
-	cells[y*width+x].vel += vel;
+	m_pCells[y*m_Width+x].m_Vel += Vel;
 }
diff --git a/src/game/client/components/flow.h b/src/game/client/components/flow.h
new file mode 100644
index 00000000..e8134797
--- /dev/null
+++ b/src/game/client/components/flow.h
@@ -0,0 +1,28 @@
+#ifndef GAME_CLIENT_COMPONENTS_FLOW_H
+#define GAME_CLIENT_COMPONENTS_FLOW_H
+#include <base/vmath.h>
+#include <game/client/component.h>
+
+class CFlow : public CComponent
+{
+	struct CCell
+	{
+		vec2 m_Vel;
+	};
+
+	CCell *m_pCells;
+	int m_Height;
+	int m_Width;
+	int m_Spacing;
+	
+	void DbgRender();
+	void Init();
+public:
+	CFlow();
+	
+	vec2 Get(vec2 Pos);
+	void Add(vec2 Pos, vec2 Vel, float Size);
+	void Update();
+};
+
+#endif
diff --git a/src/game/client/components/flow.hpp b/src/game/client/components/flow.hpp
deleted file mode 100644
index 351b1f69..00000000
--- a/src/game/client/components/flow.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <base/vmath.hpp>
-#include <game/client/component.hpp>
-
-class FLOW : public COMPONENT
-{
-	struct CELL
-	{
-		vec2 vel;
-	};
-
-	CELL *cells;
-	int height;
-	int width;
-	int spacing;
-	
-	void dbg_render();
-	void init();
-public:
-	FLOW();
-	
-	vec2 get(vec2 pos);
-	void add(vec2 pos, vec2 vel, float size);
-	void update();
-};
-
diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp
index 837322fb..f4a24384 100644
--- a/src/game/client/components/hud.cpp
+++ b/src/game/client/components/hud.cpp
@@ -1,32 +1,31 @@
-#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>
-
-#include <game/layers.hpp>
-
-#include <game/client/gameclient.hpp>
-#include <game/client/animstate.hpp>
-#include <game/client/render.hpp>
-
-#include "controls.hpp"
-#include "camera.hpp"
-#include "hud.hpp"
-#include "voting.hpp"
-#include "binds.hpp"
-
-HUD::HUD()
+#include <engine/graphics.h>
+#include <engine/textrender.h>
+#include <engine/shared/config.h>
+
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
+#include <game/layers.h>
+#include <game/client/gameclient.h>
+#include <game/client/animstate.h>
+#include <game/client/render.h>
+
+#include "controls.h"
+#include "camera.h"
+#include "hud.h"
+#include "voting.h"
+#include "binds.h"
+
+CHud::CHud()
 {
-	
+	// won't work if zero
+	m_AverageFPS = 1.0f;
 }
 	
-void HUD::on_reset()
+void CHud::OnReset()
 {
 }
 
-void HUD::render_goals()
+void CHud::RenderGoals()
 {
 	// TODO: split this up into these:
 	// render_gametimer
@@ -34,41 +33,41 @@ void HUD::render_goals()
 	// render_scorehud
 	// render_warmuptimer
 	
-	int gameflags = gameclient.snap.gameobj->flags;
+	int GameFlags = m_pClient->m_Snap.m_pGameobj->m_Flags;
 	
-	float whole = 300*Graphics()->ScreenAspect();
-	float half = whole/2.0f;
+	float Whole = 300*Graphics()->ScreenAspect();
+	float Half = Whole/2.0f;
 
 
 	Graphics()->MapScreen(0,0,300*Graphics()->ScreenAspect(),300);
-	if(!gameclient.snap.gameobj->sudden_death)
+	if(!m_pClient->m_Snap.m_pGameobj->m_SuddenDeath)
 	{
-		char buf[32];
-		int time = 0;
-		if(gameclient.snap.gameobj->time_limit)
+		char Buf[32];
+		int Time = 0;
+		if(m_pClient->m_Snap.m_pGameobj->m_TimeLimit)
 		{
-			time = gameclient.snap.gameobj->time_limit*60 - ((client_tick()-gameclient.snap.gameobj->round_start_tick)/client_tickspeed());
+			Time = m_pClient->m_Snap.m_pGameobj->m_TimeLimit*60 - ((Client()->GameTick()-m_pClient->m_Snap.m_pGameobj->m_RoundStartTick)/Client()->GameTickSpeed());
 
-			if(gameclient.snap.gameobj->game_over)
-				time  = 0;
+			if(m_pClient->m_Snap.m_pGameobj->m_GameOver)
+				Time  = 0;
 		}
 		else
-			time = (client_tick()-gameclient.snap.gameobj->round_start_tick)/client_tickspeed();
+			Time = (Client()->GameTick()-m_pClient->m_Snap.m_pGameobj->m_RoundStartTick)/Client()->GameTickSpeed();
 
-		str_format(buf, sizeof(buf), "%d:%02d", time /60, time %60);
-		float w = gfx_text_width(0, 16, buf, -1);
-		gfx_text(0, half-w/2, 2, 16, buf, -1);
+		str_format(Buf, sizeof(Buf), "%d:%02d", Time /60, Time %60);
+		float w = TextRender()->TextWidth(0, 16, Buf, -1);
+		TextRender()->Text(0, Half-w/2, 2, 16, Buf, -1);
 	}
 
-	if(gameclient.snap.gameobj->sudden_death)
+	if(m_pClient->m_Snap.m_pGameobj->m_SuddenDeath)
 	{
-		const char *text = "Sudden Death";
-		float w = gfx_text_width(0, 16, text, -1);
-		gfx_text(0, half-w/2, 2, 16, text, -1);
+		const char *pText = "Sudden Death";
+		float w = TextRender()->TextWidth(0, 16, pText, -1);
+		TextRender()->Text(0, Half-w/2, 2, 16, pText, -1);
 	}
 
 	// render small score hud
-	if(!(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over) && (gameflags&GAMEFLAG_TEAMS))
+	if(!(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver) && (GameFlags&GAMEFLAG_TEAMS))
 	{
 		for(int t = 0; t < 2; t++)
 		{
@@ -79,166 +78,171 @@ void HUD::render_goals()
 				Graphics()->SetColor(1,0,0,0.25f);
 			else
 				Graphics()->SetColor(0,0,1,0.25f);
-			RenderTools()->draw_round_rect(whole-40, 300-40-15+t*20, 50, 18, 5.0f);
+			RenderTools()->DrawRoundRect(Whole-45, 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);
-			float w = gfx_text_width(0, 14, buf, -1);
+			char Buf[32];
+			str_format(Buf, sizeof(Buf), "%d", t?m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue : m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed);
+			float w = TextRender()->TextWidth(0, 14, Buf, -1);
 			
-			if(gameflags&GAMEFLAG_FLAGS)
+			if(GameFlags&GAMEFLAG_FLAGS)
 			{
-				gfx_text(0, whole-20-w/2+5, 300-40-15+t*20, 14, buf, -1);
-				if(gameclient.snap.flags[t])
+				TextRender()->Text(0, Whole-20-w/2+5, 300-40-15+t*20, 14, Buf, -1);
+				if(m_pClient->m_Snap.m_paFlags[t])
 				{
-					if(gameclient.snap.flags[t]->carried_by == -2 || (gameclient.snap.flags[t]->carried_by == -1 && ((client_tick()/10)&1)))
+					if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy == -2 || (m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy == -1 && ((Client()->GameTick()/10)&1)))
 					{
 						Graphics()->BlendNormal();
-						Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+						Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 						Graphics()->QuadsBegin();
 
-						if(t == 0) RenderTools()->select_sprite(SPRITE_FLAG_RED);
-						else RenderTools()->select_sprite(SPRITE_FLAG_BLUE);
+						if(t == 0) RenderTools()->SelectSprite(SPRITE_FLAG_RED);
+						else RenderTools()->SelectSprite(SPRITE_FLAG_BLUE);
 						
-						float size = 16;					
-						Graphics()->QuadsDrawTL(whole-40+5, 300-40-15+t*20+1, size/2, size);
+						float Size = 16;					
+						IGraphics::CQuadItem QuadItem(Whole-40+2, 300-40-15+t*20+1, Size/2, Size);
+						Graphics()->QuadsDrawTL(&QuadItem, 1);
 						Graphics()->QuadsEnd();
 					}
-					else if(gameclient.snap.flags[t]->carried_by >= 0)
+					else if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy >= 0)
 					{
-						int id = gameclient.snap.flags[t]->carried_by%MAX_CLIENTS;
-						const char *name = gameclient.clients[id].name;
-						float w = gfx_text_width(0, 10, name, -1);
-						gfx_text(0, whole-40-5-w, 300-40-15+t*20+2, 10, name, -1);
-						TEE_RENDER_INFO info = gameclient.clients[id].render_info;
-						info.size = 18.0f;
+						int Id = m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy%MAX_CLIENTS;
+						const char *pName = m_pClient->m_aClients[Id].m_aName;
+						float w = TextRender()->TextWidth(0, 10, pName, -1);
+						TextRender()->Text(0, Whole-40-7-w, 300-40-15+t*20+2, 10, pName, -1);
+						CTeeRenderInfo Info = m_pClient->m_aClients[Id].m_RenderInfo;
+						Info.m_Size = 18.0f;
 						
-						RenderTools()->RenderTee(ANIMSTATE::get_idle(), &info, EMOTE_NORMAL, vec2(1,0),
-							vec2(whole-40+10, 300-40-15+9+t*20+1));
+						RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, EMOTE_NORMAL, vec2(1,0),
+							vec2(Whole-40+5, 300-40-15+9+t*20+1));
 					}
 				}
 			}
 			else
-				gfx_text(0, whole-20-w/2, 300-40-15+t*20, 14, buf, -1);
+				TextRender()->Text(0, Whole-20-w/2, 300-40-15+t*20, 14, Buf, -1);
 		}
 	}
 
 	// render warmup timer
-	if(gameclient.snap.gameobj->warmup)
+	if(m_pClient->m_Snap.m_pGameobj->m_Warmup)
 	{
-		char buf[256];
-		float w = gfx_text_width(0, 24, "Warmup", -1);
-		gfx_text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, 24, "Warmup", -1);
+		char Buf[256];
+		float w = TextRender()->TextWidth(0, 24, "Warmup", -1);
+		TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, 24, "Warmup", -1);
 
-		int seconds = gameclient.snap.gameobj->warmup/SERVER_TICK_SPEED;
-		if(seconds < 5)
-			str_format(buf, sizeof(buf), "%d.%d", seconds, (gameclient.snap.gameobj->warmup*10/SERVER_TICK_SPEED)%10);
+		int Seconds = m_pClient->m_Snap.m_pGameobj->m_Warmup/SERVER_TICK_SPEED;
+		if(Seconds < 5)
+			str_format(Buf, sizeof(Buf), "%d.%d", Seconds, (m_pClient->m_Snap.m_pGameobj->m_Warmup*10/SERVER_TICK_SPEED)%10);
 		else
-			str_format(buf, sizeof(buf), "%d", seconds);
-		w = gfx_text_width(0, 24, buf, -1);
-		gfx_text(0, 150*Graphics()->ScreenAspect()+-w/2, 75, 24, buf, -1);
+			str_format(Buf, sizeof(Buf), "%d", Seconds);
+		w = TextRender()->TextWidth(0, 24, Buf, -1);
+		TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 75, 24, Buf, -1);
 	}	
 }
 
-void HUD::mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *group)
+void CHud::MapscreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup)
 {
-	float points[4];
-	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]);
+	float Points[4];
+	RenderTools()->MapscreenToWorld(CenterX, CenterY, pGroup->m_ParallaxX/100.0f, pGroup->m_ParallaxY/100.0f,
+		pGroup->m_OffsetX, pGroup->m_OffsetY, Graphics()->ScreenAspect(), 1.0f, Points);
+	Graphics()->MapScreen(Points[0], Points[1], Points[2], Points[3]);
 }
 
-void HUD::render_fps()
+void CHud::RenderFps()
 {
-	if(config.cl_showfps)
+	if(g_Config.m_ClShowfps)
 	{
-		char buf[512];
-		str_format(buf, sizeof(buf), "%d", (int)(1.0f/client_frametime()));
-		gfx_text(0, width-10-gfx_text_width(0,12,buf,-1), 5, 12, buf, -1);
+		// calculate avg. fps
+		float FPS = 1.0f / Client()->FrameTime();
+		m_AverageFPS = (m_AverageFPS*(1.0f-(1.0f/m_AverageFPS))) + (FPS*(1.0f/m_AverageFPS));
+		char Buf[512];
+		str_format(Buf, sizeof(Buf), "%d", (int)m_AverageFPS);
+		TextRender()->Text(0, m_Width-10-TextRender()->TextWidth(0,12,Buf,-1), 5, 12, Buf, -1);
 	}
 }
 
-void HUD::render_connectionwarning()
+void CHud::RenderConnectionWarning()
 {
-	if(client_connection_problems())
+	if(Client()->ConnectionProblems())
 	{
-		const char *text = "Connection Problems...";
-		float w = gfx_text_width(0, 24, text, -1);
-		gfx_text(0, 150*Graphics()->ScreenAspect()-w/2, 50, 24, text, -1);
+		const char *pText = "Connection Problems...";
+		float w = TextRender()->TextWidth(0, 24, pText, -1);
+		TextRender()->Text(0, 150*Graphics()->ScreenAspect()-w/2, 50, 24, pText, -1);
 	}
 }
 
-void HUD::render_teambalancewarning()
+void CHud::RenderTeambalanceWarning()
 {
 	// render prompt about team-balance
-	bool flash = time_get()/(time_freq()/2)%2 == 0;
-	if (gameclient.snap.gameobj && (gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS) != 0)
+	bool Flash = time_get()/(time_freq()/2)%2 == 0;
+	if (m_pClient->m_Snap.m_pGameobj && (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0)
 	{	
-		if (config.cl_warning_teambalance && abs(gameclient.snap.team_size[0]-gameclient.snap.team_size[1]) >= 2)
+		int TeamDiff = m_pClient->m_Snap.m_aTeamSize[0]-m_pClient->m_Snap.m_aTeamSize[1];
+		if (g_Config.m_ClWarningTeambalance && (TeamDiff >= 2 || TeamDiff <= -2))
 		{
-			const char *text = "Please balance teams!";
-			if(flash)
-				gfx_text_color(1,1,0.5f,1);
+			const char *pText = "Please balance teams!";
+			if(Flash)
+				TextRender()->TextColor(1,1,0.5f,1);
 			else
-				gfx_text_color(0.7f,0.7f,0.2f,1.0f);
-			gfx_text(0x0, 5, 50, 6, text, -1);
-			gfx_text_color(1,1,1,1);
+				TextRender()->TextColor(0.7f,0.7f,0.2f,1.0f);
+			TextRender()->Text(0x0, 5, 50, 6, pText, -1);
+			TextRender()->TextColor(1,1,1,1);
 		}
 	}
 }
 
 
-void HUD::render_voting()
+void CHud::RenderVoting()
 {
-	if(!gameclient.voting->is_voting())
+	if(!m_pClient->m_pVoting->IsVoting())
 		return;
 	
 	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);
+	RenderTools()->DrawRoundRect(-10, 60-2, 100+10+4+5, 28, 5.0f);
 	Graphics()->QuadsEnd();
 
-	gfx_text_color(1,1,1,1);
+	TextRender()->TextColor(1,1,1,1);
 
-	char buf[512];
-	gfx_text(0x0, 5, 60, 6, gameclient.voting->vote_description(), -1);
+	char Buf[512];
+	TextRender()->Text(0x0, 5, 60, 6, m_pClient->m_pVoting->VoteDescription(), -1);
 
-	str_format(buf, sizeof(buf), "%ds left", gameclient.voting->seconds_left());
-	float tw = gfx_text_width(0x0, 6, buf, -1);
-	gfx_text(0x0, 5+100-tw, 60, 6, buf, -1);
+	str_format(Buf, sizeof(Buf), "%ds left", m_pClient->m_pVoting->SecondsLeft());
+	float tw = TextRender()->TextWidth(0x0, 6, Buf, -1);
+	TextRender()->Text(0x0, 5+100-tw, 60, 6, Buf, -1);
 	
 
-	CUIRect base = {5, 70, 100, 4};
-	gameclient.voting->render_bars(base, false);
+	CUIRect Base = {5, 70, 100, 4};
+	m_pClient->m_pVoting->RenderBars(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()->DoLabel(&base, buf, 6.0f, -1);
-
-	str_format(buf, sizeof(buf), "Vote No - %s", no_key);
-	UI()->DoLabel(&base, buf, 6.0f, 1);
+	const char *pYesKey = m_pClient->m_pBinds->GetKey("vote yes");
+	const char *pNoKey = m_pClient->m_pBinds->GetKey("vote no");
+	str_format(Buf, sizeof(Buf), "%s - Vote Yes", pYesKey);
+	Base.y += Base.h+1;
+	UI()->DoLabel(&Base, Buf, 6.0f, -1);
+
+	str_format(Buf, sizeof(Buf), "Vote No - %s", pNoKey);
+	UI()->DoLabel(&Base, Buf, 6.0f, 1);
 }
 
-void HUD::render_cursor()
+void CHud::RenderCursor()
 {
-	if(!gameclient.snap.local_character)
+	if(!m_pClient->m_Snap.m_pLocalCharacter)
 		return;
 		
-	mapscreen_to_group(gameclient.camera->center.x, gameclient.camera->center.y, layers_game_group());
-	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	MapscreenToGroup(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y, Layers()->GameGroup());
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 	Graphics()->QuadsBegin();
 
 	// render cursor
-	RenderTools()->select_sprite(data->weapons.id[gameclient.snap.local_character->weapon%NUM_WEAPONS].sprite_cursor);
-	float cursorsize = 64;
-	RenderTools()->draw_sprite(gameclient.controls->target_pos.x, gameclient.controls->target_pos.y, cursorsize);
+	RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[m_pClient->m_Snap.m_pLocalCharacter->m_Weapon%NUM_WEAPONS].m_pSpriteCursor);
+	float CursorSize = 64;
+	RenderTools()->DrawSprite(m_pClient->m_pControls->m_TargetPos.x, m_pClient->m_pControls->m_TargetPos.y, CursorSize);
 	Graphics()->QuadsEnd();
 }
 
-void HUD::render_healthandammo()
+void CHud::RenderHealthAndAmmo()
 {
 	//mapscreen_to_group(gacenter_x, center_y, layers_game_group());
 
@@ -248,61 +252,69 @@ void HUD::render_healthandammo()
 	// render ammo count
 	// render gui stuff
 
-	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
-	Graphics()->MapScreen(0,0,width,300);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
+	Graphics()->MapScreen(0,0,m_Width,300);
 	
 	Graphics()->QuadsBegin();
 	
 	// if weaponstage is active, put a "glow" around the stage ammo
-	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++)
-		Graphics()->QuadsDrawTL(x+i*12,y+24,10,10);
-
+	RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[m_pClient->m_Snap.m_pLocalCharacter->m_Weapon%NUM_WEAPONS].m_pSpriteProj);
+	IGraphics::CQuadItem Array[10];
+	int i;
+	for (i = 0; i < min(m_pClient->m_Snap.m_pLocalCharacter->m_AmmoCount, 10); i++)
+		Array[i] = IGraphics::CQuadItem(x+i*12,y+24,10,10);
+	Graphics()->QuadsDrawTL(Array, i);
 	Graphics()->QuadsEnd();
 
 	Graphics()->QuadsBegin();
 	int h = 0;
 
 	// render health
-	RenderTools()->select_sprite(SPRITE_HEALTH_FULL);
-	for(; h < gameclient.snap.local_character->health; h++)
-		Graphics()->QuadsDrawTL(x+h*12,y,10,10);
+	RenderTools()->SelectSprite(SPRITE_HEALTH_FULL);
+	for(; h < min(m_pClient->m_Snap.m_pLocalCharacter->m_Health, 10); h++)
+		Array[h] = IGraphics::CQuadItem(x+h*12,y,10,10);
+	Graphics()->QuadsDrawTL(Array, h);
 
-	RenderTools()->select_sprite(SPRITE_HEALTH_EMPTY);
+	i = 0;
+	RenderTools()->SelectSprite(SPRITE_HEALTH_EMPTY);
 	for(; h < 10; h++)
-		Graphics()->QuadsDrawTL(x+h*12,y,10,10);
+		Array[i++] = IGraphics::CQuadItem(x+h*12,y,10,10);
+	Graphics()->QuadsDrawTL(Array, i);
 
 	// render armor meter
 	h = 0;
-	RenderTools()->select_sprite(SPRITE_ARMOR_FULL);
-	for(; h < gameclient.snap.local_character->armor; h++)
-		Graphics()->QuadsDrawTL(x+h*12,y+12,10,10);
+	RenderTools()->SelectSprite(SPRITE_ARMOR_FULL);
+	for(; h < min(m_pClient->m_Snap.m_pLocalCharacter->m_Armor, 10); h++)
+		Array[h] = IGraphics::CQuadItem(x+h*12,y+12,10,10);
+	Graphics()->QuadsDrawTL(Array, h);
 
-	RenderTools()->select_sprite(SPRITE_ARMOR_EMPTY);
+	i = 0;
+	RenderTools()->SelectSprite(SPRITE_ARMOR_EMPTY);
 	for(; h < 10; h++)
-		Graphics()->QuadsDrawTL(x+h*12,y+12,10,10);
+		Array[i++] = IGraphics::CQuadItem(x+h*12,y+12,10,10);
+	Graphics()->QuadsDrawTL(Array, i);
 	Graphics()->QuadsEnd();
 }
 
-void HUD::on_render()
+void CHud::OnRender()
 {
-	if(!gameclient.snap.gameobj)
+	if(!m_pClient->m_Snap.m_pGameobj)
 		return;
 		
-	width = 300*Graphics()->ScreenAspect();
+	m_Width = 300*Graphics()->ScreenAspect();
 
-	bool spectate = false;
-	if(gameclient.snap.local_info && gameclient.snap.local_info->team == -1)
-		spectate = true;
+	bool Spectate = false;
+	if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pLocalInfo->m_Team == -1)
+		Spectate = true;
 	
-	if(gameclient.snap.local_character && !spectate && !(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over))
-		render_healthandammo();
-
-	render_goals();
-	render_fps();
-	if(client_state() != CLIENTSTATE_DEMOPLAYBACK)
-		render_connectionwarning();
-	render_teambalancewarning();
-	render_voting();
-	render_cursor();
+	if(m_pClient->m_Snap.m_pLocalCharacter && !Spectate && !(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver))
+		RenderHealthAndAmmo();
+
+	RenderGoals();
+	RenderFps();
+	if(Client()->State() != IClient::STATE_DEMOPLAYBACK)
+		RenderConnectionWarning();
+	RenderTeambalanceWarning();
+	RenderVoting();
+	RenderCursor();
 }
diff --git a/src/game/client/components/hud.h b/src/game/client/components/hud.h
new file mode 100644
index 00000000..43f0e3a8
--- /dev/null
+++ b/src/game/client/components/hud.h
@@ -0,0 +1,27 @@
+#ifndef GAME_CLIENT_COMPONENTS_HUD_H
+#define GAME_CLIENT_COMPONENTS_HUD_H
+#include <game/client/component.h>
+
+class CHud : public CComponent
+{	
+	float m_Width;
+	float m_AverageFPS;
+	
+	void RenderCursor();
+	
+	void RenderFps();
+	void RenderConnectionWarning();
+	void RenderTeambalanceWarning();
+	void RenderVoting();
+	void RenderHealthAndAmmo();
+	void RenderGoals();
+	
+	void MapscreenToGroup(float CenterX, float CenterY, struct CMapItemGroup *PGroup);
+public:
+	CHud();
+	
+	virtual void OnReset();
+	virtual void OnRender();
+};
+
+#endif
diff --git a/src/game/client/components/hud.hpp b/src/game/client/components/hud.hpp
deleted file mode 100644
index 92ff0122..00000000
--- a/src/game/client/components/hud.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <game/client/component.hpp>
-
-class HUD : public COMPONENT
-{	
-	float width;
-	
-	void render_cursor();
-	
-	void render_fps();
-	void render_connectionwarning();
-	void render_teambalancewarning();
-	void render_voting();
-	void render_healthandammo();
-	void render_goals();
-	
-	
-	void mapscreen_to_group(float center_x, float center_y, struct MAPITEM_GROUP *group);
-public:
-	HUD();
-	
-	virtual void on_reset();
-	virtual void on_render();
-};
-
diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp
index 3c9e1b79..70479e53 100644
--- a/src/game/client/components/items.cpp
+++ b/src/game/client/components/items.cpp
@@ -1,94 +1,94 @@
-#include <engine/e_client_interface.h>
-#include <engine/client/graphics.h>
-#include <game/generated/g_protocol.hpp>
-#include <game/generated/gc_data.hpp>
+#include <engine/graphics.h>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
 
-#include <game/gamecore.hpp> // get_angle
-#include <game/client/gameclient.hpp>
-#include <game/client/ui.hpp>
-#include <game/client/render.hpp>
+#include <game/gamecore.h> // get_angle
+#include <game/client/gameclient.h>
+#include <game/client/ui.h>
+#include <game/client/render.h>
 
-#include <game/client/components/flow.hpp>
-#include <game/client/components/effects.hpp>
+#include <game/client/components/flow.h>
+#include <game/client/components/effects.h>
 
-#include "items.hpp"
+#include "items.h"
 
-void ITEMS::render_projectile(const NETOBJ_PROJECTILE *current, int itemid)
+void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemId)
 {
 
 	// get positions
-	float curvature = 0;
-	float speed = 0;
-	if(current->type == WEAPON_GRENADE)
+	float Curvature = 0;
+	float Speed = 0;
+	if(pCurrent->m_Type == WEAPON_GRENADE)
 	{
-		curvature = gameclient.tuning.grenade_curvature;
-		speed = gameclient.tuning.grenade_speed;
+		Curvature = m_pClient->m_Tuning.m_GrenadeCurvature;
+		Speed = m_pClient->m_Tuning.m_GrenadeSpeed;
 	}
-	else if(current->type == WEAPON_SHOTGUN)
+	else if(pCurrent->m_Type == WEAPON_SHOTGUN)
 	{
-		curvature = gameclient.tuning.shotgun_curvature;
-		speed = gameclient.tuning.shotgun_speed;
+		Curvature = m_pClient->m_Tuning.m_ShotgunCurvature;
+		Speed = m_pClient->m_Tuning.m_ShotgunSpeed;
 	}
-	else if(current->type == WEAPON_GUN)
+	else if(pCurrent->m_Type == WEAPON_GUN)
 	{
-		curvature = gameclient.tuning.gun_curvature;
-		speed = gameclient.tuning.gun_speed;
+		Curvature = m_pClient->m_Tuning.m_GunCurvature;
+		Speed = m_pClient->m_Tuning.m_GunSpeed;
 	}
 
-	float ct = (client_prevtick()-current->start_tick)/(float)SERVER_TICK_SPEED + client_ticktime();
-	if(ct < 0)
+	float Ct = (Client()->PrevGameTick()-pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime();
+	if(Ct < 0)
 		return; // projectile havn't been shot yet
 		
-	vec2 startpos(current->x, current->y);
-	vec2 startvel(current->vx/100.0f, current->vy/100.0f);
-	vec2 pos = calc_pos(startpos, startvel, curvature, speed, ct);
-	vec2 prevpos = calc_pos(startpos, startvel, curvature, speed, ct-0.001f);
+	vec2 StartPos(pCurrent->m_X, pCurrent->m_Y);
+	vec2 StartVel(pCurrent->m_VelX/100.0f, pCurrent->m_VelY/100.0f);
+	vec2 Pos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct);
+	vec2 PrevPos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct-0.001f);
 
 
-	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 	Graphics()->QuadsBegin();
 	
-	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());
+	RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Type, 0, NUM_WEAPONS-1)].m_pSpriteProj);
+	vec2 Vel = Pos-PrevPos;
+	//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), Client()->IntraGameTick());
 	
 
 	// add particle for this projectile
-	if(current->type == WEAPON_GRENADE)
+	if(pCurrent->m_Type == WEAPON_GRENADE)
 	{
-		gameclient.effects->smoketrail(pos, vel*-1);
-		gameclient.flow->add(pos, vel*1000*client_frametime(), 10.0f);
-		Graphics()->QuadsSetRotation(client_localtime()*pi*2*2 + itemid);
+		m_pClient->m_pEffects->SmokeTrail(Pos, Vel*-1);
+		m_pClient->m_pFlow->Add(Pos, Vel*1000*Client()->FrameTime(), 10.0f);
+		Graphics()->QuadsSetRotation(Client()->LocalTime()*pi*2*2 + ItemId);
 	}
 	else
 	{
-		gameclient.effects->bullettrail(pos);
-		gameclient.flow->add(pos, vel*1000*client_frametime(), 10.0f);
+		m_pClient->m_pEffects->BulletTrail(Pos);
+		m_pClient->m_pFlow->Add(Pos, Vel*1000*Client()->FrameTime(), 10.0f);
 
-		if(length(vel) > 0.00001f)
-			Graphics()->QuadsSetRotation(get_angle(vel));
+		if(length(Vel) > 0.00001f)
+			Graphics()->QuadsSetRotation(GetAngle(Vel));
 		else
 			Graphics()->QuadsSetRotation(0);
 
 	}
 
-	Graphics()->QuadsDraw(pos.x, pos.y, 32, 32);
+	IGraphics::CQuadItem QuadItem(Pos.x, Pos.y, 32, 32);
+	Graphics()->QuadsDraw(&QuadItem, 1);
 	Graphics()->QuadsSetRotation(0);
 	Graphics()->QuadsEnd();
 }
 
-void ITEMS::render_pickup(const NETOBJ_PICKUP *prev, const NETOBJ_PICKUP *current)
+void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent)
 {
-	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_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)
+	vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick());
+	float Angle = 0.0f;
+	float Size = 64.0f;
+	if (pCurrent->m_Type == POWERUP_WEAPON)
 	{
-		angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
-		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;
+		Angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
+		RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS-1)].m_pSpriteBody);
+		Size = g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS-1)].m_VisualSize;
 	}
 	else
 	{
@@ -98,69 +98,70 @@ void ITEMS::render_pickup(const NETOBJ_PICKUP *prev, const NETOBJ_PICKUP *curren
 			SPRITE_PICKUP_WEAPON,
 			SPRITE_PICKUP_NINJA
 			};
-		RenderTools()->select_sprite(c[current->type]);
+		RenderTools()->SelectSprite(c[pCurrent->m_Type]);
 
-		if(c[current->type] == SPRITE_PICKUP_NINJA)
+		if(c[pCurrent->m_Type] == SPRITE_PICKUP_NINJA)
 		{
-			gameclient.effects->powerupshine(pos, vec2(96,18));
-			size *= 2.0f;
-			pos.x += 10.0f;
+			m_pClient->m_pEffects->PowerupShine(Pos, vec2(96,18));
+			Size *= 2.0f;
+			Pos.x += 10.0f;
 		}
 	}
 
-	Graphics()->QuadsSetRotation(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;
-	RenderTools()->draw_sprite(pos.x, pos.y, size);
+	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;
+	RenderTools()->DrawSprite(Pos.x, Pos.y, Size);
 	Graphics()->QuadsEnd();
 }
 
-void ITEMS::render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current)
+void CItems::RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent)
 {
-	float angle = 0.0f;
-	float size = 42.0f;
+	float Angle = 0.0f;
+	float Size = 42.0f;
 
 	Graphics()->BlendNormal();
-	Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 	Graphics()->QuadsBegin();
 
-	if(current->team == 0) // red team
-		RenderTools()->select_sprite(SPRITE_FLAG_RED);
+	if(pCurrent->m_Team == 0) // red team
+		RenderTools()->SelectSprite(SPRITE_FLAG_RED);
 	else
-		RenderTools()->select_sprite(SPRITE_FLAG_BLUE);
+		RenderTools()->SelectSprite(SPRITE_FLAG_BLUE);
 
-	Graphics()->QuadsSetRotation(angle);
+	Graphics()->QuadsSetRotation(Angle);
 
-	vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
+	vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick());
 	
 	// make sure that the flag isn't interpolated between capture and return
-	if(prev->carried_by != current->carried_by)
-		pos = vec2(current->x, current->y);
+	if(pPrev->m_CarriedBy != pCurrent->m_CarriedBy)
+		Pos = vec2(pCurrent->m_X, pCurrent->m_Y);
 
 	// make sure to use predicted position if we are the carrier
-	if(gameclient.snap.local_info && current->carried_by == gameclient.snap.local_info->cid)
-		pos = gameclient.local_character_pos;
+	if(m_pClient->m_Snap.m_pLocalInfo && pCurrent->m_CarriedBy == m_pClient->m_Snap.m_pLocalInfo->m_ClientId)
+		Pos = m_pClient->m_LocalCharacterPos;
 
-	Graphics()->QuadsDraw(pos.x, pos.y-size*0.75f, size, size*2);
+	IGraphics::CQuadItem QuadItem(Pos.x, Pos.y-Size*0.75f, Size, Size*2);
+	Graphics()->QuadsDraw(&QuadItem, 1);
 	Graphics()->QuadsEnd();
 }
 
 
-void ITEMS::render_laser(const struct NETOBJ_LASER *current)
+void CItems::RenderLaser(const struct CNetObj_Laser *pCurrent)
 {
-	vec2 pos = vec2(current->x, current->y);
-	vec2 from = vec2(current->from_x, current->from_y);
-	vec2 dir = normalize(pos-from);
+	vec2 Pos = vec2(pCurrent->m_X, pCurrent->m_Y);
+	vec2 From = vec2(pCurrent->m_FromX, pCurrent->m_FromY);
+	vec2 Dir = normalize(Pos-From);
 
-	float ticks = client_tick() + client_intratick() - current->start_tick;
-	float ms = (ticks/50.0f) * 1000.0f;
-	float a =  ms / gameclient.tuning.laser_bounce_delay;
+	float Ticks = Client()->GameTick() + Client()->IntraGameTick() - pCurrent->m_StartTick;
+	float Ms = (Ticks/50.0f) * 1000.0f;
+	float a =  Ms / m_pClient->m_Tuning.m_LaserBounceDelay;
 	a = clamp(a, 0.0f, 1.0f);
-	float ia = 1-a;
+	float Ia = 1-a;
 	
-	vec2 out, border;
+	vec2 Out, Border;
 	
 	Graphics()->BlendNormal();
 	Graphics()->TextureSet(-1);
@@ -170,77 +171,87 @@ void ITEMS::render_laser(const struct NETOBJ_LASER *current)
 	//vec4 outer_color(0.65f,0.85f,1.0f,1.0f);
 
 	// do outline
-	vec4 outer_color(0.075f,0.075f,0.25f,1.0f);
-	Graphics()->SetColor(outer_color.r,outer_color.g,outer_color.b,1.0f);
-	out = vec2(dir.y, -dir.x) * (7.0f*ia);
+	vec4 OuterColor(0.075f, 0.075f, 0.25f, 1.0f);
+	Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f);
+	Out = vec2(Dir.y, -Dir.x) * (7.0f*Ia);
 
-	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
-		);
+	IGraphics::CFreeformItem Freeform(
+			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);
+	Graphics()->QuadsDrawFreeform(&Freeform, 1);
 
 	// do inner	
-	vec4 inner_color(0.5f,0.5f,1.0f,1.0f);
-	out = vec2(dir.y, -dir.x) * (5.0f*ia);
-	Graphics()->SetColor(inner_color.r, inner_color.g, inner_color.b, 1.0f); // center
+	vec4 InnerColor(0.5f, 0.5f, 1.0f, 1.0f);
+	Out = vec2(Dir.y, -Dir.x) * (5.0f*Ia);
+	Graphics()->SetColor(InnerColor.r, InnerColor.g, InnerColor.b, 1.0f); // center
 	
-	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
-		);
+	Freeform = IGraphics::CFreeformItem(
+			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);
+	Graphics()->QuadsDrawFreeform(&Freeform, 1);
 		
 	Graphics()->QuadsEnd();
 	
 	// render head
 	{
 		Graphics()->BlendNormal();
-		Graphics()->TextureSet(data->images[IMAGE_PARTICLES].id);
+		Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id);
 		Graphics()->QuadsBegin();
 
-		int sprites[] = {SPRITE_PART_SPLAT01, SPRITE_PART_SPLAT02, SPRITE_PART_SPLAT03};
-		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);
+		int Sprites[] = {SPRITE_PART_SPLAT01, SPRITE_PART_SPLAT02, SPRITE_PART_SPLAT03};
+		RenderTools()->SelectSprite(Sprites[Client()->GameTick()%3]);
+		Graphics()->QuadsSetRotation(Client()->GameTick());
+		Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f);
+		IGraphics::CQuadItem QuadItem(Pos.x, Pos.y, 24, 24);
+		Graphics()->QuadsDraw(&QuadItem, 1);
+		Graphics()->SetColor(InnerColor.r, InnerColor.g, InnerColor.b, 1.0f);
+		QuadItem = IGraphics::CQuadItem(Pos.x, Pos.y, 20, 20);
+		Graphics()->QuadsDraw(&QuadItem, 1);
 		Graphics()->QuadsEnd();
 	}
 	
 	Graphics()->BlendNormal();	
 }
 
-void ITEMS::on_render()
+void CItems::OnRender()
 {
-	int num = snap_num_items(SNAP_CURRENT);
-	for(int i = 0; i < num; i++)
+	int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT);
+	for(int i = 0; i < Num; i++)
 	{
-		SNAP_ITEM item;
-		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
+		IClient::CSnapItem Item;
+		const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item);
 
-		if(item.type == NETOBJTYPE_PROJECTILE)
+		if(Item.m_Type == NETOBJTYPE_PROJECTILE)
 		{
-			render_projectile((const NETOBJ_PROJECTILE *)data, item.id);
+			RenderProjectile((const CNetObj_Projectile *)pData, Item.m_Id);
 		}
-		else if(item.type == NETOBJTYPE_PICKUP)
+		else if(Item.m_Type == NETOBJTYPE_PICKUP)
 		{
-			const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
-			if(prev)
-				render_pickup((const NETOBJ_PICKUP *)prev, (const NETOBJ_PICKUP *)data);
+			const void *pPrev = Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_Id);
+			if(pPrev)
+				RenderPickup((const CNetObj_Pickup *)pPrev, (const CNetObj_Pickup *)pData);
 		}
-		else if(item.type == NETOBJTYPE_LASER)
+		else if(Item.m_Type == NETOBJTYPE_LASER)
 		{
-			render_laser((const NETOBJ_LASER *)data);
+			RenderLaser((const CNetObj_Laser *)pData);
 		}
-		else if(item.type == NETOBJTYPE_FLAG)
+	}
+
+	// render flag
+	for(int i = 0; i < Num; i++)
+	{
+		IClient::CSnapItem Item;
+		const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item);
+
+		if(Item.m_Type == NETOBJTYPE_FLAG)
 		{
-			const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
-			if (prev)
-				render_flag((const NETOBJ_FLAG *)prev, (const NETOBJ_FLAG *)data);
+			const void *pPrev = Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_Id);
+			if (pPrev)
+				RenderFlag((const CNetObj_Flag *)pPrev, (const CNetObj_Flag *)pData);
 		}
 	}
 
@@ -248,7 +259,7 @@ void ITEMS::on_render()
 	/*
 	for(int i = 0; i < extraproj_num; i++)
 	{
-		if(extraproj_projectiles[i].start_tick < client_tick())
+		if(extraproj_projectiles[i].start_tick < Client()->GameTick())
 		{
 			extraproj_projectiles[i] = extraproj_projectiles[extraproj_num-1];
 			extraproj_num--;
diff --git a/src/game/client/components/items.h b/src/game/client/components/items.h
new file mode 100644
index 00000000..e4525546
--- /dev/null
+++ b/src/game/client/components/items.h
@@ -0,0 +1,16 @@
+#ifndef GAME_CLIENT_COMPONENTS_ITEMS_H
+#define GAME_CLIENT_COMPONENTS_ITEMS_H
+#include <game/client/component.h>
+
+class CItems : public CComponent
+{	
+	void RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemId);
+	void RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent);
+	void RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent);
+	void RenderLaser(const struct CNetObj_Laser *pCurrent);
+	
+public:
+	virtual void OnRender();
+};
+
+#endif
diff --git a/src/game/client/components/items.hpp b/src/game/client/components/items.hpp
deleted file mode 100644
index 2f33c8c4..00000000
--- a/src/game/client/components/items.hpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <game/client/component.hpp>
-
-class ITEMS : public COMPONENT
-{	
-	void render_projectile(const NETOBJ_PROJECTILE *current, int itemid);
-	void render_pickup(const NETOBJ_PICKUP *prev, const NETOBJ_PICKUP *current);
-	void render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current);
-	void render_laser(const struct NETOBJ_LASER *current);
-	
-public:
-	virtual void on_render();
-};
-
diff --git a/src/game/client/components/killmessages.cpp b/src/game/client/components/killmessages.cpp
index e6232b7d..d18dd965 100644
--- a/src/game/client/components/killmessages.cpp
+++ b/src/game/client/components/killmessages.cpp
@@ -1,127 +1,129 @@
-#include <engine/e_client_interface.h>
-#include <engine/client/graphics.h>
-#include <game/generated/g_protocol.hpp>
-#include <game/generated/gc_data.hpp>
+#include <engine/graphics.h>
+#include <engine/textrender.h>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
 
-#include <game/client/gameclient.hpp>
-#include <game/client/animstate.hpp>
-#include "killmessages.hpp"
+#include <game/client/gameclient.h>
+#include <game/client/animstate.h>
+#include "killmessages.h"
 
-void KILLMESSAGES::on_reset()
+void CKillMessages::OnReset()
 {
-	killmsg_current = 0;
-	for(int i = 0; i < killmsg_max; i++)
-		killmsgs[i].tick = -100000;
+	m_KillmsgCurrent = 0;
+	for(int i = 0; i < MAX_KILLMSGS; i++)
+		m_aKillmsgs[i].m_Tick = -100000;
 }
 
-void KILLMESSAGES::on_message(int msgtype, void *rawmsg)
+void CKillMessages::OnMessage(int MsgType, void *pRawMsg)
 {
-	if(msgtype == NETMSGTYPE_SV_KILLMSG)
+	if(MsgType == NETMSGTYPE_SV_KILLMSG)
 	{
-		NETMSG_SV_KILLMSG *msg = (NETMSG_SV_KILLMSG *)rawmsg;
+		CNetMsg_Sv_KillMsg *pMsg = (CNetMsg_Sv_KillMsg *)pRawMsg;
 		
 		// unpack messages
-		KILLMSG kill;
-		kill.killer = msg->killer;
-		kill.victim = msg->victim;
-		kill.weapon = msg->weapon;
-		kill.mode_special = msg->mode_special;
-		kill.tick = client_tick();
+		CKillMsg Kill;
+		Kill.m_Killer = pMsg->m_Killer;
+		Kill.m_Victim = pMsg->m_Victim;
+		Kill.m_Weapon = pMsg->m_Weapon;
+		Kill.m_ModeSpecial = pMsg->m_ModeSpecial;
+		Kill.m_Tick = Client()->GameTick();
 
 		// add the message
-		killmsg_current = (killmsg_current+1)%killmsg_max;
-		killmsgs[killmsg_current] = kill;		
+		m_KillmsgCurrent = (m_KillmsgCurrent+1)%MAX_KILLMSGS;
+		m_aKillmsgs[m_KillmsgCurrent] = Kill;
 	}
 }
 
-void KILLMESSAGES::on_render()
+void CKillMessages::OnRender()
 {
-	float width = 400*3.0f*Graphics()->ScreenAspect();
-	float height = 400*3.0f;
+	float Width = 400*3.0f*Graphics()->ScreenAspect();
+	float Height = 400*3.0f;
 
-	Graphics()->MapScreen(0, 0, width*1.5f, height*1.5f);
-	float startx = width*1.5f-10.0f;
+	Graphics()->MapScreen(0, 0, Width*1.5f, Height*1.5f);
+	float StartX = Width*1.5f-10.0f;
 	float y = 20.0f;
 
-	for(int i = 0; i < killmsg_max; i++)
+	for(int i = 0; i < MAX_KILLMSGS; i++)
 	{
 
-		int r = (killmsg_current+i+1)%killmsg_max;
-		if(client_tick() > killmsgs[r].tick+50*10)
+		int r = (m_KillmsgCurrent+i+1)%MAX_KILLMSGS;
+		if(Client()->GameTick() > m_aKillmsgs[r].m_Tick+50*10)
 			continue;
 
-		float font_size = 36.0f;
-		float killername_w = gfx_text_width(0, font_size, gameclient.clients[killmsgs[r].killer].name, -1);
-		float victimname_w = gfx_text_width(0, font_size, gameclient.clients[killmsgs[r].victim].name, -1);
+		float FontSize = 36.0f;
+		float KillerNameW = TextRender()->TextWidth(0, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_aName, -1);
+		float VictimNameW = TextRender()->TextWidth(0, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_aName, -1);
 
-		float x = startx;
+		float x = StartX;
 
 		// render victim name
-		x -= victimname_w;
-		gfx_text(0, x, y, font_size, gameclient.clients[killmsgs[r].victim].name, -1);
+		x -= VictimNameW;
+		TextRender()->Text(0, x, y, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_aName, -1);
 
 		// render victim tee
 		x -= 24.0f;
 		
-		if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_FLAGS)
+		if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_FLAGS)
 		{
-			if(killmsgs[r].mode_special&1)
+			if(m_aKillmsgs[r].m_ModeSpecial&1)
 			{
 				Graphics()->BlendNormal();
-				Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+				Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 				Graphics()->QuadsBegin();
 
-				if(gameclient.clients[killmsgs[r].victim].team == 0) RenderTools()->select_sprite(SPRITE_FLAG_BLUE);
-				else RenderTools()->select_sprite(SPRITE_FLAG_RED);
+				if(m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_Team == 0) RenderTools()->SelectSprite(SPRITE_FLAG_BLUE);
+				else RenderTools()->SelectSprite(SPRITE_FLAG_RED);
 				
-				float size = 56.0f;
-				Graphics()->QuadsDrawTL(x, y-16, size/2, size);
+				float Size = 56.0f;
+				IGraphics::CQuadItem QuadItem(x, y-16, Size/2, Size);
+				Graphics()->QuadsDrawTL(&QuadItem, 1);
 				Graphics()->QuadsEnd();					
 			}
 		}
 		
-		RenderTools()->RenderTee(ANIMSTATE::get_idle(), &gameclient.clients[killmsgs[r].victim].render_info, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28));
+		RenderTools()->RenderTee(CAnimState::GetIdle(), &m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_RenderInfo, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28));
 		x -= 32.0f;
 		
 		// render weapon
 		x -= 44.0f;
-		if (killmsgs[r].weapon >= 0)
+		if (m_aKillmsgs[r].m_Weapon >= 0)
 		{
-			Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+			Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 			Graphics()->QuadsBegin();
-			RenderTools()->select_sprite(data->weapons.id[killmsgs[r].weapon].sprite_body);
-			RenderTools()->draw_sprite(x, y+28, 96);
+			RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[m_aKillmsgs[r].m_Weapon].m_pSpriteBody);
+			RenderTools()->DrawSprite(x, y+28, 96);
 			Graphics()->QuadsEnd();
 		}
 		x -= 52.0f;
 
-		if(killmsgs[r].victim != killmsgs[r].killer)
+		if(m_aKillmsgs[r].m_Victim != m_aKillmsgs[r].m_Killer)
 		{
-			if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_FLAGS)
+			if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_FLAGS)
 			{
-				if(killmsgs[r].mode_special&2)
+				if(m_aKillmsgs[r].m_ModeSpecial&2)
 				{
 					Graphics()->BlendNormal();
-					Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+					Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 					Graphics()->QuadsBegin();
 
-					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);
+					if(m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_Team == 0) RenderTools()->SelectSprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
+					else RenderTools()->SelectSprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
 					
-					float size = 56.0f;
-					Graphics()->QuadsDrawTL(x-56, y-16, size/2, size);
+					float Size = 56.0f;
+					IGraphics::CQuadItem QuadItem(x-56, y-16, Size/2, Size);
+					Graphics()->QuadsDrawTL(&QuadItem, 1);
 					Graphics()->QuadsEnd();				
 				}
 			}				
 			
 			// render killer tee
 			x -= 24.0f;
-			RenderTools()->RenderTee(ANIMSTATE::get_idle(), &gameclient.clients[killmsgs[r].killer].render_info, EMOTE_ANGRY, vec2(1,0), vec2(x, y+28));
+			RenderTools()->RenderTee(CAnimState::GetIdle(), &m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_RenderInfo, EMOTE_ANGRY, vec2(1,0), vec2(x, y+28));
 			x -= 32.0f;
 
 			// render killer name
-			x -= killername_w;
-			gfx_text(0, x, y, font_size, gameclient.clients[killmsgs[r].killer].name, -1);
+			x -= KillerNameW;
+			TextRender()->Text(0, x, y, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_aName, -1);
 		}
 
 		y += 44;
diff --git a/src/game/client/components/killmessages.h b/src/game/client/components/killmessages.h
new file mode 100644
index 00000000..720b10ae
--- /dev/null
+++ b/src/game/client/components/killmessages.h
@@ -0,0 +1,31 @@
+#ifndef GAME_CLIENT_COMPONENTS_KILLMESSAGES_H
+#define GAME_CLIENT_COMPONENTS_KILLMESSAGES_H
+#include <game/client/component.h>
+
+class CKillMessages : public CComponent
+{
+public:
+	// kill messages
+	struct CKillMsg
+	{
+		int m_Weapon;
+		int m_Victim;
+		int m_Killer;
+		int m_ModeSpecial; // for CTF, if the guy is carrying a flag for example
+		int m_Tick;
+	};
+	
+	enum
+	{
+		MAX_KILLMSGS = 5,
+	};
+
+	CKillMsg m_aKillmsgs[MAX_KILLMSGS];
+	int m_KillmsgCurrent;
+
+	virtual void OnReset();
+	virtual void OnRender();
+	virtual void OnMessage(int MsgType, void *pRawMsg);
+};
+
+#endif
diff --git a/src/game/client/components/killmessages.hpp b/src/game/client/components/killmessages.hpp
deleted file mode 100644
index f29e0bdf..00000000
--- a/src/game/client/components/killmessages.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <game/client/component.hpp>
-
-class KILLMESSAGES : public COMPONENT
-{
-public:
-	// kill messages
-	struct KILLMSG
-	{
-		int weapon;
-		int victim;
-		int killer;
-		int mode_special; // for CTF, if the guy is carrying a flag for example
-		int tick;
-	};
-
-	static const int killmsg_max = 5;
-	KILLMSG killmsgs[killmsg_max];
-	int killmsg_current;
-
-	virtual void on_reset();
-	virtual void on_render();
-	virtual void on_message(int msgtype, void *rawmsg);
-};
-
diff --git a/src/game/client/components/mapimages.cpp b/src/game/client/components/mapimages.cpp
index 51194853..9be450d1 100644
--- a/src/game/client/components/mapimages.cpp
+++ b/src/game/client/components/mapimages.cpp
@@ -1,45 +1,48 @@
-#include <engine/client/graphics.h>
-#include <game/client/component.hpp>
-#include <game/mapitems.hpp>
+#include <engine/graphics.h>
+#include <engine/map.h>
+#include <game/client/component.h>
+#include <game/mapitems.h>
 
-#include "mapimages.hpp"
+#include "mapimages.h"
 
-MAPIMAGES::MAPIMAGES()
+CMapImages::CMapImages()
 {
-	count = 0;
+	m_Count = 0;
 }
 
-void MAPIMAGES::on_mapload()
+void CMapImages::OnMapLoad()
 {
+	IMap *pMap = Kernel()->RequestInterface<IMap>();
+	
 	// unload all textures
-	for(int i = 0; i < count; i++)
+	for(int i = 0; i < m_Count; i++)
 	{
-		Graphics()->UnloadTexture(textures[i]);
-		textures[i] = -1;
+		Graphics()->UnloadTexture(m_aTextures[i]);
+		m_aTextures[i] = -1;
 	}
-	count = 0;
+	m_Count = 0;
 
-	int start;
-	map_get_type(MAPITEMTYPE_IMAGE, &start, &count);
+	int Start;
+	pMap->GetType(MAPITEMTYPE_IMAGE, &Start, &m_Count);
 	
 	// load new textures
-	for(int i = 0; i < count; i++)
+	for(int i = 0; i < m_Count; i++)
 	{
-		textures[i] = 0;
+		m_aTextures[i] = 0;
 		
-		MAPITEM_IMAGE *img = (MAPITEM_IMAGE *)map_get_item(start+i, 0, 0);
-		if(img->external)
+		CMapItemImage *pImg = (CMapItemImage *)pMap->GetItem(Start+i, 0, 0);
+		if(pImg->m_External)
 		{
-			char buf[256];
-			char *name = (char *)map_get_data(img->image_name);
-			str_format(buf, sizeof(buf), "mapres/%s.png", name);
-			textures[i] = Graphics()->LoadTexture(buf, IMG_AUTO, 0);
+			char Buf[256];
+			char *pName = (char *)pMap->GetData(pImg->m_ImageName);
+			str_format(Buf, sizeof(Buf), "mapres/%s.png", pName);
+			m_aTextures[i] = Graphics()->LoadTexture(Buf, CImageInfo::FORMAT_AUTO, 0);
 		}
 		else
 		{
-			void *data = map_get_data(img->image_data);
-			textures[i] = Graphics()->LoadTextureRaw(img->width, img->height, IMG_RGBA, data, IMG_RGBA, 0);
-			map_unload_data(img->image_data);
+			void *pData = pMap->GetData(pImg->m_ImageData);
+			m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, CImageInfo::FORMAT_RGBA, pData, CImageInfo::FORMAT_RGBA, 0);
+			pMap->UnloadData(pImg->m_ImageData);
 		}
 	}
 }
diff --git a/src/game/client/components/mapimages.h b/src/game/client/components/mapimages.h
new file mode 100644
index 00000000..2ef5fc32
--- /dev/null
+++ b/src/game/client/components/mapimages.h
@@ -0,0 +1,18 @@
+#ifndef GAME_CLIENT_COMPONENTS_MAPIMAGES_H
+#define GAME_CLIENT_COMPONENTS_MAPIMAGES_H
+#include <game/client/component.h>
+
+class CMapImages : public CComponent
+{	
+	int m_aTextures[64];
+	int m_Count;
+public:
+	CMapImages();
+	
+	int Get(int Index) const { return m_aTextures[Index]; }
+	int Num() const { return m_Count; }
+
+	virtual void OnMapLoad();
+};
+
+#endif
diff --git a/src/game/client/components/mapimages.hpp b/src/game/client/components/mapimages.hpp
deleted file mode 100644
index cba46033..00000000
--- a/src/game/client/components/mapimages.hpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <game/client/component.hpp>
-
-class MAPIMAGES : public COMPONENT
-{	
-	int textures[64];
-	int count;
-public:
-	MAPIMAGES();
-	
-	int get(int index) const { return textures[index]; }
-	int num() const { return count; }
-
-	virtual void on_mapload();
-};
-
diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp
index 75f91521..202ea2da 100644
--- a/src/game/client/components/maplayers.cpp
+++ b/src/game/client/components/maplayers.cpp
@@ -1,167 +1,192 @@
-#include <engine/client/graphics.h>
+#include <stdio.h>
+#include <engine/graphics.h>
+#include <engine/keys.h> //temp
+#include <engine/shared/config.h>
 
-#include <game/layers.hpp>
-#include <game/client/gameclient.hpp>
-#include <game/client/component.hpp>
-#include <game/client/render.hpp>
+#include <game/layers.h>
+#include <game/client/gameclient.h>
+#include <game/client/component.h>
+#include <game/client/render.h>
 
-#include <game/client/components/camera.hpp>
-#include <game/client/components/mapimages.hpp>
+#include <game/client/components/camera.h>
+#include <game/client/components/mapimages.h>
 
 
-#include "maplayers.hpp"
+#include "maplayers.h"
 
-MAPLAYERS::MAPLAYERS(int t)
+CMapLayers::CMapLayers(int t)
 {
-	type = t;
+	m_Type = t;
+	m_pLayers = 0;
 }
 
+void CMapLayers::OnInit()
+{
+	m_pLayers = Layers();
+}
 
-void MAPLAYERS::mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *group)
+
+void CMapLayers::MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup)
 {
-	float points[4];
-	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]);
+	float Points[4];
+	RenderTools()->MapscreenToWorld(CenterX, CenterY, pGroup->m_ParallaxX/100.0f, pGroup->m_ParallaxY/100.0f,
+		pGroup->m_OffsetX, pGroup->m_OffsetY, Graphics()->ScreenAspect(), 1.0f, Points);
+	Graphics()->MapScreen(Points[0], Points[1], Points[2], Points[3]);
 }
 
-void MAPLAYERS::envelope_eval(float time_offset, int env, float *channels, void *user)
+void CMapLayers::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser)
 {
-	MAPLAYERS *pThis = (MAPLAYERS *)user;
-	channels[0] = 0;
-	channels[1] = 0;
-	channels[2] = 0;
-	channels[3] = 0;
+	CMapLayers *pThis = (CMapLayers *)pUser;
+	pChannels[0] = 0;
+	pChannels[1] = 0;
+	pChannels[2] = 0;
+	pChannels[3] = 0;
 
-	ENVPOINT *points;
+	CEnvPoint *pPoints;
 
 	{
-		int start, num;
-		map_get_type(MAPITEMTYPE_ENVPOINTS, &start, &num);
-		if(num)
-			points = (ENVPOINT *)map_get_item(start, 0, 0);
+		int Start, Num;
+		pThis->m_pLayers->Map()->GetType(MAPITEMTYPE_ENVPOINTS, &Start, &Num);
+		if(Num)
+			pPoints = (CEnvPoint *)pThis->m_pLayers->Map()->GetItem(Start, 0, 0);
 	}
 	
-	int start, num;
-	map_get_type(MAPITEMTYPE_ENVELOPE, &start, &num);
+	int Start, Num;
+	pThis->m_pLayers->Map()->GetType(MAPITEMTYPE_ENVELOPE, &Start, &Num);
 	
-	if(env >= num)
+	if(Env >= Num)
 		return;
 	
-	MAPITEM_ENVELOPE *item = (MAPITEM_ENVELOPE *)map_get_item(start+env, 0, 0);
-	pThis->RenderTools()->render_eval_envelope(points+item->start_point, item->num_points, 4, client_localtime()+time_offset, channels);
+	CMapItemEnvelope *pItem = (CMapItemEnvelope *)pThis->m_pLayers->Map()->GetItem(Start+Env, 0, 0);
+	pThis->RenderTools()->RenderEvalEnvelope(pPoints+pItem->m_StartPoint, pItem->m_NumPoints, 4, pThis->Client()->LocalTime()+TimeOffset, pChannels);
 }
 
-void MAPLAYERS::on_render()
+void CMapLayers::OnRender()
 {
-	if(client_state() != CLIENTSTATE_ONLINE && client_state() != CLIENTSTATE_DEMOPLAYBACK)
+	if(Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK)
 		return;
 	
-	CUIRect screen;
-	Graphics()->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;
+	vec2 Center = m_pClient->m_pCamera->m_Center;
 	//float center_x = gameclient.camera->center.x;
 	//float center_y = gameclient.camera->center.y;
 	
-	bool passed_gamelayer = false;
+	bool PassedGameLayer = false;
 	
-	for(int g = 0; g < layers_num_groups(); g++)
+	for(int g = 0; g < m_pLayers->NumGroups(); g++)
 	{
-		MAPITEM_GROUP *group = layers_get_group(g);
+		CMapItemGroup *pGroup = m_pLayers->GetGroup(g);
 		
-		if(!config.gfx_noclip && group->version >= 2 && group->use_clipping)
+		if(!g_Config.m_GfxNoclip && pGroup->m_Version >= 2 && pGroup->m_UseClipping)
 		{
 			// set clipping
-			float points[4];
-			mapscreen_to_group(center.x, center.y, layers_game_group());
-			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]);
+			float Points[4];
+			MapScreenToGroup(Center.x, Center.y, m_pLayers->GameGroup());
+			Graphics()->GetScreen(&Points[0], &Points[1], &Points[2], &Points[3]);
+			float x0 = (pGroup->m_ClipX - Points[0]) / (Points[2]-Points[0]);
+			float y0 = (pGroup->m_ClipY - Points[1]) / (Points[3]-Points[1]);
+			float x1 = ((pGroup->m_ClipX+pGroup->m_ClipW) - Points[0]) / (Points[2]-Points[0]);
+			float y1 = ((pGroup->m_ClipY+pGroup->m_ClipH) - Points[1]) / (Points[3]-Points[1]);
 			
 			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);
+		MapScreenToGroup(Center.x, Center.y, pGroup);
 		
-		for(int l = 0; l < group->num_layers; l++)
+		for(int l = 0; l < pGroup->m_NumLayers; l++)
 		{
-			MAPITEM_LAYER *layer = layers_get_layer(group->start_layer+l);
-			bool render = false;
-			bool is_game_layer = false;
+			CMapItemLayer *pLayer = m_pLayers->GetLayer(pGroup->m_StartLayer+l);
+			bool Render = false;
+			bool IsGameLayer = false;
 			
-			if(layer == (MAPITEM_LAYER*)layers_game_layer())
+			if(pLayer == (CMapItemLayer*)m_pLayers->GameLayer())
 			{
-				is_game_layer = true;
-				passed_gamelayer = 1;
+				IsGameLayer = true;
+				PassedGameLayer = 1;
 			}
 			
 			// skip rendering if detail layers if not wanted
-			if(layer->flags&LAYERFLAG_DETAIL && !config.gfx_high_detail && !is_game_layer)
+			if(pLayer->m_Flags&LAYERFLAG_DETAIL && !g_Config.m_GfxHighDetail && !IsGameLayer)
 				continue;
 				
-			if(type == -1)
-				render = true;
-			else if(type == 0)
+			if(m_Type == -1)
+				Render = true;
+			else if(m_Type == 0)
 			{
-				if(passed_gamelayer)
+				if(PassedGameLayer)
 					return;
-				render = true;
+				Render = true;
 			}
 			else
 			{
-				if(passed_gamelayer && !is_game_layer)
-					render = true;
+				if(PassedGameLayer && !IsGameLayer)
+					Render = true;
 			}
 			
-			if(render && !is_game_layer)
+			if(pLayer->m_Type == LAYERTYPE_TILES && Input()->KeyPressed(KEY_KP0))
+			{
+				CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
+				CTile *pTiles = (CTile *)m_pLayers->Map()->GetData(pTMap->m_Data);
+				char buf[256];
+				str_format(buf, sizeof(buf), "%d%d_%dx%d", g, l, pTMap->m_Width, pTMap->m_Height);
+				FILE *f = fopen(buf, "w");
+				for(int y = 0; y < pTMap->m_Height; y++)
+				{
+					for(int x = 0; x < pTMap->m_Width; x++)
+						fprintf(f, "%d,", pTiles[y*pTMap->m_Width + x].m_Index);
+					fprintf(f, "\n");
+				}
+				fclose(f);
+			}			
+			
+			if(Render && !IsGameLayer)
 			{
 				//layershot_begin();
 				
-				if(layer->type == LAYERTYPE_TILES)
+				if(pLayer->m_Type == LAYERTYPE_TILES)
 				{
-					MAPITEM_LAYER_TILEMAP *tmap = (MAPITEM_LAYER_TILEMAP *)layer;
-					if(tmap->image == -1)
+					CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
+					if(pTMap->m_Image == -1)
 						Graphics()->TextureSet(-1);
 					else
-						Graphics()->TextureSet(gameclient.mapimages->get(tmap->image));
+						Graphics()->TextureSet(m_pClient->m_pMapimages->Get(pTMap->m_Image));
 						
-					TILE *tiles = (TILE *)map_get_data(tmap->data);
+					CTile *pTiles = (CTile *)m_pLayers->Map()->GetData(pTMap->m_Data);
 					Graphics()->BlendNone();
-					RenderTools()->render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE);
+					RenderTools()->RenderTilemap(pTiles, pTMap->m_Width, pTMap->m_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);
+					RenderTools()->RenderTilemap(pTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT);
 				}
-				else if(layer->type == LAYERTYPE_QUADS)
+				else if(pLayer->m_Type == LAYERTYPE_QUADS)
 				{
-					MAPITEM_LAYER_QUADS *qlayer = (MAPITEM_LAYER_QUADS *)layer;
-					if(qlayer->image == -1)
+					CMapItemLayerQuads *pQLayer = (CMapItemLayerQuads *)pLayer;
+					if(pQLayer->m_Image == -1)
 						Graphics()->TextureSet(-1);
 					else
-						Graphics()->TextureSet(gameclient.mapimages->get(qlayer->image));
+						Graphics()->TextureSet(m_pClient->m_pMapimages->Get(pQLayer->m_Image));
 
-					QUAD *quads = (QUAD *)map_get_data_swapped(qlayer->data);
+					CQuad *pQuads = (CQuad *)m_pLayers->Map()->GetDataSwapped(pQLayer->m_Data);
 					
 					Graphics()->BlendNone();
-					RenderTools()->render_quads(quads, qlayer->num_quads, LAYERRENDERFLAG_OPAQUE, envelope_eval, this);
+					RenderTools()->RenderQuads(pQuads, pQLayer->m_NumQuads, LAYERRENDERFLAG_OPAQUE, EnvelopeEval, this);
 					Graphics()->BlendNormal();
-					RenderTools()->render_quads(quads, qlayer->num_quads, LAYERRENDERFLAG_TRANSPARENT, envelope_eval, this);
+					RenderTools()->RenderQuads(pQuads, pQLayer->m_NumQuads, LAYERRENDERFLAG_TRANSPARENT, EnvelopeEval, this);
 				}
 				
 				//layershot_end();	
 			}
 		}
-		if(!config.gfx_noclip)
+		if(!g_Config.m_GfxNoclip)
 			Graphics()->ClipDisable();
 	}
 	
-	if(!config.gfx_noclip)
+	if(!g_Config.m_GfxNoclip)
 		Graphics()->ClipDisable();
 	
 	// reset the screen like it was before
-	Graphics()->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.h b/src/game/client/components/maplayers.h
new file mode 100644
index 00000000..9f70d9cb
--- /dev/null
+++ b/src/game/client/components/maplayers.h
@@ -0,0 +1,24 @@
+#ifndef GAME_CLIENT_COMPONENTS_MAPLAYERS_H
+#define GAME_CLIENT_COMPONENTS_MAPLAYERS_H
+#include <game/client/component.h>
+
+class CMapLayers : public CComponent
+{	
+	CLayers *m_pLayers;	// todo refactor: maybe remove it and access it through client*
+	int m_Type;
+
+	void MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup);
+	static void EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser);
+public:
+	enum
+	{
+		TYPE_BACKGROUND=0,
+		TYPE_FOREGROUND,
+	};
+
+	CMapLayers(int Type);
+	virtual void OnInit();
+	virtual void OnRender();
+};
+
+#endif
diff --git a/src/game/client/components/maplayers.hpp b/src/game/client/components/maplayers.hpp
deleted file mode 100644
index c8b154b2..00000000
--- a/src/game/client/components/maplayers.hpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <game/client/component.hpp>
-
-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
-	{
-		TYPE_BACKGROUND=0,
-		TYPE_FOREGROUND,
-	};
-
-	MAPLAYERS(int type);
-	virtual void on_render();
-};
-
diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp
index 5f1bbf42..76ee2e5e 100644
--- a/src/game/client/components/menus.cpp
+++ b/src/game/client/components/menus.cpp
@@ -1,45 +1,45 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-#include <stdio.h>
+// copyright (c) 2007 magnus auvinen, see licence.txt for more info
 #include <math.h>
-#include <string.h>
-#include <stdlib.h>
 
 #include <base/system.h>
-#include <base/math.hpp>
-#include <base/vmath.hpp>
+#include <base/math.h>
+#include <base/vmath.h>
 
-#include "menus.hpp"
-#include "skins.hpp"
+#include "menus.h"
+#include "skins.h"
 
-#include <engine/e_client_interface.h>
-#include <engine/client/graphics.h>
+#include <engine/graphics.h>
+#include <engine/textrender.h>
+#include <engine/serverbrowser.h>
+#include <engine/keys.h>
+#include <engine/shared/config.h>
 
-#include <game/version.hpp>
-#include <game/generated/g_protocol.hpp>
+#include <game/version.h>
+#include <game/generated/protocol.h>
 
-#include <game/generated/gc_data.hpp>
-#include <game/client/gameclient.hpp>
-#include <game/client/lineinput.hpp>
-#include <game/localization.hpp>
+#include <game/generated/client_data.h>
+#include <game/client/gameclient.h>
+#include <game/client/lineinput.h>
+#include <game/localization.h>
 #include <mastersrv/mastersrv.h>
 
-vec4 MENUS::gui_color;
-vec4 MENUS::color_tabbar_inactive_outgame;
-vec4 MENUS::color_tabbar_active_outgame;
-vec4 MENUS::color_tabbar_inactive;
-vec4 MENUS::color_tabbar_active;
-vec4 MENUS::color_tabbar_inactive_ingame;
-vec4 MENUS::color_tabbar_active_ingame;
+vec4 CMenus::ms_GuiColor;
+vec4 CMenus::ms_ColorTabbarInactiveOutgame;
+vec4 CMenus::ms_ColorTabbarActiveOutgame;
+vec4 CMenus::ms_ColorTabbarInactive;
+vec4 CMenus::ms_ColorTabbarActive;
+vec4 CMenus::ms_ColorTabbarInactiveIngame;
+vec4 CMenus::ms_ColorTabbarActiveIngame;
 
 
-float MENUS::button_height = 25.0f;
-float MENUS::listheader_height = 17.0f;
-float MENUS::fontmod_height = 0.8f;
+float CMenus::ms_ButtonHeight = 25.0f;
+float CMenus::ms_ListheaderHeight = 17.0f;
+float CMenus::ms_FontmodHeight = 0.8f;
 
-INPUT_EVENT MENUS::inputevents[MAX_INPUTEVENTS];
-int MENUS::num_inputevents;
+IInput::CEvent CMenus::m_aInputEvents[MAX_INPUTEVENTS];
+int CMenus::m_NumInputEvents;
 
-inline float hue_to_rgb(float v1, float v2, float h)
+inline float HueToRgb(float v1, float v2, float h)
 {
    if(h < 0) h += 1;
    if(h > 1) h -= 1;
@@ -49,53 +49,54 @@ inline float hue_to_rgb(float v1, float v2, float h)
    return v1;
 }
 
-inline vec3 hsl_to_rgb(vec3 in)
+inline vec3 HslToRgb(vec3 In)
 {
 	float v1, v2;
-	vec3 out;
+	vec3 Out;
 
-	if(in.s == 0)
+	if(In.s == 0)
 	{
-		out.r = in.l;
-		out.g = in.l;
-		out.b = in.l;
+		Out.r = In.l;
+		Out.g = In.l;
+		Out.b = In.l;
 	}
 	else
 	{
-		if(in.l < 0.5f) 
-			v2 = in.l * (1 + in.s);
+		if(In.l < 0.5f) 
+			v2 = In.l * (1 + In.s);
 		else           
-			v2 = (in.l+in.s) - (in.s*in.l);
+			v2 = (In.l+In.s) - (In.s*In.l);
 
-		v1 = 2 * in.l - v2;
+		v1 = 2 * In.l - v2;
 
-		out.r = hue_to_rgb(v1, v2, in.h + (1.0f/3.0f));
-		out.g = hue_to_rgb(v1, v2, in.h);
-		out.b = hue_to_rgb(v1, v2, in.h - (1.0f/3.0f));
+		Out.r = HueToRgb(v1, v2, In.h + (1.0f/3.0f));
+		Out.g = HueToRgb(v1, v2, In.h);
+		Out.b = HueToRgb(v1, v2, In.h - (1.0f/3.0f));
 	} 
 
-	return out;
+	return Out;
 }
 
 
-MENUS::MENUS()
+CMenus::CMenus()
 {
-	popup = POPUP_NONE;
-	active_page = PAGE_INTERNET;
-	game_page = PAGE_GAME;
+	m_Popup = POPUP_NONE;
+	m_ActivePage = PAGE_INTERNET;
+	m_GamePage = PAGE_GAME;
 	
-	need_restart = false;
-	need_sendinfo = false;
-	menu_active = true;
+	m_NeedRestart = false;
+	m_NeedSendinfo = false;
+	m_MenuActive = true;
+	m_UseMouseButtons = true;
 	
-	escape_pressed = false;
-	enter_pressed = false;
-	num_inputevents = 0;
+	m_EscapePressed = false;
+	m_EnterPressed = false;
+	m_NumInputEvents = 0;
 	
-	last_input = time_get();
+	m_LastInput = time_get();
 }
 
-vec4 MENUS::button_color_mul(const void *pID)
+vec4 CMenus::ButtonColorMul(const void *pID)
 {
 	if(UI()->ActiveItem() == pID)
 		return vec4(1,1,1,0.5f);
@@ -104,69 +105,69 @@ vec4 MENUS::button_color_mul(const void *pID)
 	return vec4(1,1,1,1);
 }
 
-int MENUS::DoButton_BrowseIcon(int What, const CUIRect *pRect)
+int CMenus::DoButton_BrowseIcon(int What, const CUIRect *pRect)
 {
-	Graphics()->TextureSet(data->images[IMAGE_BROWSEICONS].id);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_BROWSEICONS].m_Id);
 	
 	Graphics()->QuadsBegin();
-	RenderTools()->select_sprite(What);
-	Graphics()->QuadsDrawTL(pRect->x, pRect->y, pRect->w, pRect->h);
+	RenderTools()->SelectSprite(What);
+	IGraphics::CQuadItem QuadItem(pRect->x, pRect->y, pRect->w, pRect->h);
+	Graphics()->QuadsDrawTL(&QuadItem, 1);
 	Graphics()->QuadsEnd();
 	
 	return 0;
 }
 
 
-int MENUS::DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
+int CMenus::DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
-	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);
+	RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f)*ButtonColorMul(pID), CUI::CORNER_ALL, 5.0f);
+	UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0);
 	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-int MENUS::DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
+void CMenus::DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
-	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);
+	RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f)*ButtonColorMul(pID), CUI::CORNER_ALL, 5.0f);
+	UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0);
 }
 
-int MENUS::DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners)
+int CMenus::DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners)
 {
 	vec4 ColorMod(1,1,1,1);
 	
 	if(Checked)
-		RenderTools()->DrawUIRect(pRect, color_tabbar_active, Corners, 10.0f);
+		RenderTools()->DrawUIRect(pRect, ms_ColorTabbarActive, Corners, 10.0f);
 	else
-		RenderTools()->DrawUIRect(pRect, color_tabbar_inactive, Corners, 10.0f);
-	UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, 0);
+		RenderTools()->DrawUIRect(pRect, ms_ColorTabbarInactive, Corners, 10.0f);
+	UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0);
 	
 	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
 
-int MENUS::DoButton_SettingsTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
+int CMenus::DoButton_SettingsTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
 	if(Checked)
-		RenderTools()->DrawUIRect(pRect, color_tabbar_active, CUI::CORNER_R, 10.0f);
+		RenderTools()->DrawUIRect(pRect, ms_ColorTabbarActive, CUI::CORNER_R, 10.0f);
 	else
-		RenderTools()->DrawUIRect(pRect, color_tabbar_inactive, CUI::CORNER_R, 10.0f);
-	UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, 0);
+		RenderTools()->DrawUIRect(pRect, ms_ColorTabbarInactive, CUI::CORNER_R, 10.0f);
+	UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0);
 	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-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)
+int CMenus::DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
+//void CMenus::ui_draw_grid_header(const void *id, const char *text, int checked, const CUIRect *r, const void *extra)
 {
 	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);
+	UI()->DoLabel(&t, pText, pRect->h*ms_FontmodHeight, -1);
 	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-int MENUS::DoButton_ListRow(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
+int CMenus::DoButton_ListRow(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
 	if(Checked)
 	{
@@ -174,12 +175,12 @@ int MENUS::DoButton_ListRow(const void *pID, const char *pText, int Checked, con
 		sr.Margin(1.5f, &sr);
 		RenderTools()->DrawUIRect(&sr, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f);
 	}
-	UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, -1);
+	UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, -1);
 	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-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)
+int CMenus::DoButton_CheckBox_Common(const void *pID, const char *pText, const char *pBoxText, const CUIRect *pRect)
+//void CMenus::ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const CUIRect *r, const void *extra)
 {
 	CUIRect c = *pRect;
 	CUIRect t = *pRect;
@@ -189,57 +190,59 @@ int MENUS::DoButton_CheckBox_Common(const void *pID, const char *pText, const ch
 	t.VSplitLeft(5.0f, 0, &t);
 	
 	c.Margin(2.0f, &c);
-	RenderTools()->DrawUIRect(&c, vec4(1,1,1,0.25f)*button_color_mul(pID), CUI::CORNER_ALL, 3.0f);
+	RenderTools()->DrawUIRect(&c, vec4(1,1,1,0.25f)*ButtonColorMul(pID), CUI::CORNER_ALL, 3.0f);
 	c.y += 2;
-	UI()->DoLabel(&c, pBoxText, pRect->h*fontmod_height*0.6f, 0);
-	UI()->DoLabel(&t, pText, pRect->h*fontmod_height*0.8f, -1);
+	UI()->DoLabel(&c, pBoxText, pRect->h*ms_FontmodHeight*0.6f, 0);
+	UI()->DoLabel(&t, pText, pRect->h*ms_FontmodHeight*0.8f, -1);
 	return UI()->DoButtonLogic(pID, pText, 0, pRect);
 }
 
-int MENUS::DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
+int CMenus::DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
 	return DoButton_CheckBox_Common(pID, pText, Checked?"X":"", pRect);
 }
 
 
-int MENUS::DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
+int CMenus::DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
-	char buf[16];
-	str_format(buf, sizeof(buf), "%d", Checked);
-	return DoButton_CheckBox_Common(pID, pText, buf, pRect);
+	char aBuf[16];
+	str_format(aBuf, sizeof(aBuf), "%d", Checked);
+	return DoButton_CheckBox_Common(pID, pText, aBuf, pRect);
 }
 
-int MENUS::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden)
+int CMenus::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden, int Corners)
 {
     int Inside = UI()->MouseInside(pRect);
-	int ReturnValue = 0;
-	static int AtIndex = 0;
+	bool ReturnValue = false;
+	static int s_AtIndex = 0;
 
 	if(UI()->LastActiveItem() == pID)
 	{
-		int Len = strlen(pStr);
+		int Len = str_length(pStr);
+		if(Len == 0)
+			s_AtIndex = 0;
 			
 		if(Inside && UI()->MouseButton(0))
 		{
-			int mx_rel = (int)(UI()->MouseX() - pRect->x);
+			int MxRel = (int)(UI()->MouseX() - pRect->x);
 
-			for (int i = 1; i <= Len; i++)
+			for(int i = 1; i <= Len; i++)
 			{
-				if (gfx_text_width(0, FontSize, pStr, i) + 10 > mx_rel)
+				if(TextRender()->TextWidth(0, FontSize, pStr, i) + 10 > MxRel)
 				{
-					AtIndex = i - 1;
+					s_AtIndex = i - 1;
 					break;
 				}
 
-				if (i == Len)
-					AtIndex = Len;
+				if(i == Len)
+					s_AtIndex = Len;
 			}
 		}
 
-		for(int i = 0; i < num_inputevents; i++)
+		for(int i = 0; i < m_NumInputEvents; i++)
 		{
-			Len = strlen(pStr);
-			LINEINPUT::manipulate(inputevents[i], pStr, StrSize, &Len, &AtIndex);
+			Len = str_length(pStr);
+			ReturnValue |= CLineInput::Manipulate(m_aInputEvents[i], pStr, StrSize, &Len, &s_AtIndex);
 		}
 	}
 
@@ -264,35 +267,41 @@ int MENUS::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSi
 		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);
+	RenderTools()->DrawUIRect(&Textbox, vec4(1, 1, 1, 0.5f), Corners, 3.0f);
+	Textbox.VMargin(3.0f, &Textbox);
 	
 	const char *pDisplayStr = pStr;
 	char aStars[128];
 	
 	if(Hidden)
 	{
-		unsigned s = strlen(pStr);
+		unsigned s = str_length(pStr);
 		if(s >= sizeof(aStars))
 			s = sizeof(aStars)-1;
-		memset(aStars, '*', s);
+		for(unsigned int i = 0; i < s; ++i)
+			aStars[i] = '*';
 		aStars[s] = 0;
 		pDisplayStr = aStars;
 	}
 
 	UI()->DoLabel(&Textbox, pDisplayStr, FontSize, -1);
 	
-	if (UI()->LastActiveItem() == pID && !JustGotActive)
+	//TODO: make it blink
+	if(UI()->LastActiveItem() == pID && !JustGotActive)
 	{
-		float w = gfx_text_width(0, FontSize, pDisplayStr, AtIndex);
+		float w = TextRender()->TextWidth(0, FontSize, pDisplayStr, s_AtIndex);
+		Textbox = *pRect;
+		Textbox.VSplitLeft(2.0f, 0, &Textbox);
 		Textbox.x += w*UI()->Scale();
-		UI()->DoLabel(&Textbox, "_", FontSize, -1);
+		Textbox.y -= FontSize/10.f;
+		
+		UI()->DoLabel(&Textbox, "|", FontSize*1.1f, -1);
 	}
 
 	return ReturnValue;
 }
 
-float MENUS::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current)
+float CMenus::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current)
 {
 	CUIRect Handle;
 	static float OffsetY;
@@ -300,7 +309,7 @@ float MENUS::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current)
 
 	Handle.y += (pRect->h-Handle.h)*Current;
 
-	/* logic */
+	// logic
     float ReturnValue = Current;
     int Inside = UI()->MouseInside(&Handle);
 
@@ -309,10 +318,10 @@ float MENUS::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current)
 		if(!UI()->MouseButton(0))
 			UI()->SetActiveItem(0);
 		
-		float min = pRect->y;
-		float max = pRect->h-Handle.h;
-		float cur = UI()->MouseY()-OffsetY;
-		ReturnValue = (cur-min)/max;
+		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;
 	}
@@ -341,14 +350,14 @@ float MENUS::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current)
 
 	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);
+	RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*ButtonColorMul(pID), CUI::CORNER_ALL, 2.5f);
 	
     return ReturnValue;
 }
 
 
 
-float MENUS::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current)
+float CMenus::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current)
 {
 	CUIRect Handle;
 	static float OffsetX;
@@ -356,7 +365,7 @@ float MENUS::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current)
 
 	Handle.x += (pRect->w-Handle.w)*Current;
 
-	/* logic */
+	// logic
     float ReturnValue = Current;
     int Inside = UI()->MouseInside(&Handle);
 
@@ -365,10 +374,10 @@ float MENUS::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current)
 		if(!UI()->MouseButton(0))
 			UI()->SetActiveItem(0);
 		
-		float min = pRect->x;
-		float max = pRect->w-Handle.w;
-		float cur = UI()->MouseX()-OffsetX;
-		ReturnValue = (cur-min)/max;
+		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;
 	}
@@ -397,12 +406,12 @@ float MENUS::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current)
 
 	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);
+	RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*ButtonColorMul(pID), CUI::CORNER_ALL, 2.5f);
 	
     return ReturnValue;
 }
 
-int MENUS::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
+int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
 {
 	// process
 	static void *pGrabbedID = 0;
@@ -415,10 +424,10 @@ int MENUS::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
 
 	if(UI()->ActiveItem() == pID)
 	{
-		if(binder.got_key)
+		if(m_Binder.m_GotKey)
 		{
-			NewKey = binder.key.key;
-			binder.got_key = false;
+			NewKey = m_Binder.m_Key.m_Key;
+			m_Binder.m_GotKey = false;
 			UI()->SetActiveItem(0);
 			MouseReleased = false;
 			pGrabbedID = pID;
@@ -428,8 +437,8 @@ int MENUS::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
 	{
 		if(UI()->MouseButton(0) && MouseReleased)
 		{
-			binder.take_key = true;
-			binder.got_key = false;
+			m_Binder.m_TakeKey = true;
+			m_Binder.m_GotKey = false;
 			UI()->SetActiveItem(pID);
 		}
 	}
@@ -445,185 +454,185 @@ int MENUS::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
 		if(Key == 0)
 			DoButton_KeySelect(pID, "", 0, pRect);
 		else
-			DoButton_KeySelect(pID, inp_key_name(Key), 0, pRect);
+			DoButton_KeySelect(pID, Input()->KeyName(Key), 0, pRect);
 	}
 	return NewKey;
 }
 
 
-int MENUS::render_menubar(CUIRect r)
+int CMenus::RenderMenubar(CUIRect r)
 {
-	CUIRect box = r;
-	CUIRect button;
+	CUIRect Box = r;
+	CUIRect Button;
 	
-	int active_page = config.ui_page;
-	int new_page = -1;
+	m_ActivePage = g_Config.m_UiPage;
+	int NewPage = -1;
 	
-	if(client_state() != CLIENTSTATE_OFFLINE)
-		active_page = game_page;
+	if(Client()->State() != IClient::STATE_OFFLINE)
+		m_ActivePage = m_GamePage;
 	
-	if(client_state() == CLIENTSTATE_OFFLINE)
+	if(Client()->State() == IClient::STATE_OFFLINE)
 	{
-		/* offline menus */
+		// offline menus
 		if(0) // this is not done yet
 		{
-			box.VSplitLeft(90.0f, &button, &box);
-			static int news_button=0;
-			if (DoButton_MenuTab(&news_button, localize("News"), active_page==PAGE_NEWS, &button, 0))
-				new_page = PAGE_NEWS;
-			box.VSplitLeft(30.0f, 0, &box); 
+			Box.VSplitLeft(90.0f, &Button, &Box);
+			static int s_NewsButton=0;
+			if (DoButton_MenuTab(&s_NewsButton, Localize("News"), m_ActivePage==PAGE_NEWS, &Button, 0))
+				NewPage = PAGE_NEWS;
+			Box.VSplitLeft(30.0f, 0, &Box); 
 		}
 
-		box.VSplitLeft(100.0f, &button, &box);
-		static int internet_button=0;
-		if(DoButton_MenuTab(&internet_button, localize("Internet"), active_page==PAGE_INTERNET, &button, CUI::CORNER_TL))
+		Box.VSplitLeft(100.0f, &Button, &Box);
+		static int s_InternetButton=0;
+		if(DoButton_MenuTab(&s_InternetButton, Localize("Internet"), m_ActivePage==PAGE_INTERNET, &Button, CUI::CORNER_TL))
 		{
-			client_serverbrowse_refresh(BROWSETYPE_INTERNET);
-			new_page = PAGE_INTERNET;
+			ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
+			NewPage = PAGE_INTERNET;
 		}
 
-		//box.VSplitLeft(4.0f, 0, &box);
-		box.VSplitLeft(80.0f, &button, &box);
-		static int lan_button=0;
-		if(DoButton_MenuTab(&lan_button, localize("LAN"), active_page==PAGE_LAN, &button, 0))
+		//Box.VSplitLeft(4.0f, 0, &Box);
+		Box.VSplitLeft(80.0f, &Button, &Box);
+		static int s_LanButton=0;
+		if(DoButton_MenuTab(&s_LanButton, Localize("LAN"), m_ActivePage==PAGE_LAN, &Button, 0))
 		{
-			client_serverbrowse_refresh(BROWSETYPE_LAN);
-			new_page = PAGE_LAN;
+			ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN);
+			NewPage = PAGE_LAN;
 		}
 
 		//box.VSplitLeft(4.0f, 0, &box);
-		box.VSplitLeft(110.0f, &button, &box);
-		static int favorites_button=0;
-		if(DoButton_MenuTab(&favorites_button, localize("Favorites"), active_page==PAGE_FAVORITES, &button, CUI::CORNER_TR))
+		Box.VSplitLeft(110.0f, &Button, &Box);
+		static int s_FavoritesButton=0;
+		if(DoButton_MenuTab(&s_FavoritesButton, Localize("Favorites"), m_ActivePage==PAGE_FAVORITES, &Button, CUI::CORNER_TR))
 		{
-			client_serverbrowse_refresh(BROWSETYPE_FAVORITES);
-			new_page  = PAGE_FAVORITES;
+			ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES);
+			NewPage  = PAGE_FAVORITES;
 		}
 		
-		box.VSplitLeft(4.0f*5, 0, &box);
-		box.VSplitLeft(100.0f, &button, &box);
-		static int demos_button=0;
-		if(DoButton_MenuTab(&demos_button, localize("Demos"), active_page==PAGE_DEMOS, &button, 0))
+		Box.VSplitLeft(4.0f*5, 0, &Box);
+		Box.VSplitLeft(100.0f, &Button, &Box);
+		static int s_DemosButton=0;
+		if(DoButton_MenuTab(&s_DemosButton, Localize("Demos"), m_ActivePage==PAGE_DEMOS, &Button, CUI::CORNER_T))
 		{
-			demolist_populate();
-			new_page  = PAGE_DEMOS;
+			DemolistPopulate();
+			NewPage  = PAGE_DEMOS;
 		}		
 	}
 	else
 	{
-		/* online menus */
-		box.VSplitLeft(90.0f, &button, &box);
-		static int game_button=0;
-		if(DoButton_MenuTab(&game_button, localize("Game"), active_page==PAGE_GAME, &button, 0))
-			new_page = PAGE_GAME;
-
-		box.VSplitLeft(4.0f, 0, &box);
-		box.VSplitLeft(140.0f, &button, &box);
-		static int server_info_button=0;
-		if(DoButton_MenuTab(&server_info_button, localize("Server info"), active_page==PAGE_SERVER_INFO, &button, 0))
-			new_page = PAGE_SERVER_INFO;
-
-		box.VSplitLeft(4.0f, 0, &box);
-		box.VSplitLeft(140.0f, &button, &box);
-		static int callvote_button=0;
-		if(DoButton_MenuTab(&callvote_button, localize("Call vote"), active_page==PAGE_CALLVOTE, &button, 0))
-			new_page = PAGE_CALLVOTE;
+		// online menus
+		Box.VSplitLeft(90.0f, &Button, &Box);
+		static int s_GameButton=0;
+		if(DoButton_MenuTab(&s_GameButton, Localize("Game"), m_ActivePage==PAGE_GAME, &Button, CUI::CORNER_T))
+			NewPage = PAGE_GAME;
+
+		Box.VSplitLeft(4.0f, 0, &Box);
+		Box.VSplitLeft(140.0f, &Button, &Box);
+		static int s_ServerInfoButton=0;
+		if(DoButton_MenuTab(&s_ServerInfoButton, Localize("Server info"), m_ActivePage==PAGE_SERVER_INFO, &Button, CUI::CORNER_T))
+			NewPage = PAGE_SERVER_INFO;
+
+		Box.VSplitLeft(4.0f, 0, &Box);
+		Box.VSplitLeft(140.0f, &Button, &Box);
+		static int s_CallVoteButton=0;
+		if(DoButton_MenuTab(&s_CallVoteButton, Localize("Call vote"), m_ActivePage==PAGE_CALLVOTE, &Button, CUI::CORNER_T))
+			NewPage = PAGE_CALLVOTE;
 			
-		box.VSplitLeft(30.0f, 0, &box);
+		Box.VSplitLeft(30.0f, 0, &Box);
 	}
 		
 	/*
 	box.VSplitRight(110.0f, &box, &button);
 	static int system_button=0;
-	if (UI()->DoButton(&system_button, "System", config.ui_page==PAGE_SYSTEM, &button))
-		config.ui_page = PAGE_SYSTEM;
+	if (UI()->DoButton(&system_button, "System", g_Config.m_UiPage==PAGE_SYSTEM, &button))
+		g_Config.m_UiPage = PAGE_SYSTEM;
 		
 	box.VSplitRight(30.0f, &box, 0);
 	*/
 	
-	box.VSplitRight(90.0f, &box, &button);
-	static int quit_button=0;
-	if(DoButton_MenuTab(&quit_button, localize("Quit"), 0, &button, 0))
-		popup = POPUP_QUIT;
-
-	box.VSplitRight(10.0f, &box, &button);
-	box.VSplitRight(130.0f, &box, &button);
-	static int settings_button=0;
-	if(DoButton_MenuTab(&settings_button, localize("Settings"), active_page==PAGE_SETTINGS, &button, 0))
-		new_page = PAGE_SETTINGS;
+	Box.VSplitRight(90.0f, &Box, &Button);
+	static int s_QuitButton=0;
+	if(DoButton_MenuTab(&s_QuitButton, Localize("Quit"), 0, &Button, CUI::CORNER_T))
+		m_Popup = POPUP_QUIT;
+
+	Box.VSplitRight(10.0f, &Box, &Button);
+	Box.VSplitRight(130.0f, &Box, &Button);
+	static int s_SettingsButton=0;
+	if(DoButton_MenuTab(&s_SettingsButton, Localize("Settings"), m_ActivePage==PAGE_SETTINGS, &Button, CUI::CORNER_T))
+		NewPage = PAGE_SETTINGS;
 	
-	if(new_page != -1)
+	if(NewPage != -1)
 	{
-		if(client_state() == CLIENTSTATE_OFFLINE)
-			config.ui_page = new_page;
+		if(Client()->State() == IClient::STATE_OFFLINE)
+			g_Config.m_UiPage = NewPage;
 		else
-			game_page = new_page;
+			m_GamePage = NewPage;
 	}
 		
 	return 0;
 }
 
-void MENUS::render_loading(float percent)
+void CMenus::RenderLoading(float Percent)
 {
-	static int64 last_load_render = 0;
+	static int64 LastLoadRender = 0;
 
 	// make sure that we don't render for each little thing we load
 	// because that will slow down loading if we have vsync
-	if(time_get()-last_load_render < time_freq()/60)
+	if(time_get()-LastLoadRender < time_freq()/60)
 		return;
 		
-	last_load_render = time_get();
+	LastLoadRender = time_get();
 	
 	// need up date this here to get correct
-	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);
+	vec3 Rgb = HslToRgb(vec3(g_Config.m_UiColorHue/255.0f, g_Config.m_UiColorSat/255.0f, g_Config.m_UiColorLht/255.0f));
+	ms_GuiColor = vec4(Rgb.r, Rgb.g, Rgb.b, g_Config.m_UiColorAlpha/255.0f);
 	
-    CUIRect screen = *UI()->Screen();
-	Graphics()->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();
+	RenderBackground();
 
 	float tw;
 
 	float w = 700;
 	float h = 200;
-	float x = screen.w/2-w/2;
-	float y = screen.h/2-h/2;
+	float x = Screen.w/2-w/2;
+	float y = Screen.h/2-h/2;
 
 	Graphics()->BlendNormal();
 
 	Graphics()->TextureSet(-1);
 	Graphics()->QuadsBegin();
 	Graphics()->SetColor(0,0,0,0.50f);
-	RenderTools()->draw_round_rect(x, y, w, h, 40.0f);
+	RenderTools()->DrawRoundRect(x, y, w, h, 40.0f);
 	Graphics()->QuadsEnd();
 
 
-	const char *caption = localize("Loading");
+	const char *pCaption = Localize("Loading");
 
-	tw = gfx_text_width(0, 48.0f, caption, -1);
+	tw = TextRender()->TextWidth(0, 48.0f, pCaption, -1);
 	CUIRect r;
 	r.x = x;
 	r.y = y+20;
 	r.w = w;
 	r.h = h;
-	UI()->DoLabel(&r, caption, 48.0f, 0, -1);
+	UI()->DoLabel(&r, pCaption, 48.0f, 0, -1);
 
 	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);
+	RenderTools()->DrawRoundRect(x+40, y+h-75, (w-80)*Percent, 25, 5.0f);
 	Graphics()->QuadsEnd();
 
-	gfx_swap();
+	Graphics()->Swap();
 }
 
-void MENUS::render_news(CUIRect main_view)
+void CMenus::RenderNews(CUIRect MainView)
 {
-	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
+	RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
 }
 
-void MENUS::on_init()
+void CMenus::OnInit()
 {
 
 	/*
@@ -669,261 +678,263 @@ void MENUS::on_init()
 	exit(-1);
 	// */
 	
-	if(config.cl_show_welcome)
-		popup = POPUP_FIRST_LAUNCH;
-	config.cl_show_welcome = 0;
+	if(g_Config.m_ClShowWelcome)
+		m_Popup = POPUP_FIRST_LAUNCH;
+	g_Config.m_ClShowWelcome = 0;
 }
 
-void MENUS::popup_message(const char *topic, const char *body, const char *button)
+void CMenus::PopupMessage(const char *pTopic, const char *pBody, const char *pButton)
 {
-	str_copy(message_topic, topic, sizeof(message_topic));
-	str_copy(message_body, body, sizeof(message_body));
-	str_copy(message_button, button, sizeof(message_button));
-	popup = POPUP_MESSAGE;
+	str_copy(m_aMessageTopic, pTopic, sizeof(m_aMessageTopic));
+	str_copy(m_aMessageBody, pBody, sizeof(m_aMessageBody));
+	str_copy(m_aMessageButton, pButton, sizeof(m_aMessageButton));
+	m_Popup = POPUP_MESSAGE;
 }
 
 
-int MENUS::render()
+int CMenus::Render()
 {
-    CUIRect screen = *UI()->Screen();
-	Graphics()->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)
+	static bool s_First = true;
+	if(s_First)
 	{
-		if(config.ui_page == PAGE_INTERNET)
-			client_serverbrowse_refresh(0);
-		else if(config.ui_page == PAGE_LAN)
-			client_serverbrowse_refresh(1);
-		first = false;
+		if(g_Config.m_UiPage == PAGE_INTERNET)
+			ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
+		else if(g_Config.m_UiPage == PAGE_LAN)
+			ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN);
+		else if(g_Config.m_UiPage == PAGE_FAVORITES)
+			ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES);
+		s_First = false;
 	}
 	
-	if(client_state() == CLIENTSTATE_ONLINE)
+	if(Client()->State() == IClient::STATE_ONLINE)
 	{
-		color_tabbar_inactive = color_tabbar_inactive_ingame;
-		color_tabbar_active = color_tabbar_active_ingame;
+		ms_ColorTabbarInactive = ms_ColorTabbarInactiveIngame;
+		ms_ColorTabbarActive = ms_ColorTabbarActiveIngame;
 	}
 	else
 	{
-		render_background();
-		color_tabbar_inactive = color_tabbar_inactive_outgame;
-		color_tabbar_active = color_tabbar_active_outgame;
+		RenderBackground();
+		ms_ColorTabbarInactive = ms_ColorTabbarInactiveOutgame;
+		ms_ColorTabbarActive = ms_ColorTabbarActiveOutgame;
 	}
 	
-	CUIRect tab_bar;
-	CUIRect main_view;
+	CUIRect TabBar;
+	CUIRect MainView;
 
 	// some margin around the screen
-	screen.Margin(10.0f, &screen);
+	Screen.Margin(10.0f, &Screen);
 	
-	if(popup == POPUP_NONE)
+	if(m_Popup == POPUP_NONE)
 	{
 		// do tab bar
-		screen.HSplitTop(24.0f, &tab_bar, &main_view);
-		tab_bar.VMargin(20.0f, &tab_bar);
-		render_menubar(tab_bar);
+		Screen.HSplitTop(24.0f, &TabBar, &MainView);
+		TabBar.VMargin(20.0f, &TabBar);
+		RenderMenubar(TabBar);
 		
 		// news is not implemented yet
-		if(config.ui_page <= PAGE_NEWS || config.ui_page > PAGE_SETTINGS || (client_state() == CLIENTSTATE_OFFLINE && config.ui_page >= PAGE_GAME && config.ui_page <= PAGE_CALLVOTE))
+		if(g_Config.m_UiPage <= PAGE_NEWS || g_Config.m_UiPage > PAGE_SETTINGS || (Client()->State() == IClient::STATE_OFFLINE && g_Config.m_UiPage >= PAGE_GAME && g_Config.m_UiPage <= PAGE_CALLVOTE))
 		{
-			client_serverbrowse_refresh(BROWSETYPE_INTERNET);
-			config.ui_page = PAGE_INTERNET;
+			ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
+			g_Config.m_UiPage = PAGE_INTERNET;
 		}
 		
 		// render current page
-		if(client_state() != CLIENTSTATE_OFFLINE)
+		if(Client()->State() != IClient::STATE_OFFLINE)
 		{
-			if(game_page == PAGE_GAME)
-				render_game(main_view);
-			else if(game_page == PAGE_SERVER_INFO)
-				render_serverinfo(main_view);
-			else if(game_page == PAGE_CALLVOTE)
-				render_servercontrol(main_view);
-			else if(game_page == PAGE_SETTINGS)
-				render_settings(main_view);
+			if(m_GamePage == PAGE_GAME)
+				RenderGame(MainView);
+			else if(m_GamePage == PAGE_SERVER_INFO)
+				RenderServerInfo(MainView);
+			else if(m_GamePage == PAGE_CALLVOTE)
+				RenderServerControl(MainView);
+			else if(m_GamePage == PAGE_SETTINGS)
+				RenderSettings(MainView);
 		}
-		else if(config.ui_page == PAGE_NEWS)
-			render_news(main_view);
-		else if(config.ui_page == PAGE_INTERNET)
-			render_serverbrowser(main_view);
-		else if(config.ui_page == PAGE_LAN)
-			render_serverbrowser(main_view);
-		else if(config.ui_page == PAGE_DEMOS)
-			render_demolist(main_view);
-		else if(config.ui_page == PAGE_FAVORITES)
-			render_serverbrowser(main_view);
-		else if(config.ui_page == PAGE_SETTINGS)
-			render_settings(main_view);
+		else if(g_Config.m_UiPage == PAGE_NEWS)
+			RenderNews(MainView);
+		else if(g_Config.m_UiPage == PAGE_INTERNET)
+			RenderServerbrowser(MainView);
+		else if(g_Config.m_UiPage == PAGE_LAN)
+			RenderServerbrowser(MainView);
+		else if(g_Config.m_UiPage == PAGE_DEMOS)
+			RenderDemoList(MainView);
+		else if(g_Config.m_UiPage == PAGE_FAVORITES)
+			RenderServerbrowser(MainView);
+		else if(g_Config.m_UiPage == PAGE_SETTINGS)
+			RenderSettings(MainView);
 	}
 	else
 	{
 		// make sure that other windows doesn't do anything funnay!
 		//UI()->SetHotItem(0);
 		//UI()->SetActiveItem(0);
-		char buf[128];
-		const char *title = "";
-		const char *extra_text = "";
-		const char *button_text = "";
-		int extra_align = 0;
+		char aBuf[128];
+		const char *pTitle = "";
+		const char *pExtraText = "";
+		const char *pButtonText = "";
+		int ExtraAlign = 0;
 		
-		if(popup == POPUP_MESSAGE)
+		if(m_Popup == POPUP_MESSAGE)
 		{
-			title = message_topic;
-			extra_text = message_body;
-			button_text = message_button;
+			pTitle = m_aMessageTopic;
+			pExtraText = m_aMessageBody;
+			pButtonText = m_aMessageButton;
 		}
-		else if(popup == POPUP_CONNECTING)
+		else if(m_Popup == POPUP_CONNECTING)
 		{
-			title = localize("Connecting to");
-			extra_text = config.ui_server_address;  // TODO: query the client about the address
-			button_text = localize("Abort");
-			if(client_mapdownload_totalsize() > 0)
+			pTitle = Localize("Connecting to");
+			pExtraText = g_Config.m_UiServerAddress;  // TODO: query the client about the address
+			pButtonText = Localize("Abort");
+			if(Client()->MapDownloadTotalsize() > 0)
 			{
-				title = localize("Downloading map");
-				str_format(buf, sizeof(buf), "%d/%d KiB", client_mapdownload_amount()/1024, client_mapdownload_totalsize()/1024);
-				extra_text = buf;
+				pTitle = Localize("Downloading map");
+				str_format(aBuf, sizeof(aBuf), "%d/%d KiB", Client()->MapDownloadAmount()/1024, Client()->MapDownloadTotalsize()/1024);
+				pExtraText = aBuf;
 			}
 		}
-		else if(popup == POPUP_DISCONNECTED)
+		else if(m_Popup == POPUP_DISCONNECTED)
 		{
-			title = localize("Disconnected");
-			extra_text = client_error_string();
-			button_text = localize("Ok");
-			extra_align = -1;
+			pTitle = Localize("Disconnected");
+			pExtraText = Client()->ErrorString();
+			pButtonText = Localize("Ok");
+			ExtraAlign = -1;
 		}
-		else if(popup == POPUP_PURE)
+		else if(m_Popup == POPUP_PURE)
 		{
-			title = localize("Disconnected");
-			extra_text = localize("The server is running a non-standard tuning on a pure game type.");
-			button_text = localize("Ok");
-			extra_align = -1;
+			pTitle = Localize("Disconnected");
+			pExtraText = Localize("The server is running a non-standard tuning on a pure game type.");
+			pButtonText = Localize("Ok");
+			ExtraAlign = -1;
 		}
-		else if(popup == POPUP_PASSWORD)
+		else if(m_Popup == POPUP_PASSWORD)
 		{
-			title = localize("Password Incorrect");
-			extra_text = client_error_string();
-			button_text = localize("Try again");
+			pTitle = Localize("Password Incorrect");
+			pExtraText = Client()->ErrorString();
+			pButtonText = Localize("Try again");
 		}
-		else if(popup == POPUP_QUIT)
+		else if(m_Popup == POPUP_QUIT)
 		{
-			title = localize("Quit");
-			extra_text = localize("Are you sure that you want to quit?");
+			pTitle = Localize("Quit");
+			pExtraText = Localize("Are you sure that you want to quit?");
 		}
-		else if(popup == POPUP_FIRST_LAUNCH)
+		else if(m_Popup == POPUP_FIRST_LAUNCH)
 		{
-			title = localize("Welcome to Teeworlds");
-			extra_text = localize("As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server.");
-			button_text = localize("Ok");
-			extra_align = -1;
+			pTitle = Localize("Welcome to Teeworlds");
+			pExtraText = Localize("As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server.");
+			pButtonText = Localize("Ok");
+			ExtraAlign = -1;
 		}
 		
-		CUIRect box, part;
-		box = screen;
-		box.VMargin(150.0f, &box);
-		box.HMargin(150.0f, &box);
+		CUIRect Box, Part;
+		Box = Screen;
+		Box.VMargin(150.0f, &Box);
+		Box.HMargin(150.0f, &Box);
 		
 		// render the box
-		RenderTools()->DrawUIRect(&box, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 15.0f);
+		RenderTools()->DrawUIRect(&Box, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 15.0f);
 		 
-		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);
+		Box.HSplitTop(20.f, &Part, &Box);
+		Box.HSplitTop(24.f, &Part, &Box);
+		UI()->DoLabel(&Part, pTitle, 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()->DoLabel(&part, extra_text, 20.f, -1, (int)part.w);
+		if(ExtraAlign == -1)
+			UI()->DoLabel(&Part, pExtraText, 20.f, -1, (int)Part.w);
 		else
-			UI()->DoLabel(&part, extra_text, 20.f, 0, -1);
+			UI()->DoLabel(&Part, pExtraText, 20.f, 0, -1);
 
-		if(popup == POPUP_QUIT)
+		if(m_Popup == POPUP_QUIT)
 		{
-			CUIRect yes, no;
-			box.HSplitBottom(20.f, &box, &part);
-			box.HSplitBottom(24.f, &box, &part);
-			part.VMargin(80.0f, &part);
+			CUIRect Yes, No;
+			Box.HSplitBottom(20.f, &Box, &Part);
+			Box.HSplitBottom(24.f, &Box, &Part);
+			Part.VMargin(80.0f, &Part);
 			
-			part.VSplitMid(&no, &yes);
+			Part.VSplitMid(&No, &Yes);
 			
-			yes.VMargin(20.0f, &yes);
-			no.VMargin(20.0f, &no);
+			Yes.VMargin(20.0f, &Yes);
+			No.VMargin(20.0f, &No);
 
-			static int button_abort = 0;
-			if(DoButton_Menu(&button_abort, localize("No"), 0, &no) || escape_pressed)
-				popup = POPUP_NONE;
+			static int s_ButtonAbort = 0;
+			if(DoButton_Menu(&s_ButtonAbort, Localize("No"), 0, &No) || m_EscapePressed)
+				m_Popup = POPUP_NONE;
 
-			static int button_tryagain = 0;
-			if(DoButton_Menu(&button_tryagain, localize("Yes"), 0, &yes) || enter_pressed)
-				client_quit();
+			static int s_ButtonTryAgain = 0;
+			if(DoButton_Menu(&s_ButtonTryAgain, Localize("Yes"), 0, &Yes) || m_EnterPressed)
+				Client()->Quit();
 		}
-		else if(popup == POPUP_PASSWORD)
+		else if(m_Popup == POPUP_PASSWORD)
 		{
-			CUIRect label, textbox, tryagain, abort;
+			CUIRect Label, TextBox, TryAgain, Abort;
 			
-			box.HSplitBottom(20.f, &box, &part);
-			box.HSplitBottom(24.f, &box, &part);
-			part.VMargin(80.0f, &part);
+			Box.HSplitBottom(20.f, &Box, &Part);
+			Box.HSplitBottom(24.f, &Box, &Part);
+			Part.VMargin(80.0f, &Part);
 			
-			part.VSplitMid(&abort, &tryagain);
+			Part.VSplitMid(&Abort, &TryAgain);
 			
-			tryagain.VMargin(20.0f, &tryagain);
-			abort.VMargin(20.0f, &abort);
+			TryAgain.VMargin(20.0f, &TryAgain);
+			Abort.VMargin(20.0f, &Abort);
 			
-			static int button_abort = 0;
-			if(DoButton_Menu(&button_abort, localize("Abort"), 0, &abort) || escape_pressed)
-				popup = POPUP_NONE;
+			static int s_ButtonAbort = 0;
+			if(DoButton_Menu(&s_ButtonAbort, Localize("Abort"), 0, &Abort) || m_EscapePressed)
+				m_Popup = POPUP_NONE;
 
-			static int button_tryagain = 0;
-			if(DoButton_Menu(&button_tryagain, localize("Try again"), 0, &tryagain) || enter_pressed)
+			static int s_ButtonTryAgain = 0;
+			if(DoButton_Menu(&s_ButtonTryAgain, Localize("Try again"), 0, &TryAgain) || m_EnterPressed)
 			{
-				client_connect(config.ui_server_address);
+				Client()->Connect(g_Config.m_UiServerAddress);
 			}
 			
-			box.HSplitBottom(60.f, &box, &part);
-			box.HSplitBottom(24.f, &box, &part);
+			Box.HSplitBottom(60.f, &Box, &Part);
+			Box.HSplitBottom(24.f, &Box, &Part);
 			
-			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);
+			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"), 18.0f, -1);
+			DoEditBox(&g_Config.m_Password, &TextBox, g_Config.m_Password, sizeof(g_Config.m_Password), 12.0f, true);
 		}
-		else if(popup == POPUP_FIRST_LAUNCH)
+		else if(m_Popup == POPUP_FIRST_LAUNCH)
 		{
-			CUIRect label, textbox;
+			CUIRect Label, TextBox;
 			
-			box.HSplitBottom(20.f, &box, &part);
-			box.HSplitBottom(24.f, &box, &part);
-			part.VMargin(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(DoButton_Menu(&enter_button, localize("Enter"), 0, &part) || enter_pressed)
-				popup = POPUP_NONE;
+			static int s_EnterButton = 0;
+			if(DoButton_Menu(&s_EnterButton, Localize("Enter"), 0, &Part) || m_EnterPressed)
+				m_Popup = POPUP_NONE;
 			
-			box.HSplitBottom(40.f, &box, &part);
-			box.HSplitBottom(24.f, &box, &part);
+			Box.HSplitBottom(40.f, &Box, &Part);
+			Box.HSplitBottom(24.f, &Box, &Part);
 			
-			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);
+			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"), 18.0f, -1);
+			DoEditBox(&g_Config.m_PlayerName, &TextBox, g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), 12.0f);
 		}
 		else
 		{
-			box.HSplitBottom(20.f, &box, &part);
-			box.HSplitBottom(24.f, &box, &part);
-			part.VMargin(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(DoButton_Menu(&button, button_text, 0, &part) || escape_pressed || enter_pressed)
+			static int s_Button = 0;
+			if(DoButton_Menu(&s_Button, pButtonText, 0, &Part) || m_EscapePressed || m_EnterPressed)
 			{
-				if(popup == POPUP_CONNECTING)
-					client_disconnect();
-				popup = POPUP_NONE;
+				if(m_Popup == POPUP_CONNECTING)
+					Client()->Disconnect();
+				m_Popup = POPUP_NONE;
 			}
 		}
 	}
@@ -932,109 +943,113 @@ int MENUS::render()
 }
 
 
-void MENUS::set_active(bool active)
+void CMenus::SetActive(bool Active)
 {
-	menu_active = active;
-	if(!menu_active && need_sendinfo)
+	m_MenuActive = Active;
+	if(!m_MenuActive && m_NeedSendinfo)
 	{
-		gameclient.send_info(false);
-		need_sendinfo = false;
+		m_pClient->SendInfo(false);
+		m_NeedSendinfo = false;
 	}
 }
 
-void MENUS::on_reset()
+void CMenus::OnReset()
 {
 }
 
-bool MENUS::on_mousemove(float x, float y)
+bool CMenus::OnMouseMove(float x, float y)
 {
-	last_input = time_get();
+	m_LastInput = time_get();
 	
-	if(!menu_active)
+	if(!m_MenuActive)
 		return false;
 		
-	mouse_pos.x += x;
-	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 > Graphics()->ScreenWidth()) mouse_pos.x = Graphics()->ScreenWidth();
-	if(mouse_pos.y > Graphics()->ScreenHeight()) mouse_pos.y = Graphics()->ScreenHeight();
+	m_MousePos.x += x;
+	m_MousePos.y += y;
+	if(m_MousePos.x < 0) m_MousePos.x = 0;
+	if(m_MousePos.y < 0) m_MousePos.y = 0;
+	if(m_MousePos.x > Graphics()->ScreenWidth()) m_MousePos.x = Graphics()->ScreenWidth();
+	if(m_MousePos.y > Graphics()->ScreenHeight()) m_MousePos.y = Graphics()->ScreenHeight();
 	
 	return true;
 }
 
-bool MENUS::on_input(INPUT_EVENT e)
+bool CMenus::OnInput(IInput::CEvent e)
 {
-	last_input = time_get();
+	m_LastInput = time_get();
 	
 	// special handle esc and enter for popup purposes
-	if(e.flags&INPFLAG_PRESS)
+	if(e.m_Flags&IInput::FLAG_PRESS)
 	{
-		if(e.key == KEY_ESCAPE)
+		if(e.m_Key == KEY_ESCAPE)
 		{
-			escape_pressed = true;
-			set_active(!is_active());
+			m_EscapePressed = true;
+			SetActive(!IsActive());
 			return true;
 		}
 	}
 		
-	if(is_active())
+	if(IsActive())
 	{
 		// special for popups
-		if(e.flags&INPFLAG_PRESS && e.key == KEY_RETURN)
-			enter_pressed = true;
+		if(e.m_Flags&IInput::FLAG_PRESS && e.m_Key == KEY_RETURN)
+			m_EnterPressed = true;
 		
-		if(num_inputevents < MAX_INPUTEVENTS)
-			inputevents[num_inputevents++] = e;
+		if(m_NumInputEvents < MAX_INPUTEVENTS)
+			m_aInputEvents[m_NumInputEvents++] = e;
 		return true;
 	}
 	return false;
 }
 
-void MENUS::on_statechange(int new_state, int old_state)
+void CMenus::OnStateChange(int NewState, int OldState)
 {
-	if(new_state == CLIENTSTATE_OFFLINE)
+	// reset active item
+	UI()->SetActiveItem(0);
+
+	if(NewState == IClient::STATE_OFFLINE)
 	{
-		popup = POPUP_NONE;
-		if(client_error_string() && client_error_string()[0] != 0)
+		m_Popup = POPUP_NONE;
+		if(Client()->ErrorString() && Client()->ErrorString()[0] != 0)
 		{
-			if(strstr(client_error_string(), "password"))
+			if(str_find(Client()->ErrorString(), "password"))
 			{
-				popup = POPUP_PASSWORD;
-				UI()->SetHotItem(&config.password);
-				UI()->SetActiveItem(&config.password);
+				m_Popup = POPUP_PASSWORD;
+				UI()->SetHotItem(&g_Config.m_Password);
+				UI()->SetActiveItem(&g_Config.m_Password);
 			}
 			else
-				popup = POPUP_DISCONNECTED;
-		}	}
-	else if(new_state == CLIENTSTATE_LOADING)
+				m_Popup = POPUP_DISCONNECTED;
+		}
+	}
+	else if(NewState == IClient::STATE_LOADING)
 	{
-		popup = POPUP_CONNECTING;
-		client_serverinfo_request();
+		m_Popup = POPUP_CONNECTING;
+		//client_serverinfo_request();
 	}
-	else if(new_state == CLIENTSTATE_CONNECTING)
-		popup = POPUP_CONNECTING;
-	else if (new_state == CLIENTSTATE_ONLINE || new_state == CLIENTSTATE_DEMOPLAYBACK)
+	else if(NewState == IClient::STATE_CONNECTING)
+		m_Popup = POPUP_CONNECTING;
+	else if (NewState == IClient::STATE_ONLINE || NewState == IClient::STATE_DEMOPLAYBACK)
 	{
-		popup = POPUP_NONE;
-		set_active(false);
+		m_Popup = POPUP_NONE;
+		SetActive(false);
 	}
 }
 
 extern "C" void font_debug_render();
 
-void MENUS::on_render()
+void CMenus::OnRender()
 {
 	/*
 	// text rendering test stuff
 	render_background();
 
-	TEXT_CURSOR cursor;
-	gfx_text_set_cursor(&cursor, 10, 10, 20, TEXTFLAG_RENDER);
-	gfx_text_ex(&cursor, "ようこそ - ガイド", -1);
+	CTextCursor cursor;
+	TextRender()->SetCursor(&cursor, 10, 10, 20, TEXTFLAG_RENDER);
+	TextRender()->TextEx(&cursor, "ようこそ - ガイド", -1);
 
-	gfx_text_set_cursor(&cursor, 10, 30, 15, TEXTFLAG_RENDER);
-	gfx_text_ex(&cursor, "ようこそ - ガイド", -1);
+	TextRender()->SetCursor(&cursor, 10, 30, 15, TEXTFLAG_RENDER);
+	TextRender()->TextEx(&cursor, "ようこそ - ガイド", -1);
 	
 	//Graphics()->TextureSet(-1);
 	Graphics()->QuadsBegin();
@@ -1042,101 +1057,105 @@ void MENUS::on_render()
 	Graphics()->QuadsEnd();
 	return;*/
 	
-	if(client_state() != CLIENTSTATE_ONLINE && client_state() != CLIENTSTATE_DEMOPLAYBACK)
-		set_active(true);
+	if(Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK)
+		SetActive(true);
 
-	if(client_state() == CLIENTSTATE_DEMOPLAYBACK)
+	if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
 	{
-		CUIRect screen = *UI()->Screen();
-		Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);
-		render_demoplayer(screen);
+		CUIRect Screen = *UI()->Screen();
+		Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
+		RenderDemoPlayer(Screen);
 	}
 	
-	if(client_state() == CLIENTSTATE_ONLINE && gameclient.servermode == gameclient.SERVERMODE_PUREMOD)
+	if(Client()->State() == IClient::STATE_ONLINE && m_pClient->m_ServerMode == m_pClient->SERVERMODE_PUREMOD)
 	{
-		client_disconnect();
-		set_active(true);
-		popup = POPUP_PURE;
+		Client()->Disconnect();
+		SetActive(true);
+		m_Popup = POPUP_PURE;
 	}
 	
-	if(!is_active())
+	if(!IsActive())
 	{
-		escape_pressed = false;
-		enter_pressed = false;
-		num_inputevents = 0;
+		m_EscapePressed = false;
+		m_EnterPressed = false;
+		m_NumInputEvents = 0;
 		return;
 	}
 	
 	// update colors
-	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);
-
-	color_tabbar_inactive_outgame = vec4(0,0,0,0.25f);
-	color_tabbar_active_outgame = vec4(0,0,0,0.5f);
-
-	float color_ingame_scale_i = 0.5f;
-	float color_ingame_scale_a = 0.2f;
-	color_tabbar_inactive_ingame = vec4(
-		gui_color.r*color_ingame_scale_i,
-		gui_color.g*color_ingame_scale_i,
-		gui_color.b*color_ingame_scale_i,
-		gui_color.a*0.8f);
+	vec3 Rgb = HslToRgb(vec3(g_Config.m_UiColorHue/255.0f, g_Config.m_UiColorSat/255.0f, g_Config.m_UiColorLht/255.0f));
+	ms_GuiColor = vec4(Rgb.r, Rgb.g, Rgb.b, g_Config.m_UiColorAlpha/255.0f);
+
+	ms_ColorTabbarInactiveOutgame = vec4(0,0,0,0.25f);
+	ms_ColorTabbarActiveOutgame = vec4(0,0,0,0.5f);
+
+	float ColorIngameScaleI = 0.5f;
+	float ColorIngameAcaleA = 0.2f;
+	ms_ColorTabbarInactiveIngame = vec4(
+		ms_GuiColor.r*ColorIngameScaleI,
+		ms_GuiColor.g*ColorIngameScaleI,
+		ms_GuiColor.b*ColorIngameScaleI,
+		ms_GuiColor.a*0.8f);
 	
-	color_tabbar_active_ingame = vec4(
-		gui_color.r*color_ingame_scale_a,
-		gui_color.g*color_ingame_scale_a,
-		gui_color.b*color_ingame_scale_a,
-		gui_color.a);
+	ms_ColorTabbarActiveIngame = vec4(
+		ms_GuiColor.r*ColorIngameAcaleA,
+		ms_GuiColor.g*ColorIngameAcaleA,
+		ms_GuiColor.b*ColorIngameAcaleA,
+		ms_GuiColor.a);
     
 	// update the ui
-	CUIRect *screen = UI()->Screen();
-	float mx = (mouse_pos.x/(float)Graphics()->ScreenWidth())*screen->w;
-	float my = (mouse_pos.y/(float)Graphics()->ScreenHeight())*screen->h;
+	CUIRect *pScreen = UI()->Screen();
+	float mx = (m_MousePos.x/(float)Graphics()->ScreenWidth())*pScreen->w;
+	float my = (m_MousePos.y/(float)Graphics()->ScreenHeight())*pScreen->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;
+	int Buttons = 0;
+	if(m_UseMouseButtons)
+	{
+		if(Input()->KeyPressed(KEY_MOUSE_1)) Buttons |= 1;
+		if(Input()->KeyPressed(KEY_MOUSE_2)) Buttons |= 2;
+		if(Input()->KeyPressed(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();
+	if(Client()->State() != IClient::STATE_DEMOPLAYBACK)
+		Render();
 
 	// render cursor
-	Graphics()->TextureSet(data->images[IMAGE_CURSOR].id);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id);
 	Graphics()->QuadsBegin();
 	Graphics()->SetColor(1,1,1,1);
-	Graphics()->QuadsDrawTL(mx,my,24,24);
+	IGraphics::CQuadItem QuadItem(mx, my, 24, 24);
+	Graphics()->QuadsDrawTL(&QuadItem, 1);
 	Graphics()->QuadsEnd();
 
 	// render debug information
-	if(config.debug)
+	if(g_Config.m_Debug)
 	{
-		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()->HotItem(), UI()->ActiveItem(), UI()->LastActiveItem());
-		TEXT_CURSOR cursor;
-		gfx_text_set_cursor(&cursor, 10, 10, 10, TEXTFLAG_RENDER);
-		gfx_text_ex(&cursor, buf, -1);
+		CUIRect Screen = *UI()->Screen();
+		Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
+
+		char aBuf[512];
+		str_format(aBuf, sizeof(aBuf), "%p %p %p", UI()->HotItem(), UI()->ActiveItem(), UI()->LastActiveItem());
+		CTextCursor Cursor;
+		TextRender()->SetCursor(&Cursor, 10, 10, 10, TEXTFLAG_RENDER);
+		TextRender()->TextEx(&Cursor, aBuf, -1);
 	}
 
-	escape_pressed = false;
-	enter_pressed = false;
-	num_inputevents = 0;
+	m_EscapePressed = false;
+	m_EnterPressed = false;
+	m_NumInputEvents = 0;
 }
 
-static int texture_blob = -1;
+static int gs_TextureBlob = -1;
 
-void MENUS::render_background()
+void CMenus::RenderBackground()
 {
 	//Graphics()->Clear(1,1,1);
 	//render_sunrays(0,0);
-	if(texture_blob == -1)
-		texture_blob = Graphics()->LoadTexture("blob.png", IMG_AUTO, 0);
+	if(gs_TextureBlob == -1)
+		gs_TextureBlob = Graphics()->LoadTexture("blob.png", CImageInfo::FORMAT_AUTO, 0);
 
 
 	float sw = 300*Graphics()->ScreenAspect();
@@ -1150,36 +1169,41 @@ void MENUS::render_background()
 	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);
-		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);
+		vec4 Bottom(ms_GuiColor.r, ms_GuiColor.g, ms_GuiColor.b, 1.0f);
+		vec4 Top(ms_GuiColor.r, ms_GuiColor.g, ms_GuiColor.b, 1.0f);
+		IGraphics::CColorVertex Array[4] = {
+			IGraphics::CColorVertex(0, Top.r, Top.g, Top.b, Top.a),
+			IGraphics::CColorVertex(1, Top.r, Top.g, Top.b, Top.a),
+			IGraphics::CColorVertex(2, Bottom.r, Bottom.g, Bottom.b, Bottom.a),
+			IGraphics::CColorVertex(3, Bottom.r, Bottom.g, Bottom.b, Bottom.a)};
+		Graphics()->SetColorVertex(Array, 4);
+		IGraphics::CQuadItem QuadItem(0, 0, sw, sh);
+		Graphics()->QuadsDrawTL(&QuadItem, 1);
 	Graphics()->QuadsEnd();
 	
 	// render the tiles
 	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++)
+		float Size = 15.0f;
+		float OffsetTime = 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++)
 			{
 				Graphics()->SetColor(0,0,0,0.045f);
-				Graphics()->QuadsDrawTL((x-offset_time)*size*2+(y&1)*size, (y+offset_time)*size, size, size);
+				IGraphics::CQuadItem QuadItem((x-OffsetTime)*Size*2+(y&1)*Size, (y+OffsetTime)*Size, Size, Size);
+				Graphics()->QuadsDrawTL(&QuadItem, 1);
 			}
 	Graphics()->QuadsEnd();
 
 	// render border fade
-	Graphics()->TextureSet(texture_blob);
+	Graphics()->TextureSet(gs_TextureBlob);
 	Graphics()->QuadsBegin();
 		Graphics()->SetColor(0,0,0,0.5f);
-		Graphics()->QuadsDrawTL(-100, -100, sw+200, sh+200);
+		QuadItem = IGraphics::CQuadItem(-100, -100, sw+200, sh+200);
+		Graphics()->QuadsDrawTL(&QuadItem, 1);
 	Graphics()->QuadsEnd();
 
 	// restore screen	
-    {CUIRect screen = *UI()->Screen();
-	Graphics()->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.h b/src/game/client/components/menus.h
new file mode 100644
index 00000000..3055e661
--- /dev/null
+++ b/src/game/client/components/menus.h
@@ -0,0 +1,223 @@
+#ifndef GAME_CLIENT_COMPONENTS_MENUS_H
+#define GAME_CLIENT_COMPONENTS_MENUS_H
+
+#include <base/vmath.h>
+#include <base/tl/sorted_array.h>
+
+#include <game/client/component.h>
+#include <game/client/ui.h>
+
+
+// compnent to fetch keypresses, override all other input
+class CMenusKeyBinder : public CComponent
+{
+public:
+	bool m_TakeKey;
+	bool m_GotKey;
+	IInput::CEvent m_Key;
+	CMenusKeyBinder();
+	virtual bool OnInput(IInput::CEvent Event);
+};
+
+class CMenus : public CComponent
+{	
+	static vec4 ms_GuiColor;
+	static vec4 ms_ColorTabbarInactiveOutgame;
+	static vec4 ms_ColorTabbarActiveOutgame;
+	static vec4 ms_ColorTabbarInactiveIngame;
+	static vec4 ms_ColorTabbarActiveIngame;
+	static vec4 ms_ColorTabbarInactive;
+	static vec4 ms_ColorTabbarActive;
+	
+	vec4 ButtonColorMul(const void *pID);
+
+
+	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);
+
+	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 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);
+	*/
+
+	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, int Corners=CUI::CORNER_ALL);
+	//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);
+	void 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 UiDoGetButtons(int Start, int Stop, CUIRect View);
+
+	struct CListboxItem
+	{
+		int m_Visible;
+		int m_Selected;
+		CUIRect m_Rect;
+		CUIRect m_HitRect;
+	};
+	
+	void UiDoListboxStart(void *pId, const CUIRect *pRect, float RowHeight, const char *pTitle, const char *pBottomText, int NumItems,
+						  int ItemsPerRow, int SelectedIndex, float ScrollValue);
+	CListboxItem UiDoListboxNextItem(void *pID, bool Selected = false);
+	static CListboxItem UiDoListboxNextRow();
+	int UiDoListboxEnd(float *pScrollValue, bool *pItemActivated);
+	
+	//static void demolist_listdir_callback(const char *name, int is_dir, void *user);
+	//static void demolist_list_callback(const CUIRect *rect, int index, void *user);
+
+	enum
+	{
+		POPUP_NONE=0,
+		POPUP_FIRST_LAUNCH,
+		POPUP_CONNECTING,
+		POPUP_MESSAGE,
+		POPUP_DISCONNECTED,
+		POPUP_PURE,
+		POPUP_PASSWORD,
+		POPUP_QUIT, 
+	};
+
+	enum
+	{
+		PAGE_NEWS=1,
+		PAGE_GAME,
+		PAGE_SERVER_INFO,
+		PAGE_CALLVOTE,
+		PAGE_INTERNET,
+		PAGE_LAN,
+		PAGE_FAVORITES,
+		PAGE_DEMOS,
+		PAGE_SETTINGS,
+		PAGE_SYSTEM,
+	};
+
+	int m_GamePage;
+	int m_Popup;
+	int m_ActivePage;
+	bool m_MenuActive;
+	bool m_UseMouseButtons;
+	vec2 m_MousePos;
+	
+	int64 m_LastInput;
+	
+	//
+	char m_aMessageTopic[512];
+	char m_aMessageBody[512];
+	char m_aMessageButton[512];
+	
+	void PopupMessage(const char *pTopic, const char *pBody, const char *pButton);
+
+	// TODO: this is a bit ugly but.. well.. yeah	
+	enum { MAX_INPUTEVENTS = 32 };
+	static IInput::CEvent m_aInputEvents[MAX_INPUTEVENTS];
+	static int m_NumInputEvents;
+	
+	// some settings
+	static float ms_ButtonHeight;
+	static float ms_ListheaderHeight;
+	static float ms_FontmodHeight;
+	
+	// for graphic settings
+	bool m_NeedRestart;
+	bool m_NeedSendinfo;
+	
+	//
+	bool m_EscapePressed;
+	bool m_EnterPressed;
+	
+	// for call vote
+	int m_CallvoteSelectedOption;
+	int m_CallvoteSelectedPlayer;
+	
+	// demo
+	struct CDemoItem
+	{
+		char m_aFilename[512];
+		char m_aName[256];
+		
+		bool operator<(const CDemoItem &Other) { return str_comp(m_aName, Other.m_aName) < 0; } 
+	};
+	
+	sorted_array<CDemoItem> m_lDemos;
+		
+	void DemolistPopulate();
+	static void DemolistCountCallback(const char *pName, int IsDir, void *pUser);
+	static void DemolistFetchCallback(const char *pName, int IsDir, void *pUser);
+
+	// found in menus.cpp
+	int Render();
+	//void render_background();
+	//void render_loading(float percent);
+	int RenderMenubar(CUIRect r);
+	void RenderNews(CUIRect MainView);
+	
+	// found in menus_demo.cpp
+	void RenderDemoPlayer(CUIRect MainView);
+	void RenderDemoList(CUIRect MainView);
+	
+	// found in menus_ingame.cpp
+	void RenderGame(CUIRect MainView);
+	void RenderServerInfo(CUIRect MainView);
+	void RenderServerControl(CUIRect MainView);
+	void RenderServerControlKick(CUIRect MainView);
+	void RenderServerControlServer(CUIRect MainView);
+	
+	// found in menus_browser.cpp
+	int m_SelectedIndex;
+	void RenderServerbrowserServerList(CUIRect View);
+	void RenderServerbrowserServerDetail(CUIRect View);
+	void RenderServerbrowserFilters(CUIRect View);
+	void RenderServerbrowser(CUIRect MainView);
+	
+	// found in menus_settings.cpp
+	void RenderSettingsGeneral(CUIRect MainView);
+	void RenderSettingsPlayer(CUIRect MainView);
+	void RenderSettingsControls(CUIRect MainView);
+	void RenderSettingsGraphics(CUIRect MainView);
+	void RenderSettingsSound(CUIRect MainView);
+	void RenderSettings(CUIRect MainView);
+	
+	void SetActive(bool Active);
+public:
+	void RenderBackground();
+
+	void UseMouseButtons(bool Use) { m_UseMouseButtons = Use; }
+
+	static CMenusKeyBinder m_Binder;
+	
+	CMenus();
+
+	void RenderLoading(float Percent);
+
+	bool IsActive() const { return m_MenuActive; }
+
+	virtual void OnInit();
+
+	virtual void OnStateChange(int NewState, int OldState);
+	virtual void OnReset();
+	virtual void OnRender();
+	virtual bool OnInput(IInput::CEvent Event);
+	virtual bool OnMouseMove(float x, float y);
+};
+#endif
diff --git a/src/game/client/components/menus.hpp b/src/game/client/components/menus.hpp
deleted file mode 100644
index 02759403..00000000
--- a/src/game/client/components/menus.hpp
+++ /dev/null
@@ -1,216 +0,0 @@
-#include <base/vmath.hpp>
-#include <base/tl/sorted_array.hpp>
-
-#include <game/client/component.hpp>
-#include <game/client/ui.hpp>
-
-
-// compnent to fetch keypresses, override all other input
-class MENUS_KEYBINDER : public COMPONENT
-{
-public:
-	bool take_key;
-	bool got_key;
-	INPUT_EVENT key;
-	MENUS_KEYBINDER();
-	virtual bool on_input(INPUT_EVENT e);
-};
-
-class MENUS : public COMPONENT
-{	
-	static vec4 gui_color;
-	static vec4 color_tabbar_inactive_outgame;
-	static vec4 color_tabbar_active_outgame;
-	static vec4 color_tabbar_inactive_ingame;
-	static vec4 color_tabbar_active_ingame;
-	static vec4 color_tabbar_inactive;
-	static vec4 color_tabbar_active;
-	
-	vec4 button_color_mul(const void *pID);
-
-
-	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);
-
-	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 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);
-	*/
-
-	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;
-		CUIRect rect;
-		CUIRect hitrect;
-	};
-	
-	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);
-
-	enum
-	{
-		POPUP_NONE=0,
-		POPUP_FIRST_LAUNCH,
-		POPUP_CONNECTING,
-		POPUP_MESSAGE,
-		POPUP_DISCONNECTED,
-		POPUP_PURE,
-		POPUP_PASSWORD,
-		POPUP_QUIT, 
-	};
-
-	enum
-	{
-		PAGE_NEWS=1,
-		PAGE_GAME,
-		PAGE_SERVER_INFO,
-		PAGE_CALLVOTE,
-		PAGE_INTERNET,
-		PAGE_LAN,
-		PAGE_FAVORITES,
-		PAGE_DEMOS,
-		PAGE_SETTINGS,
-		PAGE_SYSTEM,
-	};
-
-	int game_page;
-	int popup;
-	int active_page;
-	bool menu_active;
-	vec2 mouse_pos;
-	
-	int64 last_input;
-	
-	//
-	char message_topic[512];
-	char message_body[512];
-	char message_button[512];
-	
-	void popup_message(const char *topic, const char *body, const char *button);
-
-	// TODO: this is a bit ugly but.. well.. yeah	
-	enum { MAX_INPUTEVENTS = 32 };
-	static INPUT_EVENT inputevents[MAX_INPUTEVENTS];
-	static int num_inputevents;
-	
-	// some settings
-	static float button_height;
-	static float listheader_height;
-	static float fontmod_height;
-	
-	// for graphic settings
-	bool need_restart;
-	bool need_sendinfo;
-	
-	//
-	bool escape_pressed;
-	bool enter_pressed;
-	
-	// for call vote
-	int callvote_selectedoption;
-	int callvote_selectedplayer;
-	
-	// demo
-	struct DEMOITEM
-	{
-		char filename[512];
-		char name[256];
-		
-		bool operator<(const DEMOITEM &other) { return str_comp(name, other.name) < 0; } 
-	};
-	
-	sorted_array<DEMOITEM> demos;
-		
-	void demolist_populate();
-	static void demolist_count_callback(const char *name, int is_dir, void *user);
-	static void demolist_fetch_callback(const char *name, int is_dir, void *user);
-
-	// found in menus.cpp
-	int render();
-	//void render_background();
-	//void render_loading(float percent);
-	int render_menubar(CUIRect r);
-	void render_news(CUIRect main_view);
-	
-	// found in menus_demo.cpp
-	void render_demoplayer(CUIRect main_view);
-	void render_demolist(CUIRect main_view);
-	
-	// found in menus_ingame.cpp
-	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(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(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();
-
-	void render_loading(float percent);
-
-	bool is_active() const { return menu_active; }
-
-	virtual void on_init();
-
-	virtual void on_statechange(int new_state, int old_state);
-	virtual void on_reset();
-	virtual void on_render();
-	virtual bool on_input(INPUT_EVENT e);
-	virtual bool on_mousemove(float x, float y);
-};
diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp
index dcf68f8d..0a737052 100644
--- a/src/game/client/components/menus_browser.cpp
+++ b/src/game/client/components/menus_browser.cpp
@@ -1,46 +1,45 @@
+#include <engine/serverbrowser.h>
+#include <engine/textrender.h>
+#include <engine/keys.h>
+#include <engine/shared/config.h>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
+
+#include <game/client/ui.h>
+#include <game/client/render.h>
+#include "menus.h"
+#include <game/localization.h>
+#include <game/version.h>
+
+void CMenus::RenderServerbrowserServerList(CUIRect View)
+{
+	CUIRect Headers;
+	CUIRect Status;
 
-#include <string.h> // strcmp, strlen, strncpy
-#include <stdlib.h> // atoi
-
-#include <engine/e_client_interface.h>
-#include <game/generated/g_protocol.hpp>
-#include <game/generated/gc_data.hpp>
-
-#include <game/client/ui.hpp>
-#include <game/client/render.hpp>
-#include "menus.hpp"
-#include <game/localization.hpp>
-#include <game/version.hpp>
+	View.HSplitTop(ms_ListheaderHeight, &Headers, &View);
+	View.HSplitBottom(28.0f, &View, &Status);
 
-void MENUS::render_serverbrowser_serverlist(CUIRect view)
-{
-	CUIRect headers;
-	CUIRect status;
-	
-	view.HSplitTop(listheader_height, &headers, &view);
-	view.HSplitBottom(28.0f, &view, &status);
-	
 	// split of the scrollbar
-	RenderTools()->DrawUIRect(&headers, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f);
-	headers.VSplitRight(20.0f, &headers, 0);
-	
-	struct column
+	RenderTools()->DrawUIRect(&Headers, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f);
+	Headers.VSplitRight(20.0f, &Headers, 0);
+
+	struct CColumn
 	{
-		int id;
-		int sort;
-		LOC_CONSTSTRING caption;
-		int direction;
-		float width;
-		int flags;
-		CUIRect rect;
-		CUIRect spacer;
+		int m_Id;
+		int m_Sort;
+		CLocConstString m_Caption;
+		int m_Direction;
+		float m_Width;
+		int m_Flags;
+		CUIRect m_Rect;
+		CUIRect m_Spacer;
 	};
-	
+
 	enum
 	{
 		FIXED=1,
 		SPACER=2,
-		
+
 		COL_FLAG_LOCK=0,
 		COL_FLAG_PURE,
 		COL_FLAG_FAV,
@@ -51,494 +50,542 @@ void MENUS::render_serverbrowser_serverlist(CUIRect view)
 		COL_PING,
 		COL_VERSION,
 	};
-	
-	static column cols[] = {
+
+	static CColumn s_aCols[] = {
 		{-1,			-1,						" ",		-1, 2.0f, 0, {0}, {0}},
 		{COL_FLAG_LOCK,	-1,						" ",		-1, 14.0f, 0, {0}, {0}},
 		{COL_FLAG_PURE,	-1,						" ",		-1, 14.0f, 0, {0}, {0}},
 		{COL_FLAG_FAV,	-1,						" ",		-1, 14.0f, 0, {0}, {0}},
-		{COL_NAME,		BROWSESORT_NAME,		localize("Name"),		0, 300.0f, 0, {0}, {0}},
-		{COL_GAMETYPE,	BROWSESORT_GAMETYPE,	localize("Type"),		1, 50.0f, 0, {0}, {0}},
-		{COL_MAP,		BROWSESORT_MAP,			localize("Map"), 		1, 100.0f, 0, {0}, {0}},
-		{COL_PLAYERS,	BROWSESORT_NUMPLAYERS,	localize("Players"),	1, 60.0f, 0, {0}, {0}},
+		{COL_NAME,		IServerBrowser::SORT_NAME,		Localize("Name"),		0, 300.0f, 0, {0}, {0}},
+		{COL_GAMETYPE,	IServerBrowser::SORT_GAMETYPE,	Localize("Type"),		1, 50.0f, 0, {0}, {0}},
+		{COL_MAP,		IServerBrowser::SORT_MAP,			Localize("Map"), 		1, 100.0f, 0, {0}, {0}},
+		{COL_PLAYERS,	IServerBrowser::SORT_NUMPLAYERS,	Localize("Players"),	1, 60.0f, 0, {0}, {0}},
 		{-1,			-1,						" ",		1, 10.0f, 0, {0}, {0}},
-		{COL_PING,		BROWSESORT_PING,		localize("Ping"),		1, 40.0f, FIXED, {0}, {0}},
+		{COL_PING,		IServerBrowser::SORT_PING,		Localize("Ping"),		1, 40.0f, FIXED, {0}, {0}},
 	};
-	
-	int num_cols = sizeof(cols)/sizeof(column);
-	
+
+	int NumCols = sizeof(s_aCols)/sizeof(CColumn);
+
 	// do layout
-	for(int i = 0; i < num_cols; i++)
+	for(int i = 0; i < NumCols; i++)
 	{
-		if(cols[i].direction == -1)
+		if(s_aCols[i].m_Direction == -1)
 		{
-			headers.VSplitLeft(cols[i].width, &cols[i].rect, &headers);
-			
-			if(i+1 < num_cols)
+			Headers.VSplitLeft(s_aCols[i].m_Width, &s_aCols[i].m_Rect, &Headers);
+
+			if(i+1 < NumCols)
 			{
-				//cols[i].flags |= SPACER;
-				headers.VSplitLeft(2, &cols[i].spacer, &headers);
+				//Cols[i].flags |= SPACER;
+				Headers.VSplitLeft(2, &s_aCols[i].m_Spacer, &Headers);
 			}
 		}
 	}
-	
-	for(int i = num_cols-1; i >= 0; i--)
+
+	for(int i = NumCols-1; i >= 0; i--)
 	{
-		if(cols[i].direction == 1)
+		if(s_aCols[i].m_Direction == 1)
 		{
-			headers.VSplitRight(cols[i].width, &headers, &cols[i].rect);
-			headers.VSplitRight(2, &headers, &cols[i].spacer);
+			Headers.VSplitRight(s_aCols[i].m_Width, &Headers, &s_aCols[i].m_Rect);
+			Headers.VSplitRight(2, &Headers, &s_aCols[i].m_Spacer);
 		}
 	}
-	
-	for(int i = 0; i < num_cols; i++)
+
+	for(int i = 0; i < NumCols; i++)
 	{
-		if(cols[i].direction == 0)
-			cols[i].rect = headers;
+		if(s_aCols[i].m_Direction == 0)
+			s_aCols[i].m_Rect = Headers;
 	}
-	
+
 	// do headers
-	for(int i = 0; i < num_cols; i++)
+	for(int i = 0; i < NumCols; i++)
 	{
-		if(DoButton_GridHeader(cols[i].caption, cols[i].caption, config.b_sort == cols[i].sort, &cols[i].rect))
+		if(DoButton_GridHeader(s_aCols[i].m_Caption, s_aCols[i].m_Caption, g_Config.m_BrSort == s_aCols[i].m_Sort, &s_aCols[i].m_Rect))
 		{
-			if(cols[i].sort != -1)
+			if(s_aCols[i].m_Sort != -1)
 			{
-				if(config.b_sort == cols[i].sort)
-					config.b_sort_order ^= 1;
+				if(g_Config.m_BrSort == s_aCols[i].m_Sort)
+					g_Config.m_BrSortOrder ^= 1;
 				else
-					config.b_sort_order = 0;
-				config.b_sort = cols[i].sort;
+					g_Config.m_BrSortOrder = 0;
+				g_Config.m_BrSort = s_aCols[i].m_Sort;
 			}
 		}
 	}
-	
-	RenderTools()->DrawUIRect(&view, vec4(0,0,0,0.15f), 0, 0);
-	
-	CUIRect scroll;
-	view.VSplitRight(15, &view, &scroll);
-	
-	int num_servers = client_serverbrowse_sorted_num();
-	
+
+	RenderTools()->DrawUIRect(&View, vec4(0,0,0,0.15f), 0, 0);
+
+	CUIRect Scroll;
+	View.VSplitRight(15, &View, &Scroll);
+
+	int NumServers = ServerBrowser()->NumSortedServers();
+
 	// display important messages in the middle of the screen so no
 	// users misses it
 	{
-		CUIRect msgbox = view;
-		msgbox.y += view.h/3;
-		
-		if(active_page == PAGE_INTERNET && client_serverbrowse_refreshingmasters())
-			UI()->DoLabel(&msgbox, localize("Refreshing master servers"), 16.0f, 0);
-		else if(!client_serverbrowse_num())
-			UI()->DoLabel(&msgbox, localize("No servers found"), 16.0f, 0);
-		else if(client_serverbrowse_num() && !num_servers)
-			UI()->DoLabel(&msgbox, localize("No servers match your filter criteria"), 16.0f, 0);
+		CUIRect MsgBox = View;
+		MsgBox.y += View.h/3;
+
+		if(m_ActivePage == PAGE_INTERNET && ServerBrowser()->IsRefreshingMasters())
+			UI()->DoLabel(&MsgBox, Localize("Refreshing master servers"), 16.0f, 0);
+		else if(!ServerBrowser()->NumServers())
+			UI()->DoLabel(&MsgBox, Localize("No servers found"), 16.0f, 0);
+		else if(ServerBrowser()->NumServers() && !NumServers)
+			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;
-	scroll.HMargin(5.0f, &scroll);
-	scrollvalue = DoScrollbarV(&scrollbar, &scroll, scrollvalue);
-	
-	int scrollnum = num_servers-num+10;
-	if(scrollnum > 0)
+	int Num = (int)(View.h/s_aCols[0].m_Rect.h);
+	static int s_ScrollBar = 0;
+	static float s_ScrollValue = 0;
+
+	Scroll.HMargin(5.0f, &Scroll);
+	s_ScrollValue = DoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue);
+
+	int ScrollNum = NumServers-Num+10;
+	if(ScrollNum > 0)
 	{
-		if(inp_key_presses(KEY_MOUSE_WHEEL_UP))
-			scrollvalue -= 1.0f/scrollnum;
-		if(inp_key_presses(KEY_MOUSE_WHEEL_DOWN))
-			scrollvalue += 1.0f/scrollnum;
-			
-		if(scrollvalue < 0) scrollvalue = 0;
-		if(scrollvalue > 1) scrollvalue = 1;
+		if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP))
+			s_ScrollValue -= 1.0f/ScrollNum;
+		if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN))
+			s_ScrollValue += 1.0f/ScrollNum;
 	}
 	else
-		scrollnum = 0;
+		ScrollNum = 0;
+		
+    if(m_SelectedIndex > -1)
+	{
+		for(int i = 0; i < m_NumInputEvents; i++)
+		{
+			int NewIndex = -1;
+			if(m_aInputEvents[i].m_Flags&IInput::FLAG_PRESS)
+			{
+				if(m_aInputEvents[i].m_Key == KEY_DOWN) NewIndex = m_SelectedIndex + 1;
+				if(m_aInputEvents[i].m_Key == KEY_UP) NewIndex = m_SelectedIndex - 1;
+			}
+			if(NewIndex > -1 && NewIndex < NumServers)
+			{
+			    //scroll
+			    if(ScrollNum)
+			    {
+			        if(NewIndex - m_SelectedIndex > 0)
+                        s_ScrollValue += 1.0f/ScrollNum;
+                    else
+                        s_ScrollValue -= 1.0f/ScrollNum;
+			    }
+			    
+				m_SelectedIndex = NewIndex;
+				
+				const CServerInfo *pItem = ServerBrowser()->SortedGet(m_SelectedIndex);
+				str_copy(g_Config.m_UiServerAddress, pItem->m_aAddress, sizeof(g_Config.m_UiServerAddress));
+			}
+		}
+	}
+	
+    if(s_ScrollValue < 0) s_ScrollValue = 0;
+    if(s_ScrollValue > 1) s_ScrollValue = 1;
 
 	// set clipping
-	UI()->ClipEnable(&view);
-	
-	int start = (int)(scrollnum*scrollvalue);
-	if(start < 0)
-		start = 0;
-	
-	CUIRect original_view = view;
-	view.y -= scrollvalue*scrollnum*cols[0].rect.h;
-	
-	int new_selected = -1;
-	int num_players = 0;
+	UI()->ClipEnable(&View);
+
+	CUIRect OriginalView = View;
+	View.y -= s_ScrollValue*ScrollNum*s_aCols[0].m_Rect.h;
 
-	selected_index = -1;
+	int NewSelected = -1;
+	int NumPlayers = 0;
 
-	for (int i = 0; i < num_servers; i++)
+	m_SelectedIndex = -1;
+
+	for (int i = 0; i < NumServers; i++)
 	{
-		SERVER_INFO *item = client_serverbrowse_sorted_get(i);
-		num_players += item->num_players;
+		const CServerInfo *pItem = ServerBrowser()->SortedGet(i);
+		NumPlayers += pItem->m_NumPlayers;
 	}
-	
-	for (int i = 0; i < num_servers; i++)
+
+	for (int i = 0; i < NumServers; i++)
 	{
-		int item_index = i;
-		SERVER_INFO *item = client_serverbrowse_sorted_get(item_index);
-		CUIRect row;
-        CUIRect select_hit_box;
-		
-		int selected = strcmp(item->address, config.ui_server_address) == 0; //selected_index==item_index;
-		
-		view.HSplitTop(17.0f, &row, &view);
-		select_hit_box = row;
-		
-		if(selected)
-		{
-			selected_index = i;
-			CUIRect r = row;
-			r.Margin(1.5f, &r);
-			RenderTools()->DrawUIRect(&r, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f);
-		}
+		int ItemIndex = i;
+		const CServerInfo *pItem = ServerBrowser()->SortedGet(ItemIndex);
+		CUIRect Row;
+        CUIRect SelectHitBox;
+
+		int Selected = str_comp(pItem->m_aAddress, g_Config.m_UiServerAddress) == 0; //selected_index==ItemIndex;
 
+		View.HSplitTop(17.0f, &Row, &View);
+		SelectHitBox = Row;
+
+		if(Selected)
+			m_SelectedIndex = i;
 
 		// make sure that only those in view can be selected
-		if(row.y+row.h > original_view.y)
+		if(Row.y+Row.h > OriginalView.y && Row.y < OriginalView.y+OriginalView.h)
 		{
-			if(select_hit_box.y < original_view.y) // clip the selection
+			if(Selected)
+			{
+				CUIRect r = Row;
+				r.Margin(1.5f, &r);
+				RenderTools()->DrawUIRect(&r, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f);
+			}
+
+			// clip the selection
+			if(SelectHitBox.y < OriginalView.y) // top
 			{
-				select_hit_box.h -= original_view.y-select_hit_box.y;
-				select_hit_box.y = original_view.y;
+				SelectHitBox.h -= OriginalView.y-SelectHitBox.y;
+				SelectHitBox.y = OriginalView.y;
 			}
-			
-			if(UI()->DoButtonLogic(item, "", selected, &select_hit_box))
+			else if(SelectHitBox.y+SelectHitBox.h > OriginalView.y+OriginalView.h) // bottom
+				SelectHitBox.h = OriginalView.y+OriginalView.h-SelectHitBox.y;
+
+			if(UI()->DoButtonLogic(pItem, "", Selected, &SelectHitBox))
 			{
-				new_selected = item_index;
+				NewSelected = ItemIndex;
 			}
 		}
-		
-		// check if we need to do more
-		if(row.y > original_view.y+original_view.h)
-			break;
+		else
+		{
+			// reset active item, if not visible
+			if(UI()->ActiveItem() == pItem)
+				UI()->SetActiveItem(0);
 
-		for(int c = 0; c < num_cols; c++)
+			// don't render invisible items
+			continue;
+		}
+
+		for(int c = 0; c < NumCols; c++)
 		{
-			CUIRect button;
-			char temp[64];
-			button.x = cols[c].rect.x;
-			button.y = row.y;
-			button.h = row.h;
-			button.w = cols[c].rect.w;
-			
-			//int s = 0;
-			int id = cols[c].id;
-
-			//s = UI()->DoButton(item, "L", l, &button, ui_draw_browse_icon, 0);
-			
-			if(id == COL_FLAG_LOCK)
+			CUIRect Button;
+			char aTemp[64];
+			Button.x = s_aCols[c].m_Rect.x;
+			Button.y = Row.y;
+			Button.h = Row.h;
+			Button.w = s_aCols[c].m_Rect.w;
+
+			int Id = s_aCols[c].m_Id;
+
+			if(Id == COL_FLAG_LOCK)
 			{
-				if(item->flags & SRVFLAG_PASSWORD)
-					DoButton_BrowseIcon(SPRITE_BROWSE_LOCK, &button);
+				if(pItem->m_Flags & SERVER_FLAG_PASSWORD)
+					DoButton_BrowseIcon(SPRITE_BROWSE_LOCK, &Button);
 			}
-			else if(id == COL_FLAG_PURE)
+			else if(Id == COL_FLAG_PURE)
 			{
-				if(strcmp(item->gametype, "DM") == 0 || strcmp(item->gametype, "TDM") == 0 || strcmp(item->gametype, "CTF") == 0)
+				if(	str_comp(pItem->m_aGameType, "DM") == 0 ||
+					str_comp(pItem->m_aGameType, "TDM") == 0 ||
+					str_comp(pItem->m_aGameType, "CTF") == 0)
 				{
 					// pure server
 				}
 				else
 				{
 					// unpure
-					DoButton_BrowseIcon(SPRITE_BROWSE_UNPURE, &button);
+					DoButton_BrowseIcon(SPRITE_BROWSE_UNPURE, &Button);
 				}
 			}
-			else if(id == COL_FLAG_FAV)
+			else if(Id == COL_FLAG_FAV)
 			{
-				if(item->favorite)
-					DoButton_BrowseIcon(SPRITE_BROWSE_HEART, &button);
+				if(pItem->m_Favorite)
+					DoButton_BrowseIcon(SPRITE_BROWSE_HEART, &Button);
 			}
-			else if(id == COL_NAME)
+			else if(Id == COL_NAME)
 			{
-				TEXT_CURSOR cursor;
-				gfx_text_set_cursor(&cursor, button.x, button.y, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
-				cursor.line_width = button.w;
-				
-				if(config.b_filter_string[0] && (item->quicksearch_hit&BROWSEQUICK_SERVERNAME))
+				CTextCursor Cursor;
+				TextRender()->SetCursor(&Cursor, Button.x, Button.y, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
+				Cursor.m_LineWidth = Button.w;
+
+				if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit&IServerBrowser::QUICK_SERVERNAME))
 				{
 					// highlight the parts that matches
-					const char *s = str_find_nocase(item->name, config.b_filter_string);
+					const char *s = str_find_nocase(pItem->m_aName, g_Config.m_BrFilterString);
 					if(s)
 					{
-						gfx_text_ex(&cursor, item->name, (int)(s-item->name));
-						gfx_text_color(0.4f,0.4f,1.0f,1);
-						gfx_text_ex(&cursor, s, strlen(config.b_filter_string));
-						gfx_text_color(1,1,1,1);
-						gfx_text_ex(&cursor, s+strlen(config.b_filter_string), -1);
+						TextRender()->TextEx(&Cursor, pItem->m_aName, (int)(s-pItem->m_aName));
+						TextRender()->TextColor(0.4f,0.4f,1.0f,1);
+						TextRender()->TextEx(&Cursor, s, str_length(g_Config.m_BrFilterString));
+						TextRender()->TextColor(1,1,1,1);
+						TextRender()->TextEx(&Cursor, s+str_length(g_Config.m_BrFilterString), -1);
 					}
 					else
-						gfx_text_ex(&cursor, item->name, -1);
+						TextRender()->TextEx(&Cursor, pItem->m_aName, -1);
 				}
 				else
-					gfx_text_ex(&cursor, item->name, -1);
+					TextRender()->TextEx(&Cursor, pItem->m_aName, -1);
 			}
-			else if(id == COL_MAP)
-				UI()->DoLabel(&button, item->map, 12.0f, -1);
-			else if(id == COL_PLAYERS)
+			else if(Id == COL_MAP)
+				UI()->DoLabel(&Button, pItem->m_aMap, 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()->DoLabel(&button, temp, 12.0f, 1);
-				gfx_text_color(1,1,1,1);
+				str_format(aTemp, sizeof(aTemp), "%i/%i", pItem->m_NumPlayers, pItem->m_MaxPlayers);
+				if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit&IServerBrowser::QUICK_PLAYERNAME))
+					TextRender()->TextColor(0.4f,0.4f,1.0f,1);
+				UI()->DoLabel(&Button, aTemp, 12.0f, 1);
+				TextRender()->TextColor(1,1,1,1);
 			}
-			else if(id == COL_PING)
+			else if(Id == COL_PING)
 			{
-				str_format(temp, sizeof(temp), "%i", item->latency);
-				UI()->DoLabel(&button, temp, 12.0f, 1);
+				str_format(aTemp, sizeof(aTemp), "%i", pItem->m_Latency);
+				UI()->DoLabel(&Button, aTemp, 12.0f, 1);
 			}
-			else if(id == COL_VERSION)
+			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()->DoLabel(&button, version, 12.0f, 1);
-			}			
-			else if(id == COL_GAMETYPE)
+				const char *pVersion = pItem->m_aVersion;
+				if(str_comp(pVersion, "0.3 e2d7973c6647a13c") == 0) // TODO: remove me later on
+					pVersion = "0.3.0";
+				UI()->DoLabel(&Button, pVersion, 12.0f, 1);
+			}
+			else if(Id == COL_GAMETYPE)
 			{
-				UI()->DoLabel(&button, item->gametype, 12.0f, 0);
+				UI()->DoLabel(&Button, pItem->m_aGameType, 12.0f, 0);
 			}
 
 		}
 	}
 
 	UI()->ClipDisable();
-	
-	if(new_selected != -1)
+
+	if(NewSelected != -1)
 	{
 		// select the new server
-		SERVER_INFO *item = client_serverbrowse_sorted_get(new_selected);
-		strncpy(config.ui_server_address, item->address, sizeof(config.ui_server_address));
-		if(inp_mouse_doubleclick())
-			client_connect(config.ui_server_address);
+		const CServerInfo *pItem = ServerBrowser()->SortedGet(NewSelected);
+		str_copy(g_Config.m_UiServerAddress, pItem->m_aAddress, sizeof(g_Config.m_UiServerAddress));
+		if(Input()->MouseDoubleClick())
+			Client()->Connect(g_Config.m_UiServerAddress);
 	}
 
-	RenderTools()->DrawUIRect(&status, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f);
-	status.Margin(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
-	CUIRect quicksearch;
-	status.VSplitLeft(250.0f, &quicksearch, &status);
-	const char *label = localize("Quick search");
-	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);
-	
+	CUIRect QuickSearch, Button;
+	Status.VSplitLeft(260.0f, &QuickSearch, &Status);
+	const char *pLabel = Localize("Quick search:");
+	UI()->DoLabel(&QuickSearch, pLabel, 12.0f, -1);
+	QuickSearch.VSplitLeft(TextRender()->TextWidth(0, 12.0f, pLabel, -1), 0, &QuickSearch);
+	QuickSearch.VSplitLeft(5.0f, 0, &QuickSearch);
+	QuickSearch.VSplitLeft(155.0f, &QuickSearch, &Button);
+	DoEditBox(&g_Config.m_BrFilterString, &QuickSearch, g_Config.m_BrFilterString, sizeof(g_Config.m_BrFilterString), 12.0f, false, CUI::CORNER_L);
+	// clear button
+	{
+		static int s_ClearButton = 0;
+		RenderTools()->DrawUIRect(&Button, vec4(1,1,1,0.33f)*ButtonColorMul(&s_ClearButton), CUI::CORNER_R, 3.0f);
+		UI()->DoLabel(&Button, "x", Button.h*ms_FontmodHeight, 0);
+		if(UI()->DoButtonLogic(&s_ClearButton, "x", 0, &Button))
+		{
+			g_Config.m_BrFilterString[0] = 0;
+			UI()->SetActiveItem(&g_Config.m_BrFilterString);
+		}
+	}
+
 	// 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);
-	status.VSplitRight(gfx_text_width(0, 14.0f, buf, -1), 0, &status);
-	UI()->DoLabel(&status, buf, 14.0f, -1);
+	char aBuf[128];
+	str_format(aBuf, sizeof(aBuf), Localize("%d of %d servers, %d players"), ServerBrowser()->NumSortedServers(), ServerBrowser()->NumServers(), NumPlayers);
+	Status.VSplitRight(TextRender()->TextWidth(0, 14.0f, aBuf, -1), 0, &Status);
+	UI()->DoLabel(&Status, aBuf, 14.0f, -1);
 }
 
-void MENUS::render_serverbrowser_filters(CUIRect view)
+void CMenus::RenderServerbrowserFilters(CUIRect View)
 {
 	// filters
-	CUIRect button;
+	CUIRect Button;
 
-	view.HSplitTop(5.0f, 0, &view);
-	view.VSplitLeft(5.0f, 0, &view);
-	view.VSplitRight(5.0f, &view, 0);
-	view.HSplitBottom(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
-	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;
+	View.HSplitTop(20.0f, &Button, &View);
+	if (DoButton_CheckBox(&g_Config.m_BrFilterEmpty, Localize("Has people playing"), g_Config.m_BrFilterEmpty, &Button))
+		g_Config.m_BrFilterEmpty ^= 1;
 
-	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;
+	View.HSplitTop(20.0f, &Button, &View);
+	if (DoButton_CheckBox(&g_Config.m_BrFilterFull, Localize("Server not full"), g_Config.m_BrFilterFull, &Button))
+		g_Config.m_BrFilterFull ^= 1;
 
-	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;
+	View.HSplitTop(20.0f, &Button, &View);
+	if (DoButton_CheckBox(&g_Config.m_BrFilterPw, Localize("No password"), g_Config.m_BrFilterPw, &Button))
+		g_Config.m_BrFilterPw ^= 1;
 
-	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;
+	View.HSplitTop(20.0f, &Button, &View);
+	if (DoButton_CheckBox((char *)&g_Config.m_BrFilterCompatversion, Localize("Compatible version"), g_Config.m_BrFilterCompatversion, &Button))
+		g_Config.m_BrFilterCompatversion ^= 1;
+
+	View.HSplitTop(20.0f, &Button, &View);
+	if (DoButton_CheckBox((char *)&g_Config.m_BrFilterPure, Localize("Standard gametype"), g_Config.m_BrFilterPure, &Button))
+		g_Config.m_BrFilterPure ^= 1;
+
+	View.HSplitTop(20.0f, &Button, &View);
+	//button.VSplitLeft(20.0f, 0, &button);
+	if (DoButton_CheckBox((char *)&g_Config.m_BrFilterPureMap, Localize("Standard map"), g_Config.m_BrFilterPureMap, &Button))
+		g_Config.m_BrFilterPureMap ^= 1;
 	
-	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;
-
-	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;
-		
-	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);
+	View.HSplitTop(5.0f, 0, &View);
+
+	View.HSplitTop(19.0f, &Button, &View);
+	UI()->DoLabel(&Button, Localize("Game types:"), 12.0f, -1);
+	Button.VSplitLeft(95.0f, 0, &Button);
+	View.HSplitTop(3.0f, 0, &View);
+	DoEditBox(&g_Config.m_BrFilterGametype, &Button, g_Config.m_BrFilterGametype, sizeof(g_Config.m_BrFilterGametype), 12.0f);
 
 	{
-		view.HSplitTop(20.0f, &button, &view);
-		CUIRect editbox;
-		button.VSplitLeft(40.0f, &editbox, &button);
-		button.VSplitLeft(5.0f, &button, &button);
+		View.HSplitTop(19.0f, &Button, &View);
+		CUIRect EditBox;
+		Button.VSplitRight(50.0f, &Button, &EditBox);
+		EditBox.VSplitRight(5.0f, &EditBox, 0);
 		
-		char buf[8];
-		str_format(buf, sizeof(buf), "%d", config.b_filter_ping);
-		DoEditBox(&config.b_filter_ping, &editbox, buf, sizeof(buf), 14.0f);
-		config.b_filter_ping = atoi(buf);
+		UI()->DoLabel(&Button, Localize("Maximum ping:"), 12.0f, -1);
 		
-		UI()->DoLabel(&button, localize("Maximum ping"), 14.0f, -1);
+		char aBuf[5];
+		str_format(aBuf, sizeof(aBuf), "%d", g_Config.m_BrFilterPing);
+		DoEditBox(&g_Config.m_BrFilterPing, &EditBox, aBuf, sizeof(aBuf), 12.0f);
+		g_Config.m_BrFilterPing = str_toint(aBuf);
 	}
-	
-	view.HSplitBottom(button_height, &view, &button);
-	static int clear_button = 0;
-	if(DoButton_Menu(&clear_button, localize("Reset filter"), 0, &button))
+
+	View.HSplitBottom(ms_ButtonHeight, &View, &Button);
+	static int s_ClearButton = 0;
+	if(DoButton_Menu(&s_ClearButton, Localize("Reset filter"), 0, &Button))
 	{
-		config.b_filter_full = 0;
-		config.b_filter_empty = 0;
-		config.b_filter_pw = 0;
-		config.b_filter_ping = 999;
-		config.b_filter_gametype[0] = 0;
-		config.b_filter_compatversion = 1;
-		config.b_filter_string[0] = 0;
-		config.b_filter_pure = 1;
+		g_Config.m_BrFilterFull = 0;
+		g_Config.m_BrFilterEmpty = 0;
+		g_Config.m_BrFilterPw = 0;
+		g_Config.m_BrFilterPing = 999;
+		g_Config.m_BrFilterGametype[0] = 0;
+		g_Config.m_BrFilterCompatversion = 1;
+		g_Config.m_BrFilterString[0] = 0;
+		g_Config.m_BrFilterPure = 1;
+		g_Config.m_BrFilterPureMap = 1;
 	}
 }
 
-void MENUS::render_serverbrowser_serverdetail(CUIRect view)
+void CMenus::RenderServerbrowserServerDetail(CUIRect View)
 {
-	CUIRect server_details = view;
-	CUIRect server_scoreboard, server_header;
-	
-	SERVER_INFO *selected_server = client_serverbrowse_sorted_get(selected_index);
-	
+	CUIRect ServerDetails = View;
+	CUIRect ServerScoreBoard, ServerHeader;
+
+	const CServerInfo *pSelectedServer = ServerBrowser()->SortedGet(m_SelectedIndex);
+
 	//server_details.VSplitLeft(10.0f, 0x0, &server_details);
 
 	// split off a piece to use for scoreboard
-	server_details.HSplitTop(140.0f, &server_details, &server_scoreboard);
-	server_details.HSplitBottom(10.0f, &server_details, 0x0);
+	ServerDetails.HSplitTop(140.0f, &ServerDetails, &ServerScoreBoard);
+	ServerDetails.HSplitBottom(10.0f, &ServerDetails, 0x0);
 
 	// server details
-	const float font_size = 12.0f;
-	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);
+	const float FontSize = 12.0f;
+	ServerDetails.HSplitTop(20.0f, &ServerHeader, &ServerDetails);
+	RenderTools()->DrawUIRect(&ServerHeader, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f);
+	RenderTools()->DrawUIRect(&ServerDetails, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f);
+	ServerHeader.VSplitLeft(8.0f, 0x0, &ServerHeader);
+	UI()->DoLabel(&ServerHeader, Localize("Server details"), FontSize+2.0f, -1);
 
-	server_details.VSplitLeft(5.0f, 0x0, &server_details);
+	ServerDetails.VSplitLeft(5.0f, 0x0, &ServerDetails);
 
-	server_details.Margin(3.0f, &server_details);
+	ServerDetails.Margin(3.0f, &ServerDetails);
 
-	if (selected_server)
+	if (pSelectedServer)
 	{
-		CUIRect row;
-		static LOC_CONSTSTRING labels[] = {
-			localize("Version"),
-			localize("Game type"),
-			localize("Ping")};
+		CUIRect Row;
+		static CLocConstString s_aLabels[] = {
+			Localize("Version"),
+			Localize("Game type"),
+			Localize("Ping")};
 
-		CUIRect left_column;
-		CUIRect right_column;
+		CUIRect LeftColumn;
+		CUIRect RightColumn;
 
-		// 
+		//
 		{
-			CUIRect button;
-			server_details.HSplitBottom(20.0f, &server_details, &button);
-			static int add_fav_button = 0;
-			if(DoButton_CheckBox(&add_fav_button, localize("Favorite"), selected_server->favorite, &button))
+			CUIRect Button;
+			ServerDetails.HSplitBottom(20.0f, &ServerDetails, &Button);
+			static int s_AddFavButton = 0;
+			if(DoButton_CheckBox(&s_AddFavButton, Localize("Favorite"), pSelectedServer->m_Favorite, &Button))
 			{
-				if(selected_server->favorite)
-					client_serverbrowse_removefavorite(selected_server->netaddr);
+				if(pSelectedServer->m_Favorite)
+					ServerBrowser()->RemoveFavorite(pSelectedServer->m_NetAddr);
 				else
-					client_serverbrowse_addfavorite(selected_server->netaddr);
+					ServerBrowser()->AddFavorite(pSelectedServer->m_NetAddr);
 			}
 		}
-		//UI()->DoLabel(&row, temp, font_size, -1);		
+		//UI()->DoLabel(&row, temp, font_size, -1);
 
-		server_details.VSplitLeft(5.0f, 0x0, &server_details);
-		server_details.VSplitLeft(80.0f, &left_column, &right_column);
+		ServerDetails.VSplitLeft(5.0f, 0x0, &ServerDetails);
+		ServerDetails.VSplitLeft(80.0f, &LeftColumn, &RightColumn);
 
-		for (unsigned int i = 0; i < sizeof(labels) / sizeof(labels[0]); i++)
+		for (unsigned int i = 0; i < sizeof(s_aLabels) / sizeof(s_aLabels[0]); i++)
 		{
-			left_column.HSplitTop(15.0f, &row, &left_column);
-			UI()->DoLabel(&row, labels[i], font_size, -1);
+			LeftColumn.HSplitTop(15.0f, &Row, &LeftColumn);
+			UI()->DoLabel(&Row, s_aLabels[i], FontSize, -1);
 		}
 
-		right_column.HSplitTop(15.0f, &row, &right_column);
-		UI()->DoLabel(&row, selected_server->version, font_size, -1);
+		RightColumn.HSplitTop(15.0f, &Row, &RightColumn);
+		UI()->DoLabel(&Row, pSelectedServer->m_aVersion, FontSize, -1);
 
-		right_column.HSplitTop(15.0f, &row, &right_column);
-		UI()->DoLabel(&row, selected_server->gametype, font_size, -1);
+		RightColumn.HSplitTop(15.0f, &Row, &RightColumn);
+		UI()->DoLabel(&Row, pSelectedServer->m_aGameType, FontSize, -1);
 
-		char temp[16];
-		str_format(temp, sizeof(temp), "%d", selected_server->latency);
-		right_column.HSplitTop(15.0f, &row, &right_column);
-		UI()->DoLabel(&row, temp, font_size, -1);
+		char aTemp[16];
+		str_format(aTemp, sizeof(aTemp), "%d", pSelectedServer->m_Latency);
+		RightColumn.HSplitTop(15.0f, &Row, &RightColumn);
+		UI()->DoLabel(&Row, aTemp, FontSize, -1);
 
 	}
-	
+
 	// server scoreboard
-	
-	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);
 
-	server_scoreboard.VSplitLeft(5.0f, 0x0, &server_scoreboard);
+	ServerScoreBoard.HSplitBottom(10.0f, &ServerScoreBoard, 0x0);
+	ServerScoreBoard.HSplitTop(20.0f, &ServerHeader, &ServerScoreBoard);
+	RenderTools()->DrawUIRect(&ServerHeader, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f);
+	RenderTools()->DrawUIRect(&ServerScoreBoard, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f);
+	ServerHeader.VSplitLeft(8.0f, 0x0, &ServerHeader);
+	UI()->DoLabel(&ServerHeader, Localize("Scoreboard"), FontSize+2.0f, -1);
 
-	server_scoreboard.Margin(3.0f, &server_scoreboard);
+	ServerScoreBoard.VSplitLeft(5.0f, 0x0, &ServerScoreBoard);
 
-	if (selected_server)
+	ServerScoreBoard.Margin(3.0f, &ServerScoreBoard);
+
+	if (pSelectedServer)
 	{
-		for (int i = 0; i < selected_server->num_players; i++)
+		for (int i = 0; i < pSelectedServer->m_NumPlayers; i++)
 		{
-			CUIRect row;
-			char temp[16];
-			server_scoreboard.HSplitTop(16.0f, &row, &server_scoreboard);
+			CUIRect Row;
+			char aTemp[16];
+			ServerScoreBoard.HSplitTop(16.0f, &Row, &ServerScoreBoard);
 
-			str_format(temp, sizeof(temp), "%d", selected_server->players[i].score);
-			UI()->DoLabel(&row, temp, font_size, -1);
+			str_format(aTemp, sizeof(aTemp), "%d", pSelectedServer->m_aPlayers[i].m_Score);
+			UI()->DoLabel(&Row, aTemp, FontSize, -1);
 
-			row.VSplitLeft(25.0f, 0x0, &row);
-		
-			TEXT_CURSOR cursor;
-			gfx_text_set_cursor(&cursor, row.x, row.y, 12.0f, TEXTFLAG_RENDER);
-			
-			const char *name = selected_server->players[i].name;
-			if(config.b_filter_string[0])
+			Row.VSplitLeft(25.0f, 0x0, &Row);
+
+			CTextCursor Cursor;
+			TextRender()->SetCursor(&Cursor, Row.x, Row.y, 12.0f, TEXTFLAG_RENDER);
+
+			const char *pName = pSelectedServer->m_aPlayers[i].m_aName;
+			if(g_Config.m_BrFilterString[0])
 			{
 				// highlight the parts that matches
-				const char *s = str_find_nocase(name, config.b_filter_string);
+				const char *s = str_find_nocase(pName, g_Config.m_BrFilterString);
 				if(s)
 				{
-					gfx_text_ex(&cursor, name, (int)(s-name));
-					gfx_text_color(0.4f,0.4f,1,1);
-					gfx_text_ex(&cursor, s, strlen(config.b_filter_string));
-					gfx_text_color(1,1,1,1);
-					gfx_text_ex(&cursor, s+strlen(config.b_filter_string), -1);
+					TextRender()->TextEx(&Cursor, pName, (int)(s-pName));
+					TextRender()->TextColor(0.4f,0.4f,1,1);
+					TextRender()->TextEx(&Cursor, s, str_length(g_Config.m_BrFilterString));
+					TextRender()->TextColor(1,1,1,1);
+					TextRender()->TextEx(&Cursor, s+str_length(g_Config.m_BrFilterString), -1);
 				}
 				else
-					gfx_text_ex(&cursor, name, -1);
+					TextRender()->TextEx(&Cursor, pName, -1);
 			}
 			else
-				gfx_text_ex(&cursor, name, -1);
-			
+				TextRender()->TextEx(&Cursor, pName, -1);
+
 		}
 	}
 }
 
-void MENUS::render_serverbrowser(CUIRect main_view)
+void CMenus::RenderServerbrowser(CUIRect MainView)
 {
-	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
-	
-	CUIRect view;
-	main_view.Margin(10.0f, &view);
-	
+	RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
+
+	CUIRect View;
+	MainView.Margin(10.0f, &View);
+
 	/*
 		+-----------------+ +------+
 		|                 | |      |
@@ -549,100 +596,103 @@ void MENUS::render_serverbrowser(CUIRect main_view)
 		+-----------------+  button
 	      status toolbar      box
 	*/
-	
-	
+
+
 	//CUIRect filters;
-	CUIRect status_toolbar;
-	CUIRect toolbox;
-	CUIRect button_box;
+	CUIRect StatusToolBox;
+	CUIRect ToolBox;
+	CUIRect ButtonBox;
 
 	// split off a piece for filters, details and scoreboard
-	view.VSplitRight(200.0f, &view, &toolbox);
-	toolbox.HSplitBottom(80.0f, &toolbox, &button_box);
-	view.HSplitBottom(button_height+5.0f, &view, &status_toolbar);
+	View.VSplitRight(200.0f, &View, &ToolBox);
+	ToolBox.HSplitBottom(80.0f, &ToolBox, &ButtonBox);
+	View.HSplitBottom(ms_ButtonHeight+5.0f, &View, &StatusToolBox);
 
-	render_serverbrowser_serverlist(view);
-	
-	static int toolbox_page = 0;
-	
-	toolbox.VSplitLeft(5.0f, 0, &toolbox);
+	RenderServerbrowserServerList(View);
+
+	int ToolboxPage = g_Config.m_UiToolboxPage;
+
+	ToolBox.VSplitLeft(5.0f, 0, &ToolBox);
 
 	// do tabbar
 	{
-		CUIRect tab_bar;
-		CUIRect tabbutton0, tabbutton1;
-		toolbox.HSplitTop(22.0f, &tab_bar, &toolbox);
-	
-		tab_bar.VSplitMid(&tabbutton0, &tabbutton1);
-		tabbutton0.VSplitRight(5.0f, &tabbutton0, 0);
-		tabbutton1.VSplitLeft(5.0f, 0, &tabbutton1);
-		
-		static int filters_tab = 0;
-		if (DoButton_MenuTab(&filters_tab, localize("Filter"), toolbox_page==0, &tabbutton0, 0))
-			toolbox_page = 0;
-			
-		static int info_tab = 0;
-		if (DoButton_MenuTab(&info_tab, localize("Info"), toolbox_page==1, &tabbutton1, 0))
-			toolbox_page = 1;
+		CUIRect TabBar;
+		CUIRect TabButton0, TabButton1;
+		ToolBox.HSplitTop(22.0f, &TabBar, &ToolBox);
+
+		TabBar.VSplitMid(&TabButton0, &TabButton1);
+		//TabButton0.VSplitRight(5.0f, &TabButton0, 0);
+		//TabButton1.VSplitLeft(5.0f, 0, &TabButton1);
+
+		static int s_FiltersTab = 0;
+		if (DoButton_MenuTab(&s_FiltersTab, Localize("Filter"), ToolboxPage==0, &TabButton0, CUI::CORNER_TL))
+			ToolboxPage = 0;
+
+		static int s_InfoTab = 0;
+		if (DoButton_MenuTab(&s_InfoTab, Localize("Info"), ToolboxPage==1, &TabButton1, CUI::CORNER_TR))
+			ToolboxPage = 1;
 	}
 
-	RenderTools()->DrawUIRect(&toolbox, vec4(0,0,0,0.15f), 0, 0);
-	
-	toolbox.HSplitTop(5.0f, 0, &toolbox);
-	
-	if(toolbox_page == 0)
-		render_serverbrowser_filters(toolbox);
-	else if(toolbox_page == 1)
-		render_serverbrowser_serverdetail(toolbox);
+	g_Config.m_UiToolboxPage = ToolboxPage;
+
+	RenderTools()->DrawUIRect(&ToolBox, vec4(0,0,0,0.15f), 0, 0);
+
+	ToolBox.HSplitTop(5.0f, 0, &ToolBox);
+
+	if(ToolboxPage == 0)
+		RenderServerbrowserFilters(ToolBox);
+	else if(ToolboxPage == 1)
+		RenderServerbrowserServerDetail(ToolBox);
 
 	{
-		status_toolbar.HSplitTop(5.0f, 0, &status_toolbar);
-		
-		CUIRect button;
+		StatusToolBox.HSplitTop(5.0f, 0, &StatusToolBox);
+
+		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(DoButton_Menu(&refresh_button, localize("Refresh"), 0, &button))
+		StatusToolBox.VSplitRight(110.0f, &StatusToolBox, &Button);
+		Button.VMargin(2.0f, &Button);
+		static int s_RefreshButton = 0;
+		if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &Button))
 		{
-			if(config.ui_page == PAGE_INTERNET)
-				client_serverbrowse_refresh(BROWSETYPE_INTERNET);
-			else if(config.ui_page == PAGE_LAN)
-				client_serverbrowse_refresh(BROWSETYPE_LAN);
-			else if(config.ui_page == PAGE_FAVORITES)
-				client_serverbrowse_refresh(BROWSETYPE_FAVORITES);
+			if(g_Config.m_UiPage == PAGE_INTERNET)
+				ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
+			else if(g_Config.m_UiPage == PAGE_LAN)
+				ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN);
+			else if(g_Config.m_UiPage == PAGE_FAVORITES)
+				ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES);
 		}
-		
-		char buf[512];
-		if(strcmp(client_latestversion(), "0") != 0)
-			str_format(buf, sizeof(buf), localize("Teeworlds %s is out! Download it at www.teeworlds.com!"), client_latestversion());
+
+		char aBuf[512];
+		if(str_comp(Client()->LatestVersion(), "0") != 0)
+			str_format(aBuf, sizeof(aBuf), 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()->DoLabel(&status_toolbar, buf, 14.0f, -1);
+			str_format(aBuf, sizeof(aBuf), Localize("Current version: %s"), GAME_VERSION);
+		UI()->DoLabel(&StatusToolBox, aBuf, 14.0f, -1);
 	}
-	
+
 	// do the button box
 	{
-		
-		button_box.VSplitLeft(5.0f, 0, &button_box);
-		button_box.VSplitRight(5.0f, &button_box, 0);
-		
-		CUIRect button;
-		button_box.HSplitBottom(button_height, &button_box, &button);
-		button.VSplitRight(120.0f, 0, &button);
-		button.VMargin(2.0f, &button);
+
+		ButtonBox.VSplitLeft(5.0f, 0, &ButtonBox);
+		ButtonBox.VSplitRight(5.0f, &ButtonBox, 0);
+
+		CUIRect Button;
+		ButtonBox.HSplitBottom(ms_ButtonHeight, &ButtonBox, &Button);
+		Button.VSplitRight(120.0f, 0, &Button);
+		Button.VMargin(2.0f, &Button);
 		//button.VMargin(2.0f, &button);
-		static int join_button = 0;
-		if(DoButton_Menu(&join_button, localize("Connect"), 0, &button) || enter_pressed)
+		static int s_JoinButton = 0;
+		if(DoButton_Menu(&s_JoinButton, Localize("Connect"), 0, &Button) || m_EnterPressed)
 		{
-			client_connect(config.ui_server_address);
-			enter_pressed = false;
+			dbg_msg("", "%s", g_Config.m_UiServerAddress);
+			Client()->Connect(g_Config.m_UiServerAddress);
+			m_EnterPressed = false;
 		}
-					
-		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);
+
+		ButtonBox.HSplitBottom(5.0f, &ButtonBox, &Button);
+		ButtonBox.HSplitBottom(20.0f, &ButtonBox, &Button);
+		DoEditBox(&g_Config.m_UiServerAddress, &Button, g_Config.m_UiServerAddress, sizeof(g_Config.m_UiServerAddress), 14.0f);
+		ButtonBox.HSplitBottom(20.0f, &ButtonBox, &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 07019d46..62c03a92 100644
--- a/src/game/client/components/menus_demo.cpp
+++ b/src/game/client/components/menus_demo.cpp
@@ -1,86 +1,82 @@
 
-#include <base/math.hpp>
+#include <base/math.h>
 
-//#include <string.h> // strcmp, strlen, strncpy
-//#include <stdlib.h> // atoi
 
-#include <engine/e_client_interface.h>
-#include <game/client/render.hpp>
-#include <game/client/gameclient.hpp>
+#include <engine/demo.h>
+#include <engine/keys.h>
 
-//#include <game/generated/g_protocol.hpp>
-//#include <game/generated/gc_data.hpp>
+#include <game/client/render.h>
+#include <game/client/gameclient.h>
+#include <game/localization.h>
 
-#include <game/client/ui.hpp>
-//#include <game/client/gameclient.hpp>
-//#include <game/client/animstate.hpp>
+#include <game/client/ui.h>
 
-#include "menus.hpp"
+#include "menus.h"
 
-int MENUS::DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
+int CMenus::DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
 {
-	RenderTools()->DrawUIRect(pRect, vec4(1,1,1, Checked ? 0.10f : 0.5f)*button_color_mul(pID), CUI::CORNER_ALL, 5.0f);
+	RenderTools()->DrawUIRect(pRect, vec4(1,1,1, Checked ? 0.10f : 0.5f)*ButtonColorMul(pID), CUI::CORNER_ALL, 5.0f);
 	UI()->DoLabel(pRect, pText, 14.0f, 0);
 	return UI()->DoButtonLogic(pID, pText, Checked, pRect);
 }
 
-void MENUS::render_demoplayer(CUIRect main_view)
+void CMenus::RenderDemoPlayer(CUIRect MainView)
 {
-	const DEMOPLAYBACK_INFO *info = client_demoplayer_getinfo();
+	const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo();
 	
-	const float seekbar_height = 15.0f;
-	const float buttonbar_height = 20.0f;
-	const float margins = 5.0f;
-	float total_height;
+	const float SeekBarHeight = 15.0f;
+	const float ButtonbarHeight = 20.0f;
+	const float Margins = 5.0f;
+	float TotalHeight;
 	
-	if(menu_active)
-		total_height = seekbar_height+buttonbar_height+margins*3;
+	if(m_MenuActive)
+		TotalHeight = SeekBarHeight+ButtonbarHeight+Margins*3;
 	else
-		total_height = seekbar_height+margins*2;
+		TotalHeight = SeekBarHeight+Margins*2;
 	
-	main_view.HSplitBottom(total_height, 0, &main_view);
-	main_view.VSplitLeft(250.0f, 0, &main_view);
-	main_view.VSplitRight(250.0f, &main_view, 0);
+	MainView.HSplitBottom(TotalHeight, 0, &MainView);
+	MainView.VSplitLeft(250.0f, 0, &MainView);
+	MainView.VSplitRight(250.0f, &MainView, 0);
 	
-	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_T, 10.0f);
+	RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_T, 10.0f);
 		
-	main_view.Margin(5.0f, &main_view);
+	MainView.Margin(5.0f, &MainView);
 	
-	CUIRect seekbar, buttonbar;
+	CUIRect SeekBar, ButtonBar;
 	
-	if(menu_active)
+	if(m_MenuActive)
 	{
-		main_view.HSplitTop(seekbar_height, &seekbar, &buttonbar);
-		buttonbar.HSplitTop(margins, 0, &buttonbar);
+		MainView.HSplitTop(SeekBarHeight, &SeekBar, &ButtonBar);
+		ButtonBar.HSplitTop(Margins, 0, &ButtonBar);
 	}
 	else
-		seekbar = main_view;
+		SeekBar = MainView;
 
 	// do seekbar
 	{
-		static int seekbar_id = 0;
-		void *id = &seekbar_id;
-		char buffer[128];
+		static int s_SeekBarId = 0;
+		void *id = &s_SeekBarId;
+		char aBuffer[128];
 		
-		RenderTools()->DrawUIRect(&seekbar, vec4(0,0,0,0.5f), CUI::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;
+		int CurrentTick = pInfo->m_CurrentTick - pInfo->m_FirstTick;
+		int TotalTicks = pInfo->m_LastTick - pInfo->m_FirstTick;
 		
-		float amount = current_tick/(float)total_ticks;
+		float Amount = CurrentTick/(float)TotalTicks;
 		
-		CUIRect filledbar = seekbar;
-		filledbar.w = 10.0f + (filledbar.w-10.0f)*amount;
+		CUIRect FilledBar = SeekBar;
+		FilledBar.w = 10.0f + (FilledBar.w-10.0f)*Amount;
 		
-		RenderTools()->DrawUIRect(&filledbar, vec4(1,1,1,0.5f), CUI::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()->DoLabel(&seekbar, buffer, seekbar.h*0.70f, 0);
+		str_format(aBuffer, sizeof(aBuffer), "%d:%02d / %d:%02d",
+			CurrentTick/SERVER_TICK_SPEED/60, (CurrentTick/SERVER_TICK_SPEED)%60,
+			TotalTicks/SERVER_TICK_SPEED/60, (TotalTicks/SERVER_TICK_SPEED)%60);
+		UI()->DoLabel(&SeekBar, aBuffer, SeekBar.h*0.70f, 0);
 
 		// do the logic
-	    int inside = UI()->MouseInside(&seekbar);
+	    int Inside = UI()->MouseInside(&SeekBar);
 			
 		if(UI()->ActiveItem() == id)
 		{
@@ -88,13 +84,15 @@ void MENUS::render_demoplayer(CUIRect main_view)
 				UI()->SetActiveItem(0);
 			else
 			{
-				float amount = (UI()->MouseX()-seekbar.x)/(float)seekbar.w;
-				if(amount > 0 && amount < 1.0f)
+				static float PrevAmount = 0.0f;
+				float Amount = (UI()->MouseX()-SeekBar.x)/(float)SeekBar.w;
+				if(Amount > 0 && Amount < 1.0f && PrevAmount != Amount)
 				{
-					gameclient.on_reset();
-					gameclient.suppress_events = true;
-					client_demoplayer_setpos(amount);
-					gameclient.suppress_events = false;
+					PrevAmount = Amount;
+					m_pClient->OnReset();
+					m_pClient->m_SuppressEvents = true;
+					DemoPlayer()->SetPos(Amount);
+					m_pClient->m_SuppressEvents = false;
 				}
 			}
 		}
@@ -104,334 +102,357 @@ void MENUS::render_demoplayer(CUIRect main_view)
 				UI()->SetActiveItem(id);
 		}		
 		
-		if(inside)
+		if(Inside)
 			UI()->SetHotItem(id);
 	}	
 	
 
-	if(menu_active)
+	if(m_MenuActive)
 	{
 		// do buttons
-		CUIRect button;
+		CUIRect Button;
 
 		// pause button
-		buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar);
-		static int pause_button = 0;
-		if(DoButton_DemoPlayer(&pause_button, "| |", info->paused, &button))
-			client_demoplayer_setpause(!info->paused);
+		ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar);
+		static int s_PauseButton = 0;
+		if(DoButton_DemoPlayer(&s_PauseButton, "| |", pInfo->m_Paused, &Button))
+		{
+			if(pInfo->m_Paused)
+				DemoPlayer()->Unpause();
+			else
+				DemoPlayer()->Pause();
+		}
 		
 		// play button
-		buttonbar.VSplitLeft(margins, 0, &buttonbar);
-		buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar);
-		static int play_button = 0;
-		if(DoButton_DemoPlayer(&play_button, ">", !info->paused, &button))
+		ButtonBar.VSplitLeft(Margins, 0, &ButtonBar);
+		ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar);
+		static int s_PlayButton = 0;
+		if(DoButton_DemoPlayer(&s_PlayButton, ">", !pInfo->m_Paused, &Button))
 		{
-			client_demoplayer_setpause(0);
-			client_demoplayer_setspeed(1.0f);
+			DemoPlayer()->Unpause();
+			DemoPlayer()->SetSpeed(1.0f);
 		}
 
 		// slowdown
-		buttonbar.VSplitLeft(margins, 0, &buttonbar);
-		buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar);
-		static int slowdown_button = 0;
-		if(DoButton_DemoPlayer(&slowdown_button, "<<", 0, &button))
+		ButtonBar.VSplitLeft(Margins, 0, &ButtonBar);
+		ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar);
+		static int s_SlowDownButton = 0;
+		if(DoButton_DemoPlayer(&s_SlowDownButton, "<<", 0, &Button))
 		{
-			if(info->speed > 4.0f) client_demoplayer_setspeed(4.0f);
-			else if(info->speed > 2.0f) client_demoplayer_setspeed(2.0f);
-			else if(info->speed > 1.0f) client_demoplayer_setspeed(1.0f);
-			else if(info->speed > 0.5f) client_demoplayer_setspeed(0.5f);
-			else client_demoplayer_setspeed(0.05f);
+			if(pInfo->m_Speed > 4.0f) DemoPlayer()->SetSpeed(4.0f);
+			else if(pInfo->m_Speed > 2.0f) DemoPlayer()->SetSpeed(2.0f);
+			else if(pInfo->m_Speed > 1.0f) DemoPlayer()->SetSpeed(1.0f);
+			else if(pInfo->m_Speed > 0.5f) DemoPlayer()->SetSpeed(0.5f);
+			else DemoPlayer()->SetSpeed(0.05f);
 		}
 		
 		// fastforward
-		buttonbar.VSplitLeft(margins, 0, &buttonbar);
-		buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar);
-		static int fastforward_button = 0;
-		if(DoButton_DemoPlayer(&fastforward_button, ">>", 0, &button))
+		ButtonBar.VSplitLeft(Margins, 0, &ButtonBar);
+		ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar);
+		static int s_FastForwardButton = 0;
+		if(DoButton_DemoPlayer(&s_FastForwardButton, ">>", 0, &Button))
 		{
-			if(info->speed < 0.5f) client_demoplayer_setspeed(0.5f);
-			else if(info->speed < 1.0f) client_demoplayer_setspeed(1.0f);
-			else if(info->speed < 2.0f) client_demoplayer_setspeed(2.0f);
-			else if(info->speed < 4.0f) client_demoplayer_setspeed(4.0f);
-			else client_demoplayer_setspeed(8.0f);
+			if(pInfo->m_Speed < 0.5f) DemoPlayer()->SetSpeed(0.5f);
+			else if(pInfo->m_Speed < 1.0f) DemoPlayer()->SetSpeed(1.0f);
+			else if(pInfo->m_Speed < 2.0f) DemoPlayer()->SetSpeed(2.0f);
+			else if(pInfo->m_Speed < 4.0f) DemoPlayer()->SetSpeed(4.0f);
+			else DemoPlayer()->SetSpeed(8.0f);
 		}
 
 		// speed meter
-		buttonbar.VSplitLeft(margins*3, 0, &buttonbar);
-		char buffer[64];
-		if(info->speed >= 1.0f)
-			str_format(buffer, sizeof(buffer), "x%.0f", info->speed);
+		ButtonBar.VSplitLeft(Margins*3, 0, &ButtonBar);
+		char aBuffer[64];
+		if(pInfo->m_Speed >= 1.0f)
+			str_format(aBuffer, sizeof(aBuffer), "x%.0f", pInfo->m_Speed);
 		else
-			str_format(buffer, sizeof(buffer), "x%.1f", info->speed);
-		UI()->DoLabel(&buttonbar, buffer, button.h*0.7f, -1);
+			str_format(aBuffer, sizeof(aBuffer), "x%.1f", pInfo->m_Speed);
+		UI()->DoLabel(&ButtonBar, aBuffer, Button.h*0.7f, -1);
 
 		// close button
-		buttonbar.VSplitRight(buttonbar_height*3, &buttonbar, &button);
-		static int exit_button = 0;
-		if(DoButton_DemoPlayer(&exit_button, localize("Close"), 0, &button))
-			client_disconnect();
+		ButtonBar.VSplitRight(ButtonbarHeight*3, &ButtonBar, &Button);
+		static int s_ExitButton = 0;
+		if(DoButton_DemoPlayer(&s_ExitButton, Localize("Close"), 0, &Button))
+			Client()->Disconnect();
 	}
 }
 
-static CUIRect listbox_originalview;
-static CUIRect listbox_view;
-static float listbox_rowheight;
-static int listbox_itemindex;
-static int listbox_selected_index;
-static int listbox_new_selected;
-static int listbox_doneevents;
-static int listbox_numitems;
-
-void MENUS::ui_do_listbox_start(void *id, const CUIRect *rect, float row_height, const char *title, int num_items, int selected_index)
+static CUIRect gs_ListBoxOriginalView;
+static CUIRect gs_ListBoxView;
+static float gs_ListBoxRowHeight;
+static int gs_ListBoxItemIndex;
+static int gs_ListBoxSelectedIndex;
+static int gs_ListBoxNewSelected;
+static int gs_ListBoxDoneEvents;
+static int gs_ListBoxNumItems;
+static int gs_ListBoxItemsPerRow;
+static float gs_ListBoxScrollValue;
+static bool gs_ListBoxItemActivated;
+
+void CMenus::UiDoListboxStart(void *pId, const CUIRect *pRect, float RowHeight, const char *pTitle, const char *pBottomText, int NumItems,
+								int ItemsPerRow, int SelectedIndex, float ScrollValue)
 {
-	CUIRect scroll, row;
-	CUIRect view = *rect;
-	CUIRect header, footer;
+	CUIRect Scroll, Row;
+	CUIRect View = *pRect;
+	CUIRect Header, Footer;
 	
 	// draw header
-	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);
+	View.HSplitTop(ms_ListheaderHeight, &Header, &View);
+	RenderTools()->DrawUIRect(&Header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); 
+	UI()->DoLabel(&Header, pTitle, Header.h*ms_FontmodHeight, 0);
 
 	// draw footers
-	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);
+	View.HSplitBottom(ms_ListheaderHeight, &View, &Footer);
+	RenderTools()->DrawUIRect(&Footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); 
+	Footer.VSplitLeft(10.0f, 0, &Footer);
+	UI()->DoLabel(&Footer, pBottomText, Header.h*ms_FontmodHeight, 0);
 
 	// background
-	RenderTools()->DrawUIRect(&view, vec4(0,0,0,0.15f), 0, 0);
+	RenderTools()->DrawUIRect(&View, vec4(0,0,0,0.15f), 0, 0);
 
 	// prepare the scroll
-	view.VSplitRight(15, &view, &scroll);
+	View.VSplitRight(15, &View, &Scroll);
 
 	// setup the variables	
-	listbox_originalview = view;
-	listbox_selected_index = selected_index;
-	listbox_new_selected = selected_index;
-	listbox_itemindex = 0;
-	listbox_rowheight = row_height;
-	listbox_numitems = num_items;
-	listbox_doneevents = 0;
-	//int num_servers = client_serverbrowse_sorted_num();
-
+	gs_ListBoxOriginalView = View;
+	gs_ListBoxSelectedIndex = SelectedIndex;
+	gs_ListBoxNewSelected = SelectedIndex;
+	gs_ListBoxItemIndex = 0;
+	gs_ListBoxRowHeight = RowHeight;
+	gs_ListBoxNumItems = NumItems;
+	gs_ListBoxItemsPerRow = ItemsPerRow;
+	gs_ListBoxDoneEvents = 0;
+	gs_ListBoxScrollValue = ScrollValue;
+	gs_ListBoxItemActivated = false;
 
 	// do the scrollbar
-	view.HSplitTop(listbox_rowheight, &row, 0);
+	View.HSplitTop(gs_ListBoxRowHeight, &Row, 0);
 	
-	int num_viewable = (int)(listbox_originalview.h/row.h) + 1;
-	int num = num_items-num_viewable+1;
-	if(num < 0)
-		num = 0;
+	int NumViewable = (int)(gs_ListBoxOriginalView.h/Row.h) + 1;
+	int Num = (NumItems+gs_ListBoxItemsPerRow-1)/gs_ListBoxItemsPerRow-NumViewable+1;
+	if(Num < 0)
+		Num = 0;
+	if(Num > 0)
+	{
+		if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP))
+			gs_ListBoxScrollValue -= 1.0f/Num;
+		if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN))
+			gs_ListBoxScrollValue += 1.0f/Num;
 		
-	static float scrollvalue = 0;
-	scroll.HMargin(5.0f, &scroll);
-	scrollvalue = DoScrollbarV(id, &scroll, scrollvalue);
-
-	int start = (int)(num*scrollvalue);
-	if(start < 0)
-		start = 0;
+		if(gs_ListBoxScrollValue < 0.0f) gs_ListBoxScrollValue = 0.0f;
+		if(gs_ListBoxScrollValue > 1.0f) gs_ListBoxScrollValue = 1.0f;
+	}
+		
+	Scroll.HMargin(5.0f, &Scroll);
+	gs_ListBoxScrollValue = DoScrollbarV(pId, &Scroll, gs_ListBoxScrollValue);
 	
 	// the list
-	listbox_view = listbox_originalview;
-	listbox_view.VMargin(5.0f, &listbox_view);
-	UI()->ClipEnable(&listbox_view);
-	listbox_view.y -= scrollvalue*num*row.h;	
+	gs_ListBoxView = gs_ListBoxOriginalView;
+	gs_ListBoxView.VMargin(5.0f, &gs_ListBoxView);
+	UI()->ClipEnable(&gs_ListBoxView);
+	gs_ListBoxView.y -= gs_ListBoxScrollValue*Num*Row.h;
 }
 
-MENUS::LISTBOXITEM MENUS::ui_do_listbox_nextrow()
+CMenus::CListboxItem CMenus::UiDoListboxNextRow()
 {
-	LISTBOXITEM item = {0};
-	listbox_view.HSplitTop(listbox_rowheight /*-2.0f*/, &item.rect, &listbox_view);
-	item.visible = 1;
+	static CUIRect s_RowView;
+	CListboxItem Item = {0};
+	if(gs_ListBoxItemIndex%gs_ListBoxItemsPerRow == 0)
+		gs_ListBoxView.HSplitTop(gs_ListBoxRowHeight /*-2.0f*/, &s_RowView, &gs_ListBoxView);
+
+	s_RowView.VSplitLeft(s_RowView.w/(gs_ListBoxItemsPerRow-gs_ListBoxItemIndex%gs_ListBoxItemsPerRow), &Item.m_Rect, &s_RowView);
+
+	Item.m_Visible = 1;
 	//item.rect = row;
 	
-	item.hitrect = item.rect;
+	Item.m_HitRect = Item.m_Rect;
 	
 	//CUIRect select_hit_box = item.rect;
 
-	if(listbox_selected_index == listbox_itemindex)
-		item.selected = 1;
+	if(gs_ListBoxSelectedIndex == gs_ListBoxItemIndex)
+		Item.m_Selected = 1;
 	
 	// make sure that only those in view can be selected
-	if(item.rect.y+item.rect.h > listbox_originalview.y)
+	if(Item.m_Rect.y+Item.m_Rect.h > gs_ListBoxOriginalView.y)
 	{
 		
-		if(item.hitrect.y < item.hitrect.y) // clip the selection
+		if(Item.m_HitRect.y < Item.m_HitRect.y) // clip the selection
 		{
-			item.hitrect.h -= listbox_originalview.y-item.hitrect.y;
-			item.hitrect.y = listbox_originalview.y;
+			Item.m_HitRect.h -= gs_ListBoxOriginalView.y-Item.m_HitRect.y;
+			Item.m_HitRect.y = gs_ListBoxOriginalView.y;
 		}
 		
 	}
 	else
-		item.visible = 0;
+		Item.m_Visible = 0;
 
 	// check if we need to do more
-	if(item.rect.y > listbox_originalview.y+listbox_originalview.h)
-		item.visible = 0;
+	if(Item.m_Rect.y > gs_ListBoxOriginalView.y+gs_ListBoxOriginalView.h)
+		Item.m_Visible = 0;
 		
-	listbox_itemindex++;
-	return item;
+	gs_ListBoxItemIndex++;
+	return Item;
 }
 
-MENUS::LISTBOXITEM MENUS::ui_do_listbox_nextitem(void *id)
+CMenus::CListboxItem CMenus::UiDoListboxNextItem(void *pId, bool Selected)
 {
-	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)
-		item.selected = 1;
-	
-	// make sure that only those in view can be selected
-	if(row.y+row.h > listbox_originalview.y)
+	int ThisItemIndex = gs_ListBoxItemIndex;
+	if(Selected)
 	{
-		
-		if(select_hit_box.y < listbox_originalview.y) // clip the selection
-		{
-			select_hit_box.h -= listbox_originalview.y-select_hit_box.y;
-			select_hit_box.y = listbox_originalview.y;
-		}
-		
-		if(UI()->DoButton(id, "", listbox_selected_index==listbox_itemindex, &select_hit_box, 0, 0))
-			listbox_new_selected = listbox_itemindex;
+		if(gs_ListBoxSelectedIndex == gs_ListBoxNewSelected)
+			gs_ListBoxNewSelected = ThisItemIndex;
+		gs_ListBoxSelectedIndex = ThisItemIndex;
 	}
-	else
-		item.visible = 0;
-	
-	item.rect = row;
-	*/
 	
+	CListboxItem Item = UiDoListboxNextRow();
 
-	if(listbox_selected_index == this_itemindex)
+	if(Item.m_Visible && UI()->DoButtonLogic(pId, "", gs_ListBoxSelectedIndex == gs_ListBoxItemIndex, &Item.m_HitRect))
+		gs_ListBoxNewSelected = ThisItemIndex;
+	
+	// process input, regard selected index
+	if(gs_ListBoxSelectedIndex == ThisItemIndex)
 	{
-		if(!listbox_doneevents)
+		if(!gs_ListBoxDoneEvents)
 		{
-			listbox_doneevents = 1;
-			
-			for(int i = 0; i < num_inputevents; i++)
+			gs_ListBoxDoneEvents = 1;
+
+			if(m_EnterPressed || (Input()->MouseDoubleClick() && UI()->ActiveItem() == pId))
 			{
-				if(inputevents[i].flags&INPFLAG_PRESS)
+				gs_ListBoxItemActivated = true;
+			}
+			else
+			{			
+				for(int i = 0; i < m_NumInputEvents; i++)
 				{
-					if(inputevents[i].key == KEY_DOWN) listbox_new_selected++;
-					if(inputevents[i].key == KEY_UP) listbox_new_selected--;
+					int NewIndex = -1;
+					if(m_aInputEvents[i].m_Flags&IInput::FLAG_PRESS)
+					{
+						if(m_aInputEvents[i].m_Key == KEY_DOWN) NewIndex = gs_ListBoxNewSelected + 1;
+						if(m_aInputEvents[i].m_Key == KEY_UP) NewIndex = gs_ListBoxNewSelected - 1;
+					}
+					if(NewIndex > -1 && NewIndex < gs_ListBoxNumItems)
+					{
+						// scroll
+						int NumViewable = (int)(gs_ListBoxOriginalView.h/gs_ListBoxRowHeight) + 1;
+						int ScrollNum = (gs_ListBoxNumItems+gs_ListBoxItemsPerRow-1)/gs_ListBoxItemsPerRow-NumViewable+1;
+						if(ScrollNum > 0 && NewIndex/gs_ListBoxItemsPerRow-gs_ListBoxSelectedIndex/gs_ListBoxItemsPerRow)
+						{
+							// TODO: make the scrolling better
+							if(NewIndex - gs_ListBoxSelectedIndex > 0)
+								gs_ListBoxScrollValue += 1.0f/ScrollNum;
+							else
+								gs_ListBoxScrollValue -= 1.0f/ScrollNum;
+							if(gs_ListBoxScrollValue < 0.0f) gs_ListBoxScrollValue = 0.0f;
+							if(gs_ListBoxScrollValue > 1.0f) gs_ListBoxScrollValue = 1.0f;
+						}
+						
+						gs_ListBoxNewSelected = NewIndex;
+					}
 				}
 			}
-
-			if(listbox_new_selected >= listbox_numitems)
-				listbox_new_selected = listbox_numitems-1;
-			if(listbox_new_selected < 0)
-				listbox_new_selected = 0;
 		}
 		
 		//selected_index = i;
-		CUIRect r = item.rect;
+		CUIRect r = Item.m_Rect;
 		r.Margin(1.5f, &r);
 		RenderTools()->DrawUIRect(&r, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f);
 	}	
 
-	//listbox_itemindex++;
-	return item;
+	return Item;
 }
 
-int MENUS::ui_do_listbox_end()
+int CMenus::UiDoListboxEnd(float *pScrollValue, bool *pItemActivated)
 {
 	UI()->ClipDisable();
-	return listbox_new_selected;
+	if(pScrollValue)
+		*pScrollValue = gs_ListBoxScrollValue;
+	if(pItemActivated)
+		*pItemActivated = gs_ListBoxItemActivated;
+	return gs_ListBoxNewSelected;
 }
 
 struct FETCH_CALLBACKINFO
 {
-	MENUS *self;
-	const char *prefix;
-	int count;
+	CMenus *m_pSelf;
+	const char *m_pPrefix;
+	int m_Count;
 };
 
-void MENUS::demolist_fetch_callback(const char *name, int is_dir, void *user)
+void CMenus::DemolistFetchCallback(const char *pName, int IsDir, void *pUser)
 {
-	if(is_dir || name[0] == '.')
+	if(IsDir || pName[0] == '.')
 		return;
 			
-	FETCH_CALLBACKINFO *info = (FETCH_CALLBACKINFO *)user;
+	FETCH_CALLBACKINFO *pInfo = (FETCH_CALLBACKINFO *)pUser;
 	
-	DEMOITEM item;
-	str_format(item.filename, sizeof(item.filename), "%s/%s", info->prefix, name);
-	str_copy(item.name, name, sizeof(item.name));
-	info->self->demos.add(item);
+	CDemoItem Item;
+	str_format(Item.m_aFilename, sizeof(Item.m_aFilename), "%s/%s", pInfo->m_pPrefix, pName);
+	str_copy(Item.m_aName, pName, sizeof(Item.m_aName));
+	pInfo->m_pSelf->m_lDemos.add(Item);
 }
 
-void MENUS::demolist_populate()
+void CMenus::DemolistPopulate()
 {
-	demos.clear();
+	m_lDemos.clear();
 	
-	char buf[512];
-	str_format(buf, sizeof(buf), "%s/demos", client_user_directory());
+	char aBuf[512];
+	str_format(aBuf, sizeof(aBuf), "%s/demos", Client()->UserDirectory());
 
-	FETCH_CALLBACKINFO info = {this, buf, 0};
-	fs_listdir(buf, demolist_fetch_callback, &info);
-	info.prefix = "demos";
-	fs_listdir("demos", demolist_fetch_callback, &info);
+	FETCH_CALLBACKINFO Info = {this, aBuf, 0};
+	fs_listdir(aBuf, DemolistFetchCallback, &Info);
+	Info.m_pPrefix = "demos";
+	fs_listdir("demos", DemolistFetchCallback, &Info);
 }
 
 
-void MENUS::render_demolist(CUIRect main_view)
+void CMenus::RenderDemoList(CUIRect MainView)
 {
-	static int inited = 0;
-	if(!inited)
-		demolist_populate();
-	inited = 1;
+	static int s_Inited = 0;
+	if(!s_Inited)
+		DemolistPopulate();
+	s_Inited = 1;
 	
 	// render background
-	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
-	main_view.Margin(10.0f, &main_view);
+	RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
+	MainView.Margin(10.0f, &MainView);
 	
-	CUIRect buttonbar;
-	main_view.HSplitBottom(button_height+5.0f, &main_view, &buttonbar);
-	buttonbar.HSplitTop(5.0f, 0, &buttonbar);
+	CUIRect ButtonBar;
+	MainView.HSplitBottom(ms_ButtonHeight+5.0f, &MainView, &ButtonBar);
+	ButtonBar.HSplitTop(5.0f, 0, &ButtonBar);
 	
-	static int selected_item = -1;
-	static int demolist_id = 0;
+	static int s_SelectedItem = -1;
+	static int s_DemoListId = 0;
+	static float s_ScrollValue = 0;
 	
-	ui_do_listbox_start(&demolist_id, &main_view, 17.0f, localize("Demos"), demos.size(), selected_item);
+	UiDoListboxStart(&s_DemoListId, &MainView, 17.0f, Localize("Demos"), "", m_lDemos.size(), 1, s_SelectedItem, s_ScrollValue);
 	//for(int i = 0; i < num_demos; i++)
-	for(sorted_array<DEMOITEM>::range r = demos.all(); !r.empty(); r.pop_front())
+	for(sorted_array<CDemoItem>::range r = m_lDemos.all(); !r.empty(); r.pop_front())
 	{
-		LISTBOXITEM item = ui_do_listbox_nextitem((void*)(&r.front()));
-		if(item.visible)
-			UI()->DoLabel(&item.rect, r.front().name, item.rect.h*fontmod_height, -1);
+		CListboxItem Item = UiDoListboxNextItem((void*)(&r.front()));
+		if(Item.m_Visible)
+			UI()->DoLabel(&Item.m_Rect, r.front().m_aName, Item.m_Rect.h*ms_FontmodHeight, -1);
 	}
-	selected_item = ui_do_listbox_end();
-	
-	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);
+	bool Activated = false;
+	s_SelectedItem = UiDoListboxEnd(&s_ScrollValue, &Activated);
 	
-	static int refresh_button = 0;
-	if(DoButton_Menu(&refresh_button, localize("Refresh"), 0, &refresh_rect))
-	{
-		demolist_populate();
-	}	
+	CUIRect RefreshRect, PlayRect;
+	ButtonBar.VSplitRight(250.0f, &ButtonBar, &RefreshRect);
+	RefreshRect.VSplitRight(130.0f, &RefreshRect, &PlayRect);
+	PlayRect.VSplitRight(120.0f, 0x0, &PlayRect);
 	
-	static int play_button = 0;
-	if(DoButton_Menu(&play_button, localize("Play"), 0, &play_rect))
+	static int s_RefreshButton = 0;
+	if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &RefreshRect))
 	{
-		if(selected_item >= 0 && selected_item < demos.size())
+		DemolistPopulate();
+	}
+		
+	static int s_PlayButton = 0;
+	if(DoButton_Menu(&s_PlayButton, Localize("Play"), 0, &PlayRect) || Activated)
+	{		
+		if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size())
 		{
-			const char *error = client_demoplayer_play(demos[selected_item].filename);
-			if(error)
-				popup_message(localize("Error"), error, localize("Ok"));
+			const char *pError = Client()->DemoPlayer_Play(m_lDemos[s_SelectedItem].m_aFilename);
+			if(pError)
+				PopupMessage(Localize("Error"), pError, Localize("Ok"));
 		}
 	}
 	
diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp
index d31a15bd..7d1f2513 100644
--- a/src/game/client/components/menus_ingame.cpp
+++ b/src/game/client/components/menus_ingame.cpp
@@ -1,89 +1,90 @@
 
-#include <base/math.hpp>
+#include <base/math.h>
 
-#include <string.h> // strcmp, strlen, strncpy
-#include <stdlib.h> // atoi
 
-#include <engine/e_client_interface.h>
+#include <engine/serverbrowser.h>
+#include <engine/textrender.h>
+#include <engine/shared/config.h>
 
-#include <game/generated/g_protocol.hpp>
-#include <game/generated/gc_data.hpp>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
 
-#include <game/client/ui.hpp>
-#include <game/client/gameclient.hpp>
-#include <game/client/animstate.hpp>
+#include <game/client/ui.h>
+#include <game/client/gameclient.h>
+#include <game/client/animstate.h>
+#include <game/localization.h>
 
-#include "menus.hpp"
-#include "motd.hpp"
-#include "voting.hpp"
+#include "menus.h"
+#include "motd.h"
+#include "voting.h"
 
-void MENUS::render_game(CUIRect main_view)
+void CMenus::RenderGame(CUIRect MainView)
 {
-	CUIRect button;
+	CUIRect Button;
 	//CUIRect votearea;
-	main_view.HSplitTop(45.0f, &main_view, 0);
-	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
+	MainView.HSplitTop(45.0f, &MainView, 0);
+	RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, 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);
+	MainView.HSplitTop(10.0f, 0, &MainView);
+	MainView.HSplitTop(25.0f, &MainView, 0);
+	MainView.VMargin(10.0f, &MainView);
 	
-	main_view.VSplitRight(120.0f, &main_view, &button);
-	static int disconnect_button = 0;
-	if(DoButton_Menu(&disconnect_button, localize("Disconnect"), 0, &button))
-		client_disconnect();
+	MainView.VSplitRight(120.0f, &MainView, &Button);
+	static int s_DisconnectButton = 0;
+	if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Button))
+		Client()->Disconnect();
 
-	if(gameclient.snap.local_info && gameclient.snap.gameobj)
+	if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pGameobj)
 	{
-		if(gameclient.snap.local_info->team != -1)
+		if(m_pClient->m_Snap.m_pLocalInfo->m_Team != -1)
 		{
-			main_view.VSplitLeft(10.0f, &button, &main_view);
-			main_view.VSplitLeft(120.0f, &button, &main_view);
-			static int spectate_button = 0;
-			if(DoButton_Menu(&spectate_button, localize("Spectate"), 0, &button))
+			MainView.VSplitLeft(10.0f, &Button, &MainView);
+			MainView.VSplitLeft(120.0f, &Button, &MainView);
+			static int s_SpectateButton = 0;
+			if(DoButton_Menu(&s_SpectateButton, Localize("Spectate"), 0, &Button))
 			{
-				gameclient.send_switch_team(-1);
-				set_active(false);
+				m_pClient->SendSwitchTeam(-1);
+				SetActive(false);
 			}
 		}
 		
-		if(gameclient.snap.gameobj->flags & GAMEFLAG_TEAMS)
+		if(m_pClient->m_Snap.m_pGameobj->m_Flags & GAMEFLAG_TEAMS)
 		{
-			if(gameclient.snap.local_info->team != 0)
+			if(m_pClient->m_Snap.m_pLocalInfo->m_Team != 0)
 			{
-				main_view.VSplitLeft(10.0f, &button, &main_view);
-				main_view.VSplitLeft(120.0f, &button, &main_view);
-				static int spectate_button = 0;
-				if(DoButton_Menu(&spectate_button, localize("Join red"), 0, &button))
+				MainView.VSplitLeft(10.0f, &Button, &MainView);
+				MainView.VSplitLeft(120.0f, &Button, &MainView);
+				static int s_SpectateButton = 0;
+				if(DoButton_Menu(&s_SpectateButton, Localize("Join red"), 0, &Button))
 				{
-					gameclient.send_switch_team(0);
-					set_active(false);
+					m_pClient->SendSwitchTeam(0);
+					SetActive(false);
 				}
 			}
 
-			if(gameclient.snap.local_info->team != 1)
+			if(m_pClient->m_Snap.m_pLocalInfo->m_Team != 1)
 			{
-				main_view.VSplitLeft(10.0f, &button, &main_view);
-				main_view.VSplitLeft(120.0f, &button, &main_view);
-				static int spectate_button = 0;
-				if(DoButton_Menu(&spectate_button, localize("Join blue"), 0, &button))
+				MainView.VSplitLeft(10.0f, &Button, &MainView);
+				MainView.VSplitLeft(120.0f, &Button, &MainView);
+				static int s_SpectateButton = 0;
+				if(DoButton_Menu(&s_SpectateButton, Localize("Join blue"), 0, &Button))
 				{
-					gameclient.send_switch_team(1);
-					set_active(false);
+					m_pClient->SendSwitchTeam(1);
+					SetActive(false);
 				}
 			}
 		}
 		else
 		{
-			if(gameclient.snap.local_info->team != 0)
+			if(m_pClient->m_Snap.m_pLocalInfo->m_Team != 0)
 			{
-				main_view.VSplitLeft(10.0f, &button, &main_view);
-				main_view.VSplitLeft(120.0f, &button, &main_view);
-				static int spectate_button = 0;
-				if(DoButton_Menu(&spectate_button, localize("Join game"), 0, &button))
+				MainView.VSplitLeft(10.0f, &Button, &MainView);
+				MainView.VSplitLeft(120.0f, &Button, &MainView);
+				static int s_SpectateButton = 0;
+				if(DoButton_Menu(&s_SpectateButton, Localize("Join game"), 0, &Button))
 				{
-					gameclient.send_switch_team(0);
-					set_active(false);
+					m_pClient->SendSwitchTeam(0);
+					SetActive(false);
 				}
 			}
 		}
@@ -141,102 +142,102 @@ void MENUS::render_game(CUIRect main_view)
 	}*/
 }
 
-void MENUS::render_serverinfo(CUIRect main_view)
+void CMenus::RenderServerInfo(CUIRect MainView)
 {
 	// fetch server info
-	SERVER_INFO current_server_info;
-	client_serverinfo(&current_server_info);
+	CServerInfo CurrentServerInfo;
+	Client()->GetServerInfo(&CurrentServerInfo);
 	
-	if(!gameclient.snap.local_info)
+	if(!m_pClient->m_Snap.m_pLocalInfo)
 		return;
 	
 	// count players for server info-box
-	int num_players = 0;
-	for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
+	int NumPlayers = 0;
+	for(int i = 0; i < Client()->SnapNumItems(IClient::SNAP_CURRENT); i++)
 	{
-		SNAP_ITEM item;
-		snap_get_item(SNAP_CURRENT, i, &item);
+		IClient::CSnapItem Item;
+		Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item);
 
-		if(item.type == NETOBJTYPE_PLAYER_INFO)
+		if(Item.m_Type == NETOBJTYPE_PLAYERINFO)
 		{
-			num_players++;
+			NumPlayers++;
 		}
 	}
 
 	// render background
-	RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f);
+	RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
 	
-	CUIRect view, serverinfo, gameinfo, motd;
+	CUIRect View, ServerInfo, GameInfo, Motd;
 	
 	float x = 0.0f;
 	float y = 0.0f;
 	
-	char buf[1024];
+	char aBuf[1024];
 	
 	// set view to use for all sub-modules
-	main_view.Margin(10.0f, &view);
+	MainView.Margin(10.0f, &View);
 	
-	/* serverinfo */
-	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);
+	// serverinfo
+	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);
 	
-	serverinfo.Margin(5.0f, &serverinfo);
+	ServerInfo.Margin(5.0f, &ServerInfo);
 	
 	x = 5.0f;
 	y = 0.0f;
 	
-	gfx_text(0, serverinfo.x+x, serverinfo.y+y, 32, localize("Server info"), 250);
+	TextRender()->Text(0, ServerInfo.x+x, ServerInfo.y+y, 32, Localize("Server info"), 250);
 	y += 32.0f+5.0f;
 	
-	mem_zero(buf, sizeof(buf));
+	mem_zero(aBuf, sizeof(aBuf));
 	str_format(
-		buf,
-		sizeof(buf),
+		aBuf,
+		sizeof(aBuf),
 		"%s\n\n"
 		"%s: %s\n"
 		"%s: %d\n"
 		"%s: %s\n"
 		"%s: %s\n",
-		current_server_info.name,
-		localize("Address"), config.ui_server_address,
-		localize("Ping"), gameclient.snap.local_info->latency,
-		localize("Version"), current_server_info.version,
-		localize("Password"), current_server_info.flags&1 ? localize("Yes") : localize("No")
+		CurrentServerInfo.m_aName,
+		Localize("Address"), g_Config.m_UiServerAddress,
+		Localize("Ping"), m_pClient->m_Snap.m_pLocalInfo->m_Latency,
+		Localize("Version"), CurrentServerInfo.m_aVersion,
+		Localize("Password"), CurrentServerInfo.m_Flags &1 ? Localize("Yes") : Localize("No")
 	);
 	
-	gfx_text(0, serverinfo.x+x, serverinfo.y+y, 20, buf, 250);
+	TextRender()->Text(0, ServerInfo.x+x, ServerInfo.y+y, 20, aBuf, 250);
 	
 	{
-		CUIRect button;
-		int is_favorite = client_serverbrowse_isfavorite(current_server_info.netaddr);
-		serverinfo.HSplitBottom(20.0f, &serverinfo, &button);
-		static int add_fav_button = 0;
-		if(DoButton_CheckBox(&add_fav_button, localize("Favorite"), is_favorite, &button))
+		CUIRect Button;
+		int IsFavorite = ServerBrowser()->IsFavorite(CurrentServerInfo.m_NetAddr);
+		ServerInfo.HSplitBottom(20.0f, &ServerInfo, &Button);
+		static int s_AddFavButton = 0;
+		if(DoButton_CheckBox(&s_AddFavButton, Localize("Favorite"), IsFavorite, &Button))
 		{
-			if(is_favorite)
-				client_serverbrowse_removefavorite(current_server_info.netaddr);
+			if(IsFavorite)
+				ServerBrowser()->RemoveFavorite(CurrentServerInfo.m_NetAddr);
 			else
-				client_serverbrowse_addfavorite(current_server_info.netaddr);
+				ServerBrowser()->AddFavorite(CurrentServerInfo.m_NetAddr);
 		}
 	}
 	
-	/* gameinfo */
-	gameinfo.VSplitLeft(10.0f, 0x0, &gameinfo);
-	RenderTools()->DrawUIRect(&gameinfo, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+	// gameinfo
+	GameInfo.VSplitLeft(10.0f, 0x0, &GameInfo);
+	RenderTools()->DrawUIRect(&GameInfo, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
 	
-	gameinfo.Margin(5.0f, &gameinfo);
+	GameInfo.Margin(5.0f, &GameInfo);
 	
 	x = 5.0f;
 	y = 0.0f;
 	
-	gfx_text(0, gameinfo.x+x, gameinfo.y+y, 32, localize("Game info"), 250);
+	TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 32, Localize("Game info"), 250);
 	y += 32.0f+5.0f;
 	
-	mem_zero(buf, sizeof(buf));
+	mem_zero(aBuf, sizeof(aBuf));
 	str_format(
-		buf,
-		sizeof(buf),
+		aBuf,
+		sizeof(aBuf),
 		"\n\n"
 		"%s: %s\n"
 		"%s: %s\n"
@@ -244,153 +245,178 @@ void MENUS::render_serverinfo(CUIRect main_view)
 		"%s: %d\n"
 		"\n"
 		"%s: %d/%d\n",
-		localize("Game type"), current_server_info.gametype,
-		localize("Map"), current_server_info.map,
-		localize("Score limit"), gameclient.snap.gameobj->score_limit,
-		localize("Time limit"), gameclient.snap.gameobj->time_limit,
-		localize("Players"), gameclient.snap.num_players, current_server_info.max_players
+		Localize("Game type"), CurrentServerInfo.m_aGameType,
+		Localize("Map"), CurrentServerInfo.m_aMap,
+		Localize("Score limit"), m_pClient->m_Snap.m_pGameobj->m_ScoreLimit,
+		Localize("Time limit"), m_pClient->m_Snap.m_pGameobj->m_TimeLimit,
+		Localize("Players"), m_pClient->m_Snap.m_NumPlayers, CurrentServerInfo.m_MaxPlayers
 	);
-	gfx_text(0, gameinfo.x+x, gameinfo.y+y, 20, buf, 250);
+	TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 20, aBuf, 250);
 	
-	/* 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);
+	// 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);
+	TextRender()->Text(0, Motd.x+x, Motd.y+y, 32, Localize("MOTD"), -1);
 	y += 32.0f+5.0f;
-	gfx_text(0, motd.x+x, motd.y+y, 16, gameclient.motd->server_motd, (int)motd.w);
+	TextRender()->Text(0, Motd.x+x, Motd.y+y, 16, m_pClient->m_pMotd->m_aServerMotd, (int)Motd.w);
 }
 
-static const char *format_command(const char *cmd)
+static const char *FormatCommand(const char *pCmd)
 {
-	return cmd;
+	return pCmd;
 }
 
-void MENUS::render_servercontrol_server(CUIRect main_view)
+void CMenus::RenderServerControlServer(CUIRect MainView)
 {
-	int num_options = 0;
-	for(VOTING::VOTEOPTION *option = gameclient.voting->first; option; option = option->next)
-		num_options++;
-
-	static int votelist = 0;
-	CUIRect list = main_view;
-	ui_do_listbox_start(&votelist, &list, 24.0f, localize("Settings"), num_options, callvote_selectedoption);
+	int NumOptions = 0;
+	for(CVoting::CVoteOption *pOption = m_pClient->m_pVoting->m_pFirst; pOption; pOption = pOption->m_pNext)
+		NumOptions++;
+
+	static int s_VoteList = 0;
+	static float s_ScrollValue = 0;
+	CUIRect List = MainView;
+	UiDoListboxStart(&s_VoteList, &List, 24.0f, Localize("Settings"), "", NumOptions, 1, m_CallvoteSelectedOption, s_ScrollValue);
 	
-	for(VOTING::VOTEOPTION *option = gameclient.voting->first; option; option = option->next)
+	for(CVoting::CVoteOption *pOption = m_pClient->m_pVoting->m_pFirst; pOption; pOption = pOption->m_pNext)
 	{
-		LISTBOXITEM item = ui_do_listbox_nextitem(option);
+		CListboxItem Item = UiDoListboxNextItem(pOption);
 		
-		if(item.visible)
-			UI()->DoLabel(&item.rect, format_command(option->command), 16.0f, -1);
+		if(Item.m_Visible)
+			UI()->DoLabel(&Item.m_Rect, FormatCommand(pOption->m_aCommand), 16.0f, -1);
 	}
 	
-	callvote_selectedoption = ui_do_listbox_end();
+	m_CallvoteSelectedOption = UiDoListboxEnd(&s_ScrollValue, 0);
 }
 
-void MENUS::render_servercontrol_kick(CUIRect main_view)
+void CMenus::RenderServerControlKick(CUIRect MainView)
 {
 	// draw header
-	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);
+	CUIRect Header, Footer;
+	MainView.HSplitTop(20, &Header, &MainView);
+	RenderTools()->DrawUIRect(&Header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); 
+	UI()->DoLabel(&Header, Localize("Players"), 18.0f, 0);
 
 	// draw footers	
-	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);
+	MainView.HSplitBottom(20, &MainView, &Footer);
+	RenderTools()->DrawUIRect(&Footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); 
+	Footer.VSplitLeft(10.0f, 0, &Footer);
 
 	// players
-	RenderTools()->DrawUIRect(&main_view, vec4(0,0,0,0.15f), 0, 0);
-	CUIRect list = main_view;
+	RenderTools()->DrawUIRect(&MainView, vec4(0,0,0,0.15f), 0, 0);
+	CUIRect List = MainView;
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
-		if(!gameclient.snap.player_infos[i])
+		if(!m_pClient->m_Snap.m_paPlayerInfos[i])
 			continue;
 
-		CUIRect button;
-		list.HSplitTop(button_height, &button, &list);
+		CUIRect Button;
+		List.HSplitTop(ms_ButtonHeight, &Button, &List);
 		
-		if(DoButton_ListRow((char *)&gameclient.snap+i, "", callvote_selectedplayer == i, &button))
-			callvote_selectedplayer = i;
+		if(DoButton_ListRow((char *)&m_pClient->m_Snap+i, "", m_CallvoteSelectedPlayer == i, &Button))
+			m_CallvoteSelectedPlayer = i;
 
-		TEE_RENDER_INFO info = gameclient.clients[i].render_info;
-		info.size = button.h;
-		RenderTools()->RenderTee(ANIMSTATE::get_idle(), &info, EMOTE_NORMAL, vec2(1,0), vec2(button.x+button.h/2, button.y+button.h/2));
+		CTeeRenderInfo Info = m_pClient->m_aClients[i].m_RenderInfo;
+		Info.m_Size = Button.h;
+		RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, EMOTE_NORMAL, vec2(1,0), vec2(Button.x+Button.h/2, Button.y+Button.h/2));
 
-		button.x += button.h;
-		UI()->DoLabel(&button, gameclient.clients[i].name, 18.0f, -1);
+		Button.x += Button.h;
+		UI()->DoLabel(&Button, m_pClient->m_aClients[i].m_aName, 18.0f, -1);
 	}
 }
 
-void MENUS::render_servercontrol(CUIRect main_view)
+void CMenus::RenderServerControl(CUIRect MainView)
 {
-	static int control_page = 0;
+	static int s_ControlPage = 0;
 	
 	// render background
-	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);
+	CUIRect Temp, TabBar;
+	MainView.VSplitRight(120.0f, &MainView, &TabBar);
+	RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B|CUI::CORNER_TL, 10.0f);
+	TabBar.HSplitTop(50.0f, &Temp, &TabBar);
+	RenderTools()->DrawUIRect(&Temp, ms_ColorTabbarActive, CUI::CORNER_R, 10.0f);
 	
-	main_view.HSplitTop(10.0f, 0, &main_view);
+	MainView.HSplitTop(10.0f, 0, &MainView);
 	
-	CUIRect button;
+	CUIRect Button;
 	
-	const char *tabs[] = {
-		localize("Settings"),
-		localize("Kick")};
-	int num_tabs = (int)(sizeof(tabs)/sizeof(*tabs));
+	const char *paTabs[] = {
+		Localize("Settings"),
+		Localize("Kick")};
+	int aNumTabs = (int)(sizeof(paTabs)/sizeof(*paTabs));
 	
-	for(int i = 0; i < num_tabs; i++)
+	for(int i = 0; i < aNumTabs; i++)
 	{
-		tabbar.HSplitTop(10, &button, &tabbar);
-		tabbar.HSplitTop(26, &button, &tabbar);
-		if(DoButton_SettingsTab(tabs[i], tabs[i], control_page == i, &button))
+		TabBar.HSplitTop(10, &Button, &TabBar);
+		TabBar.HSplitTop(26, &Button, &TabBar);
+		if(DoButton_SettingsTab(paTabs[i], paTabs[i], s_ControlPage == i, &Button))
 		{
-			control_page = i;
-			callvote_selectedplayer = -1;
-			callvote_selectedoption = -1;
+			s_ControlPage = i;
+			m_CallvoteSelectedPlayer = -1;
+			m_CallvoteSelectedOption = -1;
 		}
 	}
 		
-	main_view.Margin(10.0f, &main_view);
-	CUIRect bottom;
-	main_view.HSplitBottom(button_height + 5*2, &main_view, &bottom);
-	bottom.HMargin(5.0f, &bottom);
+	MainView.Margin(10.0f, &MainView);
+	CUIRect Bottom;
+	MainView.HSplitBottom(ms_ButtonHeight + 5*2, &MainView, &Bottom);
+	Bottom.HMargin(5.0f, &Bottom);
 	
 	// render page		
-	if(control_page == 0)
-		render_servercontrol_server(main_view);
-	else if(control_page == 1)
-		render_servercontrol_kick(main_view);
+	if(s_ControlPage == 0)
+		RenderServerControlServer(MainView);
+	else if(s_ControlPage == 1)
+		RenderServerControlKick(MainView);
 		
 
 	{
-		CUIRect button;
-		bottom.VSplitRight(120.0f, &bottom, &button);
+		CUIRect Button;
+		Bottom.VSplitRight(120.0f, &Bottom, &Button);
 		
-		static int callvote_button = 0;
-		if(DoButton_Menu(&callvote_button, localize("Call vote"), 0, &button))
+		static int s_CallVoteButton = 0;
+		if(DoButton_Menu(&s_CallVoteButton, Localize("Call vote"), 0, &Button))
 		{
-			if(control_page == 0)
+			if(s_ControlPage == 0)
 			{
 				//
-				gameclient.voting->callvote_option(callvote_selectedoption);
+				m_pClient->m_pVoting->CallvoteOption(m_CallvoteSelectedOption);
 				/*
 				if(callvote_selectedmap >= 0 && callvote_selectedmap < gameclient.maplist->num())
 					gameclient.voting->callvote_map(gameclient.maplist->name(callvote_selectedmap));*/
 			}
-			else if(control_page == 1)
+			else if(s_ControlPage == 1)
+			{
+				if(m_CallvoteSelectedPlayer >= 0 && m_CallvoteSelectedPlayer < MAX_CLIENTS &&
+					m_pClient->m_Snap.m_paPlayerInfos[m_CallvoteSelectedPlayer])
+				{
+					m_pClient->m_pVoting->CallvoteKick(m_CallvoteSelectedPlayer);
+					SetActive(false);
+				}
+			}
+		}
+
+		// force vote button (only available when authed in rcon)
+		if(Client()->RconAuthed())
+		{
+			Bottom.VSplitLeft(120.0f, &Button, &Bottom);
+			
+			static int s_ForceVoteButton = 0;
+			if(DoButton_Menu(&s_ForceVoteButton, Localize("Force vote"), 0, &Button))
 			{
-				if(callvote_selectedplayer >= 0 && callvote_selectedplayer < MAX_CLIENTS &&
-					gameclient.snap.player_infos[callvote_selectedplayer])
+				if(s_ControlPage == 0)
+				{
+					m_pClient->m_pVoting->ForcevoteOption(m_CallvoteSelectedOption);
+				}
+				else if(s_ControlPage == 1)
 				{
-					gameclient.voting->callvote_kick(callvote_selectedplayer);
-					set_active(false);
+					if(m_CallvoteSelectedPlayer >= 0 && m_CallvoteSelectedPlayer < MAX_CLIENTS &&
+						m_pClient->m_Snap.m_paPlayerInfos[m_CallvoteSelectedPlayer])
+					{
+						m_pClient->m_pVoting->ForcevoteKick(m_CallvoteSelectedPlayer);
+						SetActive(false);
+					}
 				}
 			}
 		}
diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp
index 05b4d047..a612ed77 100644
--- a/src/game/client/components/menus_settings.cpp
+++ b/src/game/client/components/menus_settings.cpp
@@ -1,821 +1,752 @@
 
-#include <base/math.hpp>
+#include <base/math.h>
 
-#include <string.h> // strcmp, strlen, strncpy
-#include <stdlib.h> // atoi
 
-#include <engine/e_client_interface.h>
-#include <engine/client/graphics.h>
+#include <engine/graphics.h>
+#include <engine/textrender.h>
+#include <engine/shared/config.h>
 
-#include <game/generated/g_protocol.hpp>
-#include <game/generated/gc_data.hpp>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
 
-#include <game/client/ui.hpp>
-#include <game/client/render.hpp>
-#include <game/client/gameclient.hpp>
-#include <game/client/animstate.hpp>
-#include <game/localization.hpp>
+#include <game/client/ui.h>
+#include <game/client/render.h>
+#include <game/client/gameclient.h>
+#include <game/client/animstate.h>
+#include <game/localization.h>
 
-#include "binds.hpp"
-#include "menus.hpp"
-#include "skins.hpp"
+#include "binds.h"
+#include "menus.h"
+#include "skins.h"
 
-MENUS_KEYBINDER MENUS::binder;
+CMenusKeyBinder CMenus::m_Binder;
 
-MENUS_KEYBINDER::MENUS_KEYBINDER()
+CMenusKeyBinder::CMenusKeyBinder()
 {
-	take_key = false;
-	got_key = false;
+	m_TakeKey = false;
+	m_GotKey = false;
 }
 
-bool MENUS_KEYBINDER::on_input(INPUT_EVENT e)
+bool CMenusKeyBinder::OnInput(IInput::CEvent Event)
 {
-	if(take_key)
+	if(m_TakeKey)
 	{
-		if(e.flags&INPFLAG_PRESS && e.key != KEY_ESCAPE)
+		if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key != KEY_ESCAPE)
 		{
-			key = e;
-			got_key = true;
-			take_key = false;
+			m_Key = Event;
+			m_GotKey = true;
+			m_TakeKey = false;
 		}
 		return true;
 	}
-	
+
 	return false;
 }
 
-void MENUS::render_settings_player(CUIRect main_view)
+void CMenus::RenderSettingsPlayer(CUIRect MainView)
 {
-	CUIRect button;
-	CUIRect othersection;
-	main_view.VSplitLeft(300.0f, &main_view, &othersection);
-	main_view.HSplitTop(20.0f, &button, &main_view);
+	CUIRect Button;
+	CUIRect LeftView, RightView;
+
+	MainView.VSplitLeft(MainView.w/2, &LeftView, &RightView);
+    LeftView.HSplitTop(20.0f, &Button, &LeftView);
 
 	// render settings
-	{	
-		char buf[128];
-		
-		main_view.HSplitTop(20.0f, &button, &main_view);
-		str_format(buf, sizeof(buf), "%s:", localize("Name"));
-		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;
+	{
+		char aBuf[128];
+
+		LeftView.HSplitTop(20.0f, &Button, &LeftView);
+		str_format(aBuf, sizeof(aBuf), "%s:", Localize("Name"));
+		UI()->DoLabel(&Button, aBuf, 14.0, -1);
+		Button.VSplitLeft(80.0f, 0, &Button);
+		Button.VSplitLeft(180.0f, &Button, 0);
+		if(DoEditBox(g_Config.m_PlayerName, &Button, g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), 14.0f))
+			m_NeedSendinfo = true;
 
 		// extra spacing
-		main_view.HSplitTop(10.0f, 0, &main_view);
+		LeftView.HSplitTop(10.0f, 0, &LeftView);
 
-		static int dynamic_camera_button = 0;
-		main_view.HSplitTop(20.0f, &button, &main_view);
-		if(DoButton_CheckBox(&dynamic_camera_button, localize("Dynamic Camera"), config.cl_mouse_deadzone != 0, &button))
+		static int s_DynamicCameraButton = 0;
+		LeftView.HSplitTop(20.0f, &Button, &LeftView);
+		if(DoButton_CheckBox(&s_DynamicCameraButton, Localize("Dynamic Camera"), g_Config.m_ClMouseDeadzone != 0, &Button))
 		{
-			
-			if(config.cl_mouse_deadzone)
+
+			if(g_Config.m_ClMouseDeadzone)
 			{
-				config.cl_mouse_followfactor = 0;
-				config.cl_mouse_max_distance = 400;
-				config.cl_mouse_deadzone = 0;
+				g_Config.m_ClMouseFollowfactor = 0;
+				g_Config.m_ClMouseMaxDistance = 400;
+				g_Config.m_ClMouseDeadzone = 0;
 			}
 			else
 			{
-				config.cl_mouse_followfactor = 60;
-				config.cl_mouse_max_distance = 1000;
-				config.cl_mouse_deadzone = 300;
+				g_Config.m_ClMouseFollowfactor = 60;
+				g_Config.m_ClMouseMaxDistance = 1000;
+				g_Config.m_ClMouseDeadzone = 300;
 			}
 		}
 
-		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;
-			
-		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;
+		LeftView.HSplitTop(20.0f, &Button, &LeftView);
+		if(DoButton_CheckBox(&g_Config.m_ClAutoswitchWeapons, Localize("Switch weapon on pickup"), g_Config.m_ClAutoswitchWeapons, &Button))
+			g_Config.m_ClAutoswitchWeapons ^= 1;
+
+		LeftView.HSplitTop(20.0f, &Button, &LeftView);
+		if(DoButton_CheckBox(&g_Config.m_ClNameplates, Localize("Show name plates"), g_Config.m_ClNameplates, &Button))
+			g_Config.m_ClNameplates ^= 1;
 
 		//if(config.cl_nameplates)
 		{
-			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;
+			LeftView.HSplitTop(20.0f, &Button, &LeftView);
+			Button.VSplitLeft(15.0f, 0, &Button);
+			if(DoButton_CheckBox(&g_Config.m_ClNameplatesAlways, Localize("Always show name plates"), g_Config.m_ClNameplatesAlways, &Button))
+				g_Config.m_ClNameplatesAlways ^= 1;
 		}
-			
-		main_view.HSplitTop(20.0f, &button, &main_view);
-		
-		main_view.HSplitTop(20.0f, &button, &main_view);
-		if(DoButton_CheckBox(&config.player_color_body, localize("Custom colors"), config.player_use_custom_color, &button))
+
+        {
+            const CSkins::CSkin *pOwnSkin = m_pClient->m_pSkins->Get(max(0, m_pClient->m_pSkins->Find(g_Config.m_PlayerSkin)));
+
+            CTeeRenderInfo OwnSkinInfo;
+            OwnSkinInfo.m_Texture = pOwnSkin->m_OrgTexture;
+            OwnSkinInfo.m_ColorBody = vec4(1, 1, 1, 1);
+            OwnSkinInfo.m_ColorFeet = vec4(1, 1, 1, 1);
+
+            if(g_Config.m_PlayerUseCustomColor)
+            {
+                OwnSkinInfo.m_ColorBody = m_pClient->m_pSkins->GetColor(g_Config.m_PlayerColorBody);
+                OwnSkinInfo.m_ColorFeet = m_pClient->m_pSkins->GetColor(g_Config.m_PlayerColorFeet);
+                OwnSkinInfo.m_Texture = pOwnSkin->m_ColorTexture;
+            }
+
+            OwnSkinInfo.m_Size = UI()->Scale()*50.0f;
+
+            LeftView.HSplitTop(20.0f, &Button, &LeftView);
+            LeftView.HSplitTop(20.0f, &Button, &LeftView);
+
+            str_format(aBuf, sizeof(aBuf), "%s:", Localize("Your skin"));
+            UI()->DoLabel(&Button, aBuf, 14.0, -1);
+
+            CUIRect SkinRect;
+            LeftView.VSplitLeft(LeftView.w/1.2f, &SkinRect, 0);
+            SkinRect.HSplitTop(50.0f, &SkinRect, 0);
+            RenderTools()->DrawUIRect(&SkinRect, vec4(1, 1, 1, 0.25f), CUI::CORNER_ALL, 10.0f);
+
+            Button.VSplitLeft(30.0f, 0, &Button);
+            Button.HSplitTop(50.0f, 0, &Button);
+            RenderTools()->RenderTee(CAnimState::GetIdle(), &OwnSkinInfo, 0, vec2(1, 0), vec2(Button.x, Button.y));
+
+            LeftView.HSplitTop(20.0f, &Button, &LeftView);
+            Button.HSplitTop(15.0f, 0, &Button);
+            Button.VSplitLeft(100.0f, 0, &Button);
+
+            str_format(aBuf, sizeof(aBuf), "%s", g_Config.m_PlayerSkin);
+            UI()->DoLabel(&Button, aBuf, 14.0, -1);
+        }
+
+		RightView.HSplitTop(20.0f, &Button, &RightView);
+		RightView.HSplitTop(20.0f, &Button, &RightView);
+
+		if(DoButton_CheckBox(&g_Config.m_PlayerColorBody, Localize("Custom colors"), g_Config.m_PlayerUseCustomColor, &Button))
 		{
-			config.player_use_custom_color = config.player_use_custom_color?0:1;
-			need_sendinfo = true;
+			g_Config.m_PlayerUseCustomColor = g_Config.m_PlayerUseCustomColor?0:1;
+			m_NeedSendinfo = true;
 		}
-		
-		if(config.player_use_custom_color)
+
+		if(g_Config.m_PlayerUseCustomColor)
 		{
-			int *colors[2];
-			colors[0] = &config.player_color_body;
-			colors[1] = &config.player_color_feet;
-			
-			const char *parts[] = {
-				localize("Body"),
-				localize("Feet")};
-			const char *labels[] = {
-				localize("Hue"),
-				localize("Sat."),
-				localize("Lht.")};
-			static int color_slider[2][3] = {{0}};
+			int *paColors[2];
+			paColors[0] = &g_Config.m_PlayerColorBody;
+			paColors[1] = &g_Config.m_PlayerColorFeet;
+
+			const char *paParts[] = {
+				Localize("Body"),
+				Localize("Feet")};
+			const char *paLabels[] = {
+				Localize("Hue"),
+				Localize("Sat."),
+				Localize("Lht.")};
+			static int s_aColorSlider[2][3] = {{0}};
 			//static float v[2][3] = {{0, 0.5f, 0.25f}, {0, 0.5f, 0.25f}};
-				
+
 			for(int i = 0; i < 2; i++)
 			{
-				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;
+				CUIRect Text;
+				RightView.HSplitTop(20.0f, &Text, &RightView);
+				Text.VSplitLeft(15.0f, 0, &Text);
+				UI()->DoLabel(&Text, paParts[i], 14.0f, -1);
+
+				int PrevColor = *paColors[i];
+				int Color = 0;
 				for(int s = 0; s < 3; s++)
 				{
-					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 = DoScrollbarH(&color_slider[i][s], &button, k);
-					color <<= 8;
-					color += clamp((int)(k*255), 0, 255);
-					UI()->DoLabel(&text, labels[s], 15.0f, -1);
-					 
+					CUIRect Text;
+					RightView.HSplitTop(19.0f, &Button, &RightView);
+					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 = DoScrollbarH(&s_aColorSlider[i][s], &Button, k);
+					Color <<= 8;
+					Color += clamp((int)(k*255), 0, 255);
+					UI()->DoLabel(&Text, paLabels[s], 15.0f, -1);
+
 				}
-		
-				if(*colors[i] != color)
-					need_sendinfo = true;
-					
-				*colors[i] = color;
-				main_view.HSplitTop(5.0f, 0, &main_view);
+
+				if(*paColors[i] != Color)
+					m_NeedSendinfo = true;
+
+				*paColors[i] = Color;
+				RightView.HSplitTop(5.0f, 0, &RightView);
 			}
 		}
-		
+
+        MainView.HSplitTop(MainView.h/2, 0, &MainView);
+
 		// render skinselector
-		static int skinselector_id = 0;		
-		ui_do_listbox_start(&skinselector_id, &main_view, 50, localize("Skins"), (gameclient.skins->num()+3)/4, 0);
+		static const int s_MaxSkins = 256;
+		static const CSkins::CSkin *s_paSkinList[s_MaxSkins];
+		static int s_NumSkins = -1;
+		static float s_ScrollValue = 0;
+		if(s_NumSkins == -1)
+		{
+			mem_zero(s_paSkinList, sizeof(s_paSkinList));
+			s_NumSkins = 0;
+			for(int i = 0; i < m_pClient->m_pSkins->Num() && i < s_MaxSkins; ++i)
+			{
+				const CSkins::CSkin *s = m_pClient->m_pSkins->Get(i);
+				// no special skins
+				if(s->m_aName[0] == 'x' && s->m_aName[1] == '_')
+					continue;
+				s_paSkinList[s_NumSkins++] = s;
+			}
+		}
 
-		for(int skin_id = 0; skin_id < gameclient.skins->num(); )
+		int OldSelected = -1;
+		UiDoListboxStart(&s_NumSkins , &MainView, 50.0f, Localize("Skins"), "", s_NumSkins, 4, OldSelected, s_ScrollValue);
+
+		for(int i = 0; i < s_NumSkins; ++i)
 		{
-			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++)
+			const CSkins::CSkin *s = s_paSkinList[i];
+			if(s == 0)
+				continue;
+
+			if(str_comp(s->m_aName, g_Config.m_PlayerSkin) == 0)
+				OldSelected = i;
+
+			CListboxItem Item = UiDoListboxNextItem(&s_paSkinList[i], OldSelected == i);
+			if(Item.m_Visible)
 			{
-				//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)
+				CTeeRenderInfo Info;
+				Info.m_Texture = s->m_OrgTexture;
+				Info.m_ColorBody = vec4(1, 1, 1, 1);
+				Info.m_ColorFeet = vec4(1, 1, 1, 1);
+
+				if(g_Config.m_PlayerUseCustomColor)
 				{
-					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.m_ColorBody = m_pClient->m_pSkins->GetColor(g_Config.m_PlayerColorBody);
+					Info.m_ColorFeet = m_pClient->m_pSkins->GetColor(g_Config.m_PlayerColorFeet);
+					Info.m_Texture = s->m_ColorTexture;
 				}
-					
-				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)
+
+				Info.m_Size = UI()->Scale()*50.0f;
+				Item.m_Rect.HSplitTop(5.0f, 0, &Item.m_Rect); // some margin from the top
+				RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, 0, vec2(1, 0), vec2(Item.m_Rect.x+Item.m_Rect.w/2, Item.m_Rect.y+Item.m_Rect.h/2));
+
+				if(g_Config.m_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()->SetColor(s->m_BloodColor.r, s->m_BloodColor.g, s->m_BloodColor.b, 1.0f);
+					IGraphics::CQuadItem QuadItem(Item.m_Rect.x, Item.m_Rect.y, 12, 12);
+					Graphics()->QuadsDrawTL(&QuadItem, 1);
 					Graphics()->QuadsEnd();
 				}
 			}
 		}
-		
-		int new_selection = ui_do_listbox_end();
-		(void)new_selection;
-		//main_view
-	}
-	
-	// render skinselector
-	/*
-	{
-		
-		//othersection
-	}
-		
-	// draw header
-	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	
-	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
-	RenderTools()->DrawUIRect(&skinselection, vec4(0,0,0,0.15f), 0, 0);
-
-	CUIRect scroll;
-	skinselection.VSplitRight(15, &skinselection, &scroll);
-
-	CUIRect list = skinselection;
-	list.HSplitTop(50, &button, &list);
-	
-	int num = (int)(skinselection.h/button.h);
-	static float scrollvalue = 0;
-	static int scrollbar = 0;
-	scroll.HMargin(5.0f, &scroll);
-	scrollvalue = ui_do_scrollbar_v(&scrollbar, &scroll, scrollvalue);
-
-	int start = (int)((gameclient.skins->num()-num)*scrollvalue);
-	if(start < 0)
-		start = 0;
-		
-	for(int i = start; i < start+num && i < gameclient.skins->num(); i++)
-	{
-		const SKINS::SKIN *s = gameclient.skins->get(i);
-		
-		// no special skins
-		if(s->name[0] == 'x' && s->name[1] == '_')
-		{
-			num++;
-			continue;
-		}
-		
-		char buf[128];
-		str_format(buf, sizeof(buf), "%s", s->name);
-		int selected = 0;
-		if(strcmp(s->name, config.player_skin) == 0)
-			selected = 1;
-		
-		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;
-		CUIRect text;
-		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)
+		const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0);
+		if(OldSelected != NewSelected)
 		{
-			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();
+			mem_copy(g_Config.m_PlayerSkin, s_paSkinList[NewSelected]->m_aName, sizeof(g_Config.m_PlayerSkin));
+			m_NeedSendinfo = true;
 		}
-		
-		list.HSplitTop(50, &button, &list);
-	}*/
+	}
 }
 
-typedef void (*assign_func_callback)(CONFIGURATION *config, int value);
+typedef void (*pfnAssignFuncCallback)(CConfiguration *pConfig, int Value);
 
-typedef struct 
+typedef struct
 {
-	LOC_CONSTSTRING name;
-	const char *command;
-	int keyid;
-} KEYINFO;
+	CLocConstString m_Name;
+	const char *m_pCommand;
+	int m_KeyId;
+} CKeyInfo;
 
-static KEYINFO keys[] = 
+static CKeyInfo gs_aKeys[] =
 {
 	// we need to do localize so the scripts can pickup the string
-	{ localize("Move left"), "+left", 0},
-	{ localize("Move right"), "+right", 0 },
-	{ localize("Jump"), "+jump", 0 },
-	{ localize("Fire"), "+fire", 0 },
-	{ localize("Hook"), "+hook", 0 },
-	{ localize("Hammer"), "+weapon1", 0 },
-	{ localize("Pistol"), "+weapon2", 0 },
-	{ localize("Shotgun"), "+weapon3", 0 },
-	{ localize("Grenade"), "+weapon4", 0 },
-	{ localize("Rifle"), "+weapon5", 0 },
-	{ localize("Next weapon"), "+nextweapon", 0 },
-	{ localize("Prev. weapon"), "+prevweapon", 0 },
-	{ localize("Vote yes"), "vote yes", 0 },
-	{ localize("Vote no"), "vote no", 0 },
-	{ localize("Chat"), "chat all", 0 },
-	{ localize("Team chat"), "chat team", 0 },
-	{ localize("Emoticon"), "+emote", 0 },
-	{ localize("Console"), "toggle_local_console", 0 },
-	{ localize("Remote console"), "toggle_remote_console", 0 },
-	{ localize("Screenshot"), "screenshot", 0 },
-	{ localize("Scoreboard"), "+scoreboard", 0 },
+	{ Localize("Move left"), "+left", 0},
+	{ Localize("Move right"), "+right", 0 },
+	{ Localize("Jump"), "+jump", 0 },
+	{ Localize("Fire"), "+fire", 0 },
+	{ Localize("Hook"), "+hook", 0 },
+	{ Localize("Hammer"), "+weapon1", 0 },
+	{ Localize("Pistol"), "+weapon2", 0 },
+	{ Localize("Shotgun"), "+weapon3", 0 },
+	{ Localize("Grenade"), "+weapon4", 0 },
+	{ Localize("Rifle"), "+weapon5", 0 },
+	{ Localize("Next weapon"), "+nextweapon", 0 },
+	{ Localize("Prev. weapon"), "+prevweapon", 0 },
+	{ Localize("Vote yes"), "vote yes", 0 },
+	{ Localize("Vote no"), "vote no", 0 },
+	{ Localize("Chat"), "chat all", 0 },
+	{ Localize("Team chat"), "chat team", 0 },
+	{ Localize("Emoticon"), "+emote", 0 },
+	{ Localize("Console"), "toggle_local_console", 0 },
+	{ Localize("Remote console"), "toggle_remote_console", 0 },
+	{ Localize("Screenshot"), "screenshot", 0 },
+	{ Localize("Scoreboard"), "+scoreboard", 0 },
 };
 
-const int key_count = sizeof(keys) / sizeof(KEYINFO);
+const int g_KeyCount = sizeof(gs_aKeys) / sizeof(CKeyInfo);
 
-void MENUS::ui_do_getbuttons(int start, int stop, CUIRect view)
+void CMenus::UiDoGetButtons(int Start, int Stop, CUIRect View)
 {
-	for (int i = start; i < stop; i++)
+	for (int i = Start; i < Stop; i++)
 	{
-		KEYINFO &key = keys[i];
-		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()->DoLabel(&label, key.name, 14.0f, -1);
-		int oldid = key.keyid;
-		int newid = DoKeyReader((void *)&keys[i].name, &button, oldid);
-		if(newid != oldid)
+		CKeyInfo &Key = gs_aKeys[i];
+		CUIRect Button, Label;
+		View.HSplitTop(20.0f, &Button, &View);
+		Button.VSplitLeft(130.0f, &Label, &Button);
+
+		char aBuf[64];
+		str_format(aBuf, sizeof(aBuf), "%s:", (const char *)Key.m_Name);
+
+		UI()->DoLabel(&Label, aBuf, 14.0f, -1);
+		int OldId = Key.m_KeyId;
+		int NewId = DoKeyReader((void *)&gs_aKeys[i].m_Name, &Button, OldId);
+		if(NewId != OldId)
 		{
-			gameclient.binds->bind(oldid, "");
-			gameclient.binds->bind(newid, keys[i].command);
+			m_pClient->m_pBinds->Bind(OldId, "");
+			m_pClient->m_pBinds->Bind(NewId, gs_aKeys[i].m_pCommand);
 		}
-		view.HSplitTop(5.0f, 0, &view);
+		View.HSplitTop(5.0f, 0, &View);
 	}
 }
 
-void MENUS::render_settings_controls(CUIRect main_view)
+void CMenus::RenderSettingsControls(CUIRect MainView)
 {
 	// this is kinda slow, but whatever
-	for(int i = 0; i < key_count; i++)
-		keys[i].keyid = 0;
-	
-	for(int keyid = 0; keyid < KEY_LAST; keyid++)
+	for(int i = 0; i < g_KeyCount; i++)
+		gs_aKeys[i].m_KeyId = 0;
+
+	for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
 	{
-		const char *bind = gameclient.binds->get(keyid);
-		if(!bind[0])
+		const char *pBind = m_pClient->m_pBinds->Get(KeyId);
+		if(!pBind[0])
 			continue;
-		
-		for(int i = 0; i < key_count; i++)
-			if(strcmp(bind, keys[i].command) == 0)
+
+		for(int i = 0; i < g_KeyCount; i++)
+			if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
 			{
-				keys[i].keyid = keyid;
+				gs_aKeys[i].m_KeyId = KeyId;
 				break;
 			}
 	}
 
-	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 */
+	CUIRect MovementSettings, WeaponSettings, VotingSettings, ChatSettings, MiscSettings, ResetButton;
+	MainView.VSplitLeft(MainView.w/2-5.0f, &MovementSettings, &VotingSettings);
+
+	// 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);
-		
-		movement_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &movement_settings);
-		
+		MovementSettings.HSplitTop(MainView.h/2-5.0f, &MovementSettings, &WeaponSettings);
+		RenderTools()->DrawUIRect(&MovementSettings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+		MovementSettings.Margin(10.0f, &MovementSettings);
+
+		TextRender()->Text(0, MovementSettings.x, MovementSettings.y, 14, Localize("Movement"), -1);
+
+		MovementSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &MovementSettings);
+
 		{
-			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);
-			movement_settings.HSplitTop(20.0f, 0, &movement_settings);
+			CUIRect Button, Label;
+			MovementSettings.HSplitTop(20.0f, &Button, &MovementSettings);
+			Button.VSplitLeft(130.0f, &Label, &Button);
+			UI()->DoLabel(&Label, Localize("Mouse sens."), 14.0f, -1);
+			Button.HMargin(2.0f, &Button);
+			g_Config.m_InpMousesens = (int)(DoScrollbarH(&g_Config.m_InpMousesens, &Button, (g_Config.m_InpMousesens-5)/500.0f)*500.0f)+5;
+			//*key.key = ui_do_key_reader(key.key, &Button, *key.key);
+			MovementSettings.HSplitTop(20.0f, 0, &MovementSettings);
 		}
-		
-		ui_do_getbuttons(0, 5, movement_settings);
+
+		UiDoGetButtons(0, 5, MovementSettings);
 
 	}
-	
-	/* weapon settings */
+
+	// 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);
-		
-		weapon_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &weapon_settings);
-		ui_do_getbuttons(5, 12, weapon_settings);
+		WeaponSettings.HSplitTop(10.0f, 0, &WeaponSettings);
+		RenderTools()->DrawUIRect(&WeaponSettings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+		WeaponSettings.Margin(10.0f, &WeaponSettings);
+
+		TextRender()->Text(0, WeaponSettings.x, WeaponSettings.y, 14, Localize("Weapon"), -1);
+
+		WeaponSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &WeaponSettings);
+		UiDoGetButtons(5, 12, WeaponSettings);
 	}
-	
-	/* voting settings */
+
+	// 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);
-		
-		voting_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &voting_settings);
-		ui_do_getbuttons(12, 14, voting_settings);
+		VotingSettings.VSplitLeft(10.0f, 0, &VotingSettings);
+		VotingSettings.HSplitTop(MainView.h/4-5.0f, &VotingSettings, &ChatSettings);
+		RenderTools()->DrawUIRect(&VotingSettings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+		VotingSettings.Margin(10.0f, &VotingSettings);
+
+		TextRender()->Text(0, VotingSettings.x, VotingSettings.y, 14, Localize("Voting"), -1);
+
+		VotingSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &VotingSettings);
+		UiDoGetButtons(12, 14, VotingSettings);
 	}
-	
-	/* chat settings */
+
+	// 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);
-		
-		chat_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &chat_settings);
-		ui_do_getbuttons(14, 16, chat_settings);
+		ChatSettings.HSplitTop(10.0f, 0, &ChatSettings);
+		ChatSettings.HSplitTop(MainView.h/4-10.0f, &ChatSettings, &MiscSettings);
+		RenderTools()->DrawUIRect(&ChatSettings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+		ChatSettings.Margin(10.0f, &ChatSettings);
+
+		TextRender()->Text(0, ChatSettings.x, ChatSettings.y, 14, Localize("Chat"), -1);
+
+		ChatSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &ChatSettings);
+		UiDoGetButtons(14, 16, ChatSettings);
 	}
-	
-	/* misc settings */
+
+	// 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);
-		
-		misc_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &misc_settings);
-		ui_do_getbuttons(16, 21, misc_settings);
+		MiscSettings.HSplitTop(10.0f, 0, &MiscSettings);
+		MiscSettings.HSplitTop(MainView.h/2-5.0f-45.0f, &MiscSettings, &ResetButton);
+		RenderTools()->DrawUIRect(&MiscSettings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f);
+		MiscSettings.Margin(10.0f, &MiscSettings);
+
+		TextRender()->Text(0, MiscSettings.x, MiscSettings.y, 14, Localize("Miscellaneous"), -1);
+
+		MiscSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &MiscSettings);
+		UiDoGetButtons(16, 21, MiscSettings);
 	}
-	
+
 	// defaults
-	reset_button.HSplitTop(10.0f, 0, &reset_button);
-	static int default_button = 0;
-	if(DoButton_Menu((void*)&default_button, localize("Reset to defaults"), 0, &reset_button))
-		gameclient.binds->set_defaults();
+	ResetButton.HSplitTop(10.0f, 0, &ResetButton);
+	static int s_DefaultButton = 0;
+	if(DoButton_Menu((void*)&s_DefaultButton, Localize("Reset to defaults"), 0, &ResetButton))
+		m_pClient->m_pBinds->SetDefaults();
 }
 
-void MENUS::render_settings_graphics(CUIRect main_view)
+void CMenus::RenderSettingsGraphics(CUIRect MainView)
 {
-	CUIRect button;
-	char buf[128];
-	
+	CUIRect Button;
+	char aBuf[128];
+
 	static const int MAX_RESOLUTIONS = 256;
-	static VIDEO_MODE modes[MAX_RESOLUTIONS];
-	static int num_modes = -1;
-	
-	if(num_modes == -1)
-		num_modes = gfx_get_video_modes(modes, MAX_RESOLUTIONS);
-	
-	CUIRect modelist;
-	main_view.VSplitLeft(300.0f, &main_view, &modelist);
-	
+	static CVideoMode s_aModes[MAX_RESOLUTIONS];
+	static int s_NumNodes = -1;
+	const static int s_GfxScreenWidth = g_Config.m_GfxScreenWidth;
+	const static int s_GfxScreenHeight = g_Config.m_GfxScreenHeight;
+	const static int s_GfxColorDepth = g_Config.m_GfxColorDepth;
+
+	if(s_NumNodes == -1)
+		s_NumNodes = Graphics()->GetVideoModes(s_aModes, MAX_RESOLUTIONS);
+
+	CUIRect ModeList;
+	MainView.VSplitLeft(300.0f, &MainView, &ModeList);
+
 	// draw allmodes switch
-	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))
+	ModeList.HSplitTop(20, &Button, &ModeList);
+	if(DoButton_CheckBox(&g_Config.m_GfxDisplayAllModes, Localize("Show only supported"), g_Config.m_GfxDisplayAllModes^1, &Button))
 	{
-		config.gfx_display_all_modes ^= 1;
-		num_modes = gfx_get_video_modes(modes, MAX_RESOLUTIONS);
+		g_Config.m_GfxDisplayAllModes ^= 1;
+		s_NumNodes = Graphics()->GetVideoModes(s_aModes, MAX_RESOLUTIONS);
 	}
-	
-	// draw header
-	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	
-	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);
-	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
-	RenderTools()->DrawUIRect(&modelist, vec4(0,0,0,0.15f), 0, 0);
-
-	CUIRect scroll;
-	modelist.VSplitRight(15, &modelist, &scroll);
-
-	CUIRect list = modelist;
-	list.HSplitTop(20, &button, &list);
-	
-	int num = (int)(modelist.h/button.h);
-	static float scrollvalue = 0;
-	static int scrollbar = 0;
-	scroll.HMargin(5.0f, &scroll);
-	scrollvalue = DoScrollbarV(&scrollbar, &scroll, scrollvalue);
-
-	int start = (int)((num_modes-num)*scrollvalue);
-	if(start < 0)
-		start = 0;
-		
-	for(int i = start; i < start+num && i < num_modes; i++)
+
+	// display mode list
+	static float s_ScrollValue = 0;
+	int OldSelected = -1;
+	str_format(aBuf, sizeof(aBuf), "%s: %dx%d %d bit", Localize("Current"), s_GfxScreenWidth, s_GfxScreenHeight, s_GfxColorDepth);
+	UiDoListboxStart(&s_NumNodes , &ModeList, 24.0f, Localize("Display Modes"), aBuf, s_NumNodes, 1, OldSelected, s_ScrollValue);
+
+	for(int i = 0; i < s_NumNodes; ++i)
 	{
-		int depth = modes[i].red+modes[i].green+modes[i].blue;
-		if(depth < 16)
-			depth = 16;
-		else if(depth > 16)
-			depth = 24;
-			
-		int selected = 0;
-		if(config.gfx_color_depth == depth &&
-			config.gfx_screen_width == modes[i].width &&
-			config.gfx_screen_height == modes[i].height)
+		const int Depth = s_aModes[i].m_Red+s_aModes[i].m_Green+s_aModes[i].m_Blue > 16 ? 24 : 16;
+		if(g_Config.m_GfxColorDepth == Depth &&
+			g_Config.m_GfxScreenWidth == s_aModes[i].m_Width &&
+			g_Config.m_GfxScreenHeight == s_aModes[i].m_Height)
 		{
-			selected = 1;
+			OldSelected = i;
 		}
-		
-		str_format(buf, sizeof(buf), "  %dx%d %d bit", modes[i].width, modes[i].height, depth);
-		if(DoButton_ListRow(&modes[i], buf, selected, &button))
+
+		CListboxItem Item = UiDoListboxNextItem(&s_aModes[i], OldSelected == i);
+		if(Item.m_Visible)
 		{
-			config.gfx_color_depth = depth;
-			config.gfx_screen_width = modes[i].width;
-			config.gfx_screen_height = modes[i].height;
-			if(!selected)
-				need_restart = true;
+			str_format(aBuf, sizeof(aBuf), "  %dx%d %d bit", s_aModes[i].m_Width, s_aModes[i].m_Height, Depth);
+			UI()->DoLabel(&Item.m_Rect, aBuf, 16.0f, -1);
 		}
-		
-		list.HSplitTop(20, &button, &list);
 	}
-	
-	
+
+	const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0);
+	if(OldSelected != NewSelected)
+	{
+		const int Depth = s_aModes[NewSelected].m_Red+s_aModes[NewSelected].m_Green+s_aModes[NewSelected].m_Blue > 16 ? 24 : 16;
+		g_Config.m_GfxColorDepth = Depth;
+		g_Config.m_GfxScreenWidth = s_aModes[NewSelected].m_Width;
+		g_Config.m_GfxScreenHeight = s_aModes[NewSelected].m_Height;
+		m_NeedRestart = true;
+	}
+
 	// switches
-	main_view.HSplitTop(20.0f, &button, &main_view);
-	if(DoButton_CheckBox(&config.gfx_fullscreen, localize("Fullscreen"), config.gfx_fullscreen, &button))
+	MainView.HSplitTop(20.0f, &Button, &MainView);
+	if(DoButton_CheckBox(&g_Config.m_GfxFullscreen, Localize("Fullscreen"), g_Config.m_GfxFullscreen, &Button))
 	{
-		config.gfx_fullscreen ^= 1;
-		need_restart = true;
+		g_Config.m_GfxFullscreen ^= 1;
+		m_NeedRestart = true;
 	}
 
-	main_view.HSplitTop(20.0f, &button, &main_view);
-	if(DoButton_CheckBox(&config.gfx_vsync, localize("V-Sync"), config.gfx_vsync, &button))
+	MainView.HSplitTop(20.0f, &Button, &MainView);
+	if(DoButton_CheckBox(&g_Config.m_GfxVsync, Localize("V-Sync"), g_Config.m_GfxVsync, &Button))
 	{
-		config.gfx_vsync ^= 1;
-		need_restart = true;
+		g_Config.m_GfxVsync ^= 1;
+		m_NeedRestart = true;
 	}
 
-	main_view.HSplitTop(20.0f, &button, &main_view);
-	if(DoButton_CheckBox_Number(&config.gfx_fsaa_samples, localize("FSAA samples"), config.gfx_fsaa_samples, &button))
+	MainView.HSplitTop(20.0f, &Button, &MainView);
+	if(DoButton_CheckBox_Number(&g_Config.m_GfxFsaaSamples, Localize("FSAA samples"), g_Config.m_GfxFsaaSamples, &Button))
 	{
-		config.gfx_fsaa_samples = (config.gfx_fsaa_samples+1)%17;
-		need_restart = true;
+		g_Config.m_GfxFsaaSamples = (g_Config.m_GfxFsaaSamples+1)%17;
+		m_NeedRestart = true;
 	}
-		
-	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))
+
+	MainView.HSplitTop(40.0f, &Button, &MainView);
+	MainView.HSplitTop(20.0f, &Button, &MainView);
+	if(DoButton_CheckBox(&g_Config.m_GfxTextureQuality, Localize("Quality Textures"), g_Config.m_GfxTextureQuality, &Button))
 	{
-		config.gfx_texture_quality ^= 1;
-		need_restart = true;
+		g_Config.m_GfxTextureQuality ^= 1;
+		m_NeedRestart = true;
 	}
 
-	main_view.HSplitTop(20.0f, &button, &main_view);
-	if(DoButton_CheckBox(&config.gfx_texture_compression, localize("Texture Compression"), config.gfx_texture_compression, &button))
+	MainView.HSplitTop(20.0f, &Button, &MainView);
+	if(DoButton_CheckBox(&g_Config.m_GfxTextureCompression, Localize("Texture Compression"), g_Config.m_GfxTextureCompression, &Button))
 	{
-		config.gfx_texture_compression ^= 1;
-		need_restart = true;
+		g_Config.m_GfxTextureCompression ^= 1;
+		m_NeedRestart = true;
 	}
 
-	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;
+	MainView.HSplitTop(20.0f, &Button, &MainView);
+	if(DoButton_CheckBox(&g_Config.m_GfxHighDetail, Localize("High Detail"), g_Config.m_GfxHighDetail, &Button))
+		g_Config.m_GfxHighDetail ^= 1;
 
 	//
-	
-	CUIRect text;
-	main_view.HSplitTop(20.0f, 0, &main_view);
-	main_view.HSplitTop(20.0f, &text, &main_view);
+
+	CUIRect Text;
+	MainView.HSplitTop(20.0f, 0, &MainView);
+	MainView.HSplitTop(20.0f, &Text, &MainView);
 	//text.VSplitLeft(15.0f, 0, &text);
-	UI()->DoLabel(&text, localize("UI Color"), 14.0f, -1);
-	
-	const char *labels[] = {
-		localize("Hue"),
-		localize("Sat."),
-		localize("Lht."),
-		localize("Alpha")};
-	int *color_slider[4] = {&config.ui_color_hue, &config.ui_color_sat, &config.ui_color_lht, &config.ui_color_alpha};
+	UI()->DoLabel(&Text, Localize("UI Color"), 14.0f, -1);
+
+	const char *paLabels[] = {
+		Localize("Hue"),
+		Localize("Sat."),
+		Localize("Lht."),
+		Localize("Alpha")};
+	int *pColorSlider[4] = {&g_Config.m_UiColorHue, &g_Config.m_UiColorSat, &g_Config.m_UiColorLht, &g_Config.m_UiColorAlpha};
 	for(int s = 0; s < 4; s++)
 	{
-		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 = DoScrollbarH(color_slider[s], &button, k);
-		*color_slider[s] = (int)(k*255.0f);
-		UI()->DoLabel(&text, labels[s], 15.0f, -1);
-	}		
+		CUIRect Text;
+		MainView.HSplitTop(19.0f, &Button, &MainView);
+		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 = (*pColorSlider[s]) / 255.0f;
+		k = DoScrollbarH(pColorSlider[s], &Button, k);
+		*pColorSlider[s] = (int)(k*255.0f);
+		UI()->DoLabel(&Text, paLabels[s], 15.0f, -1);
+	}
 }
 
-void MENUS::render_settings_sound(CUIRect main_view)
+void CMenus::RenderSettingsSound(CUIRect MainView)
 {
-	CUIRect button;
-	main_view.VSplitLeft(300.0f, &main_view, 0);
-	
-	main_view.HSplitTop(20.0f, &button, &main_view);
-	if(DoButton_CheckBox(&config.snd_enable, localize("Use sounds"), config.snd_enable, &button))
+	CUIRect Button;
+	MainView.VSplitLeft(300.0f, &MainView, 0);
+
+	MainView.HSplitTop(20.0f, &Button, &MainView);
+	if(DoButton_CheckBox(&g_Config.m_SndEnable, Localize("Use sounds"), g_Config.m_SndEnable, &Button))
 	{
-		config.snd_enable ^= 1;
-		need_restart = true;
+		g_Config.m_SndEnable ^= 1;
+		m_NeedRestart = true;
 	}
-	
-	if(!config.snd_enable)
+
+	if(!g_Config.m_SndEnable)
 		return;
-	
-	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;
-		
+
+	MainView.HSplitTop(20.0f, &Button, &MainView);
+	if(DoButton_CheckBox(&g_Config.m_SndNonactiveMute, Localize("Mute when not active"), g_Config.m_SndNonactiveMute, &Button))
+		g_Config.m_SndNonactiveMute ^= 1;
+
 	// sample rate box
 	{
-		char buf[64];
-		str_format(buf, sizeof(buf), "%d", config.snd_rate);
-		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);
-		
-		if(config.snd_rate != before)
-			need_restart = true;
-
-		if(config.snd_rate < 1)
-			config.snd_rate = 1;
+		char aBuf[64];
+		str_format(aBuf, sizeof(aBuf), "%d", g_Config.m_SndRate);
+		MainView.HSplitTop(20.0f, &Button, &MainView);
+		UI()->DoLabel(&Button, Localize("Sample rate"), 14.0f, -1);
+		Button.VSplitLeft(110.0f, 0, &Button);
+		Button.VSplitLeft(180.0f, &Button, 0);
+		DoEditBox(&g_Config.m_SndRate, &Button, aBuf, sizeof(aBuf), 14.0f);
+		int Before = g_Config.m_SndRate;
+		g_Config.m_SndRate = str_toint(aBuf);
+
+		if(g_Config.m_SndRate != Before)
+			m_NeedRestart = true;
+
+		if(g_Config.m_SndRate < 1)
+			g_Config.m_SndRate = 1;
 	}
-	
+
 	// volume slider
 	{
-		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);
+		CUIRect Button, Label;
+		MainView.HSplitTop(5.0f, &Button, &MainView);
+		MainView.HSplitTop(20.0f, &Button, &MainView);
+		Button.VSplitLeft(110.0f, &Label, &Button);
+		Button.HMargin(2.0f, &Button);
+		UI()->DoLabel(&Label, Localize("Sound volume"), 14.0f, -1);
+		g_Config.m_SndVolume = (int)(DoScrollbarH(&g_Config.m_SndVolume, &Button, g_Config.m_SndVolume/100.0f)*100.0f);
+		MainView.HSplitTop(20.0f, 0, &MainView);
 	}
 }
 
 struct LANGUAGE
 {
 	LANGUAGE() {}
-	LANGUAGE(const char *n, const char *f) : name(n), filename(f) {}
-	
-	string name;
-	string filename;
-	
-	bool operator<(const LANGUAGE &other) { return name < other.name; }
+	LANGUAGE(const char *n, const char *f) : m_Name(n), m_FileName(f) {}
+
+	string m_Name;
+	string m_FileName;
+
+	bool operator<(const LANGUAGE &Other) { return m_Name < Other.m_Name; }
 };
 
 
-int fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, void *user);
+int fs_listdir(const char *pDir, FS_LISTDIR_CALLBACK cb, void *pUser);
 
-void gather_languages(const char *name, int is_dir, void *user)
+void GatherLanguages(const char *pName, int IsDir, void *pUser)
 {
-	if(is_dir || name[0] == '.')
+	if(IsDir || pName[0] == '.')
 		return;
-		
-	sorted_array<LANGUAGE> &languages = *((sorted_array<LANGUAGE> *)user);
-	char filename[128];
-	str_format(filename, sizeof(filename), "data/languages/%s", name);
-
-	char nicename[128];
-	str_format(nicename, sizeof(nicename), "%s", name);
-	nicename[0] = str_uppercase(nicename[0]);
-	
-	
-	for(char *p = nicename; *p; p++)
+
+	sorted_array<LANGUAGE> &Languages = *((sorted_array<LANGUAGE> *)pUser);
+	char aFileName[128];
+	str_format(aFileName, sizeof(aFileName), "data/languages/%s", pName);
+
+	char NiceName[128];
+	str_format(NiceName, sizeof(NiceName), "%s", pName);
+	NiceName[0] = str_uppercase(NiceName[0]);
+
+
+	for(char *p = NiceName; *p; p++)
 		if(*p == '.')
 			*p = 0;
-	
-	languages.add(LANGUAGE(nicename, filename));
+
+	Languages.add(LANGUAGE(NiceName, aFileName));
 }
 
-void MENUS::render_settings_general(CUIRect main_view)
+void CMenus::RenderSettingsGeneral(CUIRect MainView)
 {
-	static int lanuagelist = 0;
-	static int selected_language = 0;
-	static sorted_array<LANGUAGE> languages;
-	
-	if(languages.size() == 0)
+	static int s_LanguageList  = 0;
+	static int s_SelectedLanguage = 0;
+	static sorted_array<LANGUAGE> s_Languages;
+	static float s_ScrollValue = 0;
+
+	if(s_Languages.size() == 0)
 	{
-		languages.add(LANGUAGE("English", ""));
-		fs_listdir("data/languages", gather_languages, &languages);
-		for(int i = 0; i < languages.size(); i++)
-			if(str_comp(languages[i].filename, config.cl_languagefile) == 0)
+		s_Languages.add(LANGUAGE("English", ""));
+		fs_listdir("data/languages", GatherLanguages, &s_Languages);
+		for(int i = 0; i < s_Languages.size(); i++)
+			if(str_comp(s_Languages[i].m_FileName, g_Config.m_ClLanguagefile) == 0)
 			{
-				selected_language = i;
+				s_SelectedLanguage = i;
 				break;
 			}
 	}
-	
-	int old_selected = selected_language;
-	
-	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())
+
+	int OldSelected = s_SelectedLanguage;
+
+	CUIRect List = MainView;
+	UiDoListboxStart(&s_LanguageList , &List, 24.0f, Localize("Language"), "", s_Languages.size(), 1, s_SelectedLanguage, s_ScrollValue);
+
+	for(sorted_array<LANGUAGE>::range r = s_Languages.all(); !r.empty(); r.pop_front())
 	{
-		LISTBOXITEM item = ui_do_listbox_nextitem(&r.front());
-		
-		if(item.visible)
-			UI()->DoLabel(&item.rect, r.front().name, 16.0f, -1);
+		CListboxItem Item = UiDoListboxNextItem(&r.front());
+
+		if(Item.m_Visible)
+			UI()->DoLabel(&Item.m_Rect, r.front().m_Name, 16.0f, -1);
 	}
-	
-	selected_language = ui_do_listbox_end();
-	
-	if(old_selected != selected_language)
+
+	s_SelectedLanguage = UiDoListboxEnd(&s_ScrollValue, 0);
+
+	if(OldSelected != s_SelectedLanguage)
 	{
-		str_copy(config.cl_languagefile, languages[selected_language].filename, sizeof(config.cl_languagefile));
-		localization.load(languages[selected_language].filename);
+		str_copy(g_Config.m_ClLanguagefile, s_Languages[s_SelectedLanguage].m_FileName, sizeof(g_Config.m_ClLanguagefile));
+		g_Localization.Load(s_Languages[s_SelectedLanguage].m_FileName);
 	}
 }
 
-void MENUS::render_settings(CUIRect main_view)
+void CMenus::RenderSettings(CUIRect MainView)
 {
-	static int settings_page = 0;
-	
+	static int s_SettingsPage = 0;
+
 	// render background
-	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);
-	
-	main_view.HSplitTop(10.0f, 0, &main_view);
-	
-	CUIRect button;
-	
-	const char *tabs[] = {
-		localize("General"),
-		localize("Player"),
-		localize("Controls"),
-		localize("Graphics"),
-		localize("Sound")};
-		
-	int num_tabs = (int)(sizeof(tabs)/sizeof(*tabs));
-
-	for(int i = 0; i < num_tabs; i++)
+	CUIRect Temp, TabBar;
+	MainView.VSplitRight(120.0f, &MainView, &TabBar);
+	RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B|CUI::CORNER_TL, 10.0f);
+	TabBar.HSplitTop(50.0f, &Temp, &TabBar);
+	RenderTools()->DrawUIRect(&Temp, ms_ColorTabbarActive, CUI::CORNER_R, 10.0f);
+
+	MainView.HSplitTop(10.0f, 0, &MainView);
+
+	CUIRect Button;
+
+	const char *aTabs[] = {
+		Localize("General"),
+		Localize("Player"),
+		Localize("Controls"),
+		Localize("Graphics"),
+		Localize("Sound")};
+
+	int NumTabs = (int)(sizeof(aTabs)/sizeof(*aTabs));
+
+	for(int i = 0; i < NumTabs; i++)
 	{
-		tabbar.HSplitTop(10, &button, &tabbar);
-		tabbar.HSplitTop(26, &button, &tabbar);
-		if(DoButton_SettingsTab(tabs[i], tabs[i], settings_page == i, &button))
-			settings_page = i;
+		TabBar.HSplitTop(10, &Button, &TabBar);
+		TabBar.HSplitTop(26, &Button, &TabBar);
+		if(DoButton_SettingsTab(aTabs[i], aTabs[i], s_SettingsPage == i, &Button))
+			s_SettingsPage = i;
 	}
-	
-	main_view.Margin(10.0f, &main_view);
-	
-	if(settings_page == 0)
-		render_settings_general(main_view);
-	else if(settings_page == 1)
-		render_settings_player(main_view);
-	else if(settings_page == 2)
-		render_settings_controls(main_view);
-	else if(settings_page == 3)
-		render_settings_graphics(main_view);
-	else if(settings_page == 4)
-		render_settings_sound(main_view);
-
-	if(need_restart)
+
+	MainView.Margin(10.0f, &MainView);
+
+	if(s_SettingsPage == 0)
+		RenderSettingsGeneral(MainView);
+	else if(s_SettingsPage == 1)
+		RenderSettingsPlayer(MainView);
+	else if(s_SettingsPage == 2)
+		RenderSettingsControls(MainView);
+	else if(s_SettingsPage == 3)
+		RenderSettingsGraphics(MainView);
+	else if(s_SettingsPage == 4)
+		RenderSettingsSound(MainView);
+
+	if(m_NeedRestart)
 	{
-		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);
+		CUIRect RestartWarning;
+		MainView.HSplitBottom(40, &MainView, &RestartWarning);
+		UI()->DoLabel(&RestartWarning, 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 ba85f7f8..5905d52e 100644
--- a/src/game/client/components/motd.cpp
+++ b/src/game/client/components/motd.cpp
@@ -1,87 +1,91 @@
-#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>
+#include <engine/shared/config.h>
+#include <engine/graphics.h>
+#include <engine/textrender.h>
+#include <engine/keys.h>
 
-#include <game/client/gameclient.hpp>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
+#include <game/client/gameclient.h>
 
-#include "motd.hpp"
+#include "motd.h"
 
-void MOTD::clear()
+void CMotd::Clear()
 {
-	server_motd_time = 0;
+	m_ServerMotdTime = 0;
 }
 
-bool MOTD::is_active()
+bool CMotd::IsActive()
 {
-	return time_get() < server_motd_time;	
+	return time_get() < m_ServerMotdTime;	
 }
 
-void MOTD::on_statechange(int new_state, int old_state)
+void CMotd::OnStateChange(int NewState, int OldState)
 {
-	if(old_state == CLIENTSTATE_ONLINE || old_state == CLIENTSTATE_OFFLINE)
-		clear();
+	if(OldState == IClient::STATE_ONLINE || OldState == IClient::STATE_OFFLINE)
+		Clear();
 }
 
-void MOTD::on_render()
+void CMotd::OnRender()
 {
-	if(!is_active())
+	if(!IsActive())
 		return;
 		
-	float width = 400*3.0f*Graphics()->ScreenAspect();
-	float height = 400*3.0f;
+	float Width = 400*3.0f*Graphics()->ScreenAspect();
+	float Height = 400*3.0f;
 
-	Graphics()->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 x = Width/2 - w/2;
 	float y = 150.0f;
 
 	Graphics()->BlendNormal();
 	Graphics()->TextureSet(-1);
 	Graphics()->QuadsBegin();
 	Graphics()->SetColor(0,0,0,0.5f);
-	RenderTools()->draw_round_rect(x, y, w, h, 40.0f);
+	RenderTools()->DrawRoundRect(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));
+	TextRender()->Text(0, x+40.0f, y+40.0f, 32.0f, m_aServerMotd, (int)(w-80.0f));
 }
 
-void MOTD::on_message(int msgtype, void *rawmsg)
+void CMotd::OnMessage(int MsgType, void *pRawMsg)
 {
-	if(msgtype == NETMSGTYPE_SV_MOTD)
+	if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
+		return;
+
+	if(MsgType == NETMSGTYPE_SV_MOTD)
 	{
-		NETMSG_SV_MOTD *msg = (NETMSG_SV_MOTD *)rawmsg;
+		CNetMsg_Sv_Motd *pMsg = (CNetMsg_Sv_Motd *)pRawMsg;
 
 		// process escaping			
-		str_copy(server_motd, msg->message, sizeof(server_motd));
-		for(int i = 0; server_motd[i]; i++)
+		str_copy(m_aServerMotd, pMsg->m_pMessage, sizeof(m_aServerMotd));
+		for(int i = 0; m_aServerMotd[i]; i++)
 		{
-			if(server_motd[i] == '\\')
+			if(m_aServerMotd[i] == '\\')
 			{
-				if(server_motd[i+1] == 'n')
+				if(m_aServerMotd[i+1] == 'n')
 				{
-					server_motd[i] = ' ';
-					server_motd[i+1] = '\n';
+					m_aServerMotd[i] = ' ';
+					m_aServerMotd[i+1] = '\n';
 					i++;
 				}
 			}
 		}
 
-		if(server_motd[0] && config.cl_motd_time)
-			server_motd_time = time_get()+time_freq()*config.cl_motd_time;
+		if(m_aServerMotd[0] && g_Config.m_ClMotdTime)
+			m_ServerMotdTime = time_get()+time_freq()*g_Config.m_ClMotdTime;
 		else
-			server_motd_time = 0;
+			m_ServerMotdTime = 0;
 	}
 }
 
-bool MOTD::on_input(INPUT_EVENT e)
+bool CMotd::OnInput(IInput::CEvent Event)
 {
-	if(is_active() && e.flags&INPFLAG_PRESS && e.key == KEY_ESCAPE)
+	if(IsActive() && Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_ESCAPE)
 	{
-		clear();
+		Clear();
 		return true;
 	}
 	return false;
diff --git a/src/game/client/components/motd.h b/src/game/client/components/motd.h
new file mode 100644
index 00000000..41e15b8c
--- /dev/null
+++ b/src/game/client/components/motd.h
@@ -0,0 +1,21 @@
+#ifndef GAME_CLIENT_COMPONENTS_MOTD_H
+#define GAME_CLIENT_COMPONENTS_MOTD_H
+#include <game/client/component.h>
+
+class CMotd : public CComponent
+{
+	// motd
+	int64 m_ServerMotdTime;
+public:
+	char m_aServerMotd[900];
+
+	void Clear();
+	bool IsActive();
+	
+	virtual void OnRender();
+	virtual void OnStateChange(int NewState, int OldState);
+	virtual void OnMessage(int MsgType, void *pRawMsg);
+	virtual bool OnInput(IInput::CEvent Event);
+};
+
+#endif
diff --git a/src/game/client/components/motd.hpp b/src/game/client/components/motd.hpp
deleted file mode 100644
index 3b175e0a..00000000
--- a/src/game/client/components/motd.hpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <game/client/component.hpp>
-
-class MOTD : public COMPONENT
-{
-	// motd
-	int64 server_motd_time;
-public:
-	char server_motd[900];
-
-	void clear();
-	bool is_active();
-	
-	virtual void on_render();
-	virtual void on_statechange(int new_state, int old_state);
-	virtual void on_message(int msgtype, void *rawmsg);
-	virtual bool on_input(INPUT_EVENT e);
-};
-
diff --git a/src/game/client/components/nameplates.cpp b/src/game/client/components/nameplates.cpp
index 4a47ea37..da114bbb 100644
--- a/src/game/client/components/nameplates.cpp
+++ b/src/game/client/components/nameplates.cpp
@@ -1,65 +1,66 @@
-#include <engine/e_client_interface.h>
-#include <game/generated/g_protocol.hpp>
-#include <game/generated/gc_data.hpp>
+#include <engine/textrender.h>
+#include <engine/shared/config.h>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
 
-#include <game/client/gameclient.hpp>
-#include <game/client/animstate.hpp>
-#include "nameplates.hpp"
-#include "controls.hpp"
+#include <game/client/gameclient.h>
+#include <game/client/animstate.h>
+#include "nameplates.h"
+#include "controls.h"
 
-void NAMEPLATES::render_nameplate(
-	const NETOBJ_CHARACTER *prev_char,
-	const NETOBJ_CHARACTER *player_char,
-	const NETOBJ_PLAYER_INFO *player_info
+void CNamePlates::RenderNameplate(
+	const CNetObj_Character *pPrevChar,
+	const CNetObj_Character *pPlayerChar,
+	const CNetObj_PlayerInfo *pPlayerInfo
 	)
 {
-	float intratick = client_intratick();
+	float IntraTick = Client()->IntraGameTick();
 	
-	vec2 position = mix(vec2(prev_char->x, prev_char->y), vec2(player_char->x, player_char->y), intratick);
+	vec2 Position = mix(vec2(pPrevChar->m_X, pPrevChar->m_Y), vec2(pPlayerChar->m_X, pPlayerChar->m_Y), IntraTick);
 	
 	// render name plate
-	if(!player_info->local)
+	if(!pPlayerInfo->m_Local)
 	{
-		//gfx_text_color
+		//TextRender()->TextColor
 		float a = 1;
-		if(config.cl_nameplates_always == 0)
-			a = clamp(1-powf(distance(gameclient.controls->target_pos, position)/200.0f,16.0f), 0.0f, 1.0f);
+		if(g_Config.m_ClNameplatesAlways == 0)
+			a = clamp(1-powf(distance(m_pClient->m_pControls->m_TargetPos, Position)/200.0f,16.0f), 0.0f, 1.0f);
 			
-		const char *name = gameclient.clients[player_info->cid].name;
-		float tw = gfx_text_width(0, 28.0f, name, -1);
-		gfx_text_color(1,1,1,a);
-		gfx_text(0, position.x-tw/2.0f, position.y-60, 28.0f, name, -1);
+		const char *pName = m_pClient->m_aClients[pPlayerInfo->m_ClientId].m_aName;
+		float tw = TextRender()->TextWidth(0, 28.0f, pName, -1);
+		TextRender()->TextColor(1,1,1,a);
+		TextRender()->Text(0, Position.x-tw/2.0f, Position.y-60, 28.0f, pName, -1);
 		
-		if(config.debug) // render client id when in debug aswell
+		if(g_Config.m_Debug) // render client id when in debug aswell
 		{
-			char buf[128];
-			str_format(buf, sizeof(buf),"%d", player_info->cid);
-			gfx_text(0, position.x, position.y-90, 28.0f, buf, -1);
+			char aBuf[128];
+			str_format(aBuf, sizeof(aBuf),"%d", pPlayerInfo->m_ClientId);
+			TextRender()->Text(0, Position.x, Position.y-90, 28.0f, aBuf, -1);
 		}
 
-		gfx_text_color(1,1,1,1);
+		TextRender()->TextColor(1,1,1,1);
 	}
 }
 
-void NAMEPLATES::on_render()
+void CNamePlates::OnRender()
 {
-	if (!config.cl_nameplates)
+	if (!g_Config.m_ClNameplates)
 		return;
 
 	for(int i = 0; i < MAX_CLIENTS; i++)
 	{
 		// only render active characters
-		if(!gameclient.snap.characters[i].active)
+		if(!m_pClient->m_Snap.m_aCharacters[i].m_Active)
 			continue;
 
-		const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, i);
+		const void *pInfo = Client()->SnapFindItem(IClient::SNAP_CURRENT, NETOBJTYPE_PLAYERINFO, i);
 
-		if(info)
+		if(pInfo)
 		{
-			render_nameplate(
-				&gameclient.snap.characters[i].prev,
-				&gameclient.snap.characters[i].cur,
-				(const NETOBJ_PLAYER_INFO *)info);
+			RenderNameplate(
+				&m_pClient->m_Snap.m_aCharacters[i].m_Prev,
+				&m_pClient->m_Snap.m_aCharacters[i].m_Cur,
+				(const CNetObj_PlayerInfo *)pInfo);
 		}
 	}
 }
diff --git a/src/game/client/components/nameplates.h b/src/game/client/components/nameplates.h
new file mode 100644
index 00000000..279b6582
--- /dev/null
+++ b/src/game/client/components/nameplates.h
@@ -0,0 +1,17 @@
+#ifndef GAME_CLIENT_COMPONENTS_NAMEPLATES_H
+#define GAME_CLIENT_COMPONENTS_NAMEPLATES_H
+#include <game/client/component.h>
+
+class CNamePlates : public CComponent
+{
+	void RenderNameplate(
+		const class CNetObj_Character *pPrevChar,
+		const class CNetObj_Character *pPlayerChar,
+		const class CNetObj_PlayerInfo *pPlayerInfo
+	);
+
+public:
+	virtual void OnRender();
+};
+
+#endif
diff --git a/src/game/client/components/nameplates.hpp b/src/game/client/components/nameplates.hpp
deleted file mode 100644
index 2695f5ac..00000000
--- a/src/game/client/components/nameplates.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <game/client/component.hpp>
-
-class NAMEPLATES : public COMPONENT
-{
-	void render_nameplate(
-		const class NETOBJ_CHARACTER *prev_char,
-		const class NETOBJ_CHARACTER *player_char,
-		const class NETOBJ_PLAYER_INFO *player_info
-	);
-
-public:
-	virtual void on_render();
-};
-
diff --git a/src/game/client/components/particles.cpp b/src/game/client/components/particles.cpp
index 61fcf738..99c2c721 100644
--- a/src/game/client/components/particles.cpp
+++ b/src/game/client/components/particles.cpp
@@ -1,155 +1,156 @@
-#include <base/math.hpp>
-#include <engine/client/graphics.h>
+#include <base/math.h>
+#include <engine/graphics.h>
 
-#include <game/generated/gc_data.hpp>
-#include <game/client/render.hpp>
-#include <game/gamecore.hpp>
-#include "particles.hpp"
+#include <game/generated/client_data.h>
+#include <game/client/render.h>
+#include <game/gamecore.h>
+#include "particles.h"
 
-PARTICLES::PARTICLES()
+CParticles::CParticles()
 {
-	on_reset();
-	render_trail.parts = this;
-	render_explosions.parts = this;
-	render_general.parts = this;
+	OnReset();
+	m_RenderTrail.m_pParts = this;
+	m_RenderExplosions.m_pParts = this;
+	m_RenderGeneral.m_pParts = this;
 }
 
 
-void PARTICLES::on_reset()
+void CParticles::OnReset()
 {
 	// reset particles
 	for(int i = 0; i < MAX_PARTICLES; i++)
 	{
-		particles[i].prev_part = i-1;
-		particles[i].next_part = i+1;
+		m_aParticles[i].m_PrevPart = i-1;
+		m_aParticles[i].m_NextPart = i+1;
 	}
 	
-	particles[0].prev_part = 0;
-	particles[MAX_PARTICLES-1].next_part = -1;
-	first_free = 0;
+	m_aParticles[0].m_PrevPart = 0;
+	m_aParticles[MAX_PARTICLES-1].m_NextPart = -1;
+	m_FirstFree = 0;
 
 	for(int i = 0; i < NUM_GROUPS; i++)
-		first_part[i] = -1;
+		m_aFirstPart[i] = -1;
 }
 
-void PARTICLES::add(int group, PARTICLE *part)
+void CParticles::Add(int Group, CParticle *pPart)
 {
-	if (first_free == -1)
+	if (m_FirstFree == -1)
 		return;
 		
 	// remove from the free list
-	int id = first_free;
-	first_free = particles[id].next_part;
-	particles[first_free].prev_part = -1;
+	int Id = m_FirstFree;
+	m_FirstFree = m_aParticles[Id].m_NextPart;
+	m_aParticles[m_FirstFree].m_PrevPart = -1;
 	
 	// copy data
-	particles[id] = *part;
+	m_aParticles[Id] = *pPart;
 	
 	// insert to the group list
-	particles[id].prev_part = -1;
-	particles[id].next_part = first_part[group];
-	if(first_part[group] != -1)
-		particles[first_part[group]].prev_part = id;
-	first_part[group] = id;
+	m_aParticles[Id].m_PrevPart = -1;
+	m_aParticles[Id].m_NextPart = m_aFirstPart[Group];
+	if(m_aFirstPart[Group] != -1)
+		m_aParticles[m_aFirstPart[Group]].m_PrevPart = Id;
+	m_aFirstPart[Group] = Id;
 	
 	// set some parameters
-	particles[id].life = 0;
+	m_aParticles[Id].m_Life = 0;
 }
 
-void PARTICLES::update(float time_passed)
+void CParticles::Update(float TimePassed)
 {
-	static float friction_fraction = 0;
-	friction_fraction += time_passed;
+	static float FrictionFraction = 0;
+	FrictionFraction += TimePassed;
 
-	if(friction_fraction > 2.0f) // safty messure
-		friction_fraction = 0;
+	if(FrictionFraction > 2.0f) // safty messure
+		FrictionFraction = 0;
 	
-	int friction_count = 0;
-	while(friction_fraction > 0.05f)
+	int FrictionCount = 0;
+	while(FrictionFraction > 0.05f)
 	{
-		friction_count++;
-		friction_fraction -= 0.05f;
+		FrictionCount++;
+		FrictionFraction -= 0.05f;
 	}
 	
 	for(int g = 0; g < NUM_GROUPS; g++)
 	{
-		int i = first_part[g];
+		int i = m_aFirstPart[g];
 		while(i != -1)
 		{
-			int next = particles[i].next_part;
-			//particles[i].vel += flow_get(particles[i].pos)*time_passed * particles[i].flow_affected;
-			particles[i].vel.y += particles[i].gravity*time_passed;
+			int Next = m_aParticles[i].m_NextPart;
+			//m_aParticles[i].vel += flow_get(m_aParticles[i].pos)*time_passed * m_aParticles[i].flow_affected;
+			m_aParticles[i].m_Vel.y += m_aParticles[i].m_Gravity*TimePassed;
 			
-			for(int f = 0; f < friction_count; f++) // apply friction
-				particles[i].vel *= particles[i].friction;
+			for(int f = 0; f < FrictionCount; f++) // apply friction
+				m_aParticles[i].m_Vel *= m_aParticles[i].m_Friction;
 			
 			// move the point
-			vec2 vel = particles[i].vel*time_passed;
-			move_point(&particles[i].pos, &vel, 0.1f+0.9f*frandom(), NULL);
-			particles[i].vel = vel* (1.0f/time_passed);
+			vec2 Vel = m_aParticles[i].m_Vel*TimePassed;
+			Collision()->MovePoint(&m_aParticles[i].m_Pos, &Vel, 0.1f+0.9f*frandom(), NULL);
+			m_aParticles[i].m_Vel = Vel* (1.0f/TimePassed);
 			
-			particles[i].life += time_passed;
-			particles[i].rot += time_passed * particles[i].rotspeed;
+			m_aParticles[i].m_Life += TimePassed;
+			m_aParticles[i].m_Rot += TimePassed * m_aParticles[i].m_Rotspeed;
 
 			// check particle death
-			if(particles[i].life > particles[i].life_span)
+			if(m_aParticles[i].m_Life > m_aParticles[i].m_LifeSpan)
 			{
 				// remove it from the group list
-				if(particles[i].prev_part != -1)
-					particles[particles[i].prev_part].next_part = particles[i].next_part;
+				if(m_aParticles[i].m_PrevPart != -1)
+					m_aParticles[m_aParticles[i].m_PrevPart].m_NextPart = m_aParticles[i].m_NextPart;
 				else
-					first_part[g] = particles[i].next_part;
+					m_aFirstPart[g] = m_aParticles[i].m_NextPart;
 					
-				if(particles[i].next_part != -1)
-					particles[particles[i].next_part].prev_part = particles[i].prev_part;
+				if(m_aParticles[i].m_NextPart != -1)
+					m_aParticles[m_aParticles[i].m_NextPart].m_PrevPart = m_aParticles[i].m_PrevPart;
 					
 				// insert to the free list
-				if(first_free != -1)
-					particles[first_free].prev_part = i;
-				particles[i].prev_part = -1;
-				particles[i].next_part = first_free;
-				first_free = i;
+				if(m_FirstFree != -1)
+					m_aParticles[m_FirstFree].m_PrevPart = i;
+				m_aParticles[i].m_PrevPart = -1;
+				m_aParticles[i].m_NextPart = m_FirstFree;
+				m_FirstFree = i;
 			}
 			
-			i = next;
+			i = Next;
 		}
 	}
 }
 
-void PARTICLES::on_render()
+void CParticles::OnRender()
 {
-	static int64 lasttime = 0;
+	static int64 LastTime = 0;
 	int64 t = time_get();
-	update((float)((t-lasttime)/(double)time_freq()));
-	lasttime = t;
+	Update((float)((t-LastTime)/(double)time_freq()));
+	LastTime = t;
 }
 
-void PARTICLES::render_group(int group)
+void CParticles::RenderGroup(int Group)
 {
 	Graphics()->BlendNormal();
 	//gfx_blend_additive();
-	Graphics()->TextureSet(data->images[IMAGE_PARTICLES].id);
+	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id);
 	Graphics()->QuadsBegin();
 
-	int i = first_part[group];
+	int i = m_aFirstPart[Group];
 	while(i != -1)
 	{
-		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);
+		RenderTools()->SelectSprite(m_aParticles[i].m_Spr);
+		float a = m_aParticles[i].m_Life / m_aParticles[i].m_LifeSpan;
+		vec2 p = m_aParticles[i].m_Pos;
+		float Size = mix(m_aParticles[i].m_StartSize, m_aParticles[i].m_EndSize, a);
 
-		Graphics()->QuadsSetRotation(particles[i].rot);
+		Graphics()->QuadsSetRotation(m_aParticles[i].m_Rot);
 
 		Graphics()->SetColor(
-			particles[i].color.r,
-			particles[i].color.g,
-			particles[i].color.b,
-			particles[i].color.a); // pow(a, 0.75f) * 
+			m_aParticles[i].m_Color.r,
+			m_aParticles[i].m_Color.g,
+			m_aParticles[i].m_Color.b,
+			m_aParticles[i].m_Color.a); // pow(a, 0.75f) * 
 
-		Graphics()->QuadsDraw(p.x, p.y, size, size);
+		IGraphics::CQuadItem QuadItem(p.x, p.y, Size, Size);
+		Graphics()->QuadsDraw(&QuadItem, 1);
 		
-		i = particles[i].next_part;
+		i = m_aParticles[i].m_NextPart;
 	}
 	Graphics()->QuadsEnd();
 	Graphics()->BlendNormal();
diff --git a/src/game/client/components/particles.h b/src/game/client/components/particles.h
new file mode 100644
index 00000000..af9a9203
--- /dev/null
+++ b/src/game/client/components/particles.h
@@ -0,0 +1,94 @@
+#ifndef GAME_CLIENT_COMPONENTS_PARTICLES_H
+#define GAME_CLIENT_COMPONENTS_PARTICLES_H
+#include <base/vmath.h>
+#include <game/client/component.h>
+
+// particles
+struct CParticle
+{
+	void SetDefault()
+	{
+		m_Vel = vec2(0,0);
+		m_LifeSpan = 0;
+		m_StartSize = 32;
+		m_EndSize = 32;
+		m_Rot = 0;
+		m_Rotspeed = 0;
+		m_Gravity = 0;
+		m_Friction = 0;
+		m_FlowAffected = 1.0f;
+		m_Color = vec4(1,1,1,1);
+	}
+	
+	vec2 m_Pos;
+	vec2 m_Vel;
+
+	int m_Spr;
+
+	float m_FlowAffected;
+
+	float m_LifeSpan;
+	
+	float m_StartSize;
+	float m_EndSize;
+
+	float m_Rot;
+	float m_Rotspeed;
+
+	float m_Gravity;
+	float m_Friction;
+
+	vec4 m_Color;
+	
+	// set by the particle system
+	float m_Life;
+	int m_PrevPart;
+	int m_NextPart;
+};
+
+class CParticles : public CComponent
+{
+	friend class CGameClient;
+public:
+	enum
+	{
+		GROUP_PROJECTILE_TRAIL=0,
+		GROUP_EXPLOSIONS,
+		GROUP_GENERAL,
+		NUM_GROUPS
+	};
+
+	CParticles();
+	
+	void Add(int Group, CParticle *pPart);
+	
+	virtual void OnReset();
+	virtual void OnRender();
+
+private:
+	
+	enum
+	{
+		MAX_PARTICLES=1024*8,
+	};
+
+	CParticle m_aParticles[MAX_PARTICLES];
+	int m_FirstFree;
+	int m_aFirstPart[NUM_GROUPS];
+	
+	void RenderGroup(int Group);
+	void Update(float TimePassed);
+
+	template<int TGROUP>
+	class CRenderGroup : public CComponent
+	{
+	public:
+		CParticles *m_pParts;
+		virtual void OnRender() { m_pParts->RenderGroup(TGROUP); }
+	};
+	
+	CRenderGroup<GROUP_PROJECTILE_TRAIL> m_RenderTrail;
+	CRenderGroup<GROUP_EXPLOSIONS> m_RenderExplosions;
+	CRenderGroup<GROUP_GENERAL> m_RenderGeneral;
+};
+#endif
diff --git a/src/game/client/components/particles.hpp b/src/game/client/components/particles.hpp
deleted file mode 100644
index 6c466d94..00000000
--- a/src/game/client/components/particles.hpp
+++ /dev/null
@@ -1,91 +0,0 @@
-#include <base/vmath.hpp>
-#include <game/client/component.hpp>
-
-// particles
-struct PARTICLE
-{
-	void set_default()
-	{
-		vel = vec2(0,0);
-		life_span = 0;
-		start_size = 32;
-		end_size = 32;
-		rot = 0;
-		rotspeed = 0;
-		gravity = 0;
-		friction = 0;
-		flow_affected = 1.0f;
-		color = vec4(1,1,1,1);
-	}
-	
-	vec2 pos;
-	vec2 vel;
-
-	int spr;
-
-	float flow_affected;
-
-	float life_span;
-	
-	float start_size;
-	float end_size;
-
-	float rot;
-	float rotspeed;
-
-	float gravity;
-	float friction;
-
-	vec4 color;
-	
-	// set by the particle system
-	float life;
-	int prev_part;
-	int next_part;
-};
-
-class PARTICLES : public COMPONENT
-{
-	friend class GAMECLIENT;
-public:
-	enum
-	{
-		GROUP_PROJECTILE_TRAIL=0,
-		GROUP_EXPLOSIONS,
-		GROUP_GENERAL,
-		NUM_GROUPS
-	};
-
-	PARTICLES();
-	
-	void add(int group, PARTICLE *part);
-	
-	virtual void on_reset();
-	virtual void on_render();
-
-private:
-	
-	enum
-	{
-		MAX_PARTICLES=1024*8,
-	};
-
-	PARTICLE particles[MAX_PARTICLES];
-	int first_free;
-	int first_part[NUM_GROUPS];
-	
-	void render_group(int group);
-	void update(float time_passed);
-
-	template<int TGROUP>
-	class RENDER_GROUP : public COMPONENT
-	{
-	public:
-		PARTICLES *parts;
-		virtual void on_render() { parts->render_group(TGROUP); }
-	};
-	
-	RENDER_GROUP<GROUP_PROJECTILE_TRAIL> render_trail;
-	RENDER_GROUP<GROUP_EXPLOSIONS> render_explosions;
-	RENDER_GROUP<GROUP_GENERAL> render_general;
-};
diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp
index e1fee3e8..8ad7b0cb 100644
--- a/src/game/client/components/players.cpp
+++ b/src/game/client/components/players.cpp
@@ -1,147 +1,269 @@
-#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/gamecore.hpp> // get_angle
-#include <game/client/animstate.hpp>
-#include <game/client/gameclient.hpp>
-#include <game/client/ui.hpp>
-#include <game/client/render.hpp>
-
-#include <game/client/components/flow.hpp>
-#include <game/client/components/skins.hpp>
-#include <game/client/components/effects.hpp>
-#include <game/client/components/sounds.hpp>
-#include <game/client/components/controls.hpp>
-
-#include "players.hpp"
-
-void PLAYERS::render_hand(TEE_RENDER_INFO *info, vec2 center_pos, vec2 dir, float angle_offset, vec2 post_rot_offset)
+#include <engine/graphics.h>
+#include <engine/shared/config.h>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
+
+#include <game/gamecore.h> // get_angle
+#include <game/client/animstate.h>
+#include <game/client/gameclient.h>
+#include <game/client/ui.h>
+#include <game/client/render.h>
+
+#include <game/client/components/flow.h>
+#include <game/client/components/skins.h>
+#include <game/client/components/effects.h>
+#include <game/client/components/sounds.h>
+#include <game/client/components/controls.h>
+
+#include "players.h"
+
+void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset)
 {
 	// for drawing hand
 	//const skin *s = skin_get(skin_id);
 	
-	float basesize = 10.0f;
+	float BaseSize = 10.0f;
 	//dir = normalize(hook_pos-pos);
 
-	vec2 hand_pos = center_pos + dir;
-	float angle = get_angle(dir);
-	if (dir.x < 0)
-		angle -= angle_offset;
+	vec2 HandPos = CenterPos + Dir;
+	float Angle = GetAngle(Dir);
+	if (Dir.x < 0)
+		Angle -= AngleOffset;
 	else
-		angle += angle_offset;
+		Angle += AngleOffset;
 
-	vec2 dirx = dir;
-	vec2 diry(-dir.y,dir.x);
+	vec2 DirX = Dir;
+	vec2 DirY(-Dir.y,Dir.x);
 
-	if (dir.x < 0)
-		diry = -diry;
+	if (Dir.x < 0)
+		DirY = -DirY;
 
-	hand_pos += dirx * post_rot_offset.x;
-	hand_pos += diry * post_rot_offset.y;
+	HandPos += DirX * PostRotOffset.x;
+	HandPos += DirY * PostRotOffset.y;
 
-	//Graphics()->TextureSet(data->images[IMAGE_CHAR_DEFAULT].id);
-	Graphics()->TextureSet(info->texture);
+	//Graphics()->TextureSet(data->m_aImages[IMAGE_CHAR_DEFAULT].id);
+	Graphics()->TextureSet(pInfo->m_Texture);
 	Graphics()->QuadsBegin();
-	Graphics()->SetColor(info->color_body.r, info->color_body.g, info->color_body.b, info->color_body.a);
+	Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, pInfo->m_ColorBody.a);
 
 	// two passes
 	for (int i = 0; i < 2; i++)
 	{
-		bool outline = i == 0;
+		bool OutLine = i == 0;
 
-		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);
+		RenderTools()->SelectSprite(OutLine?SPRITE_TEE_HAND_OUTLINE:SPRITE_TEE_HAND, 0, 0, 0);
+		Graphics()->QuadsSetRotation(Angle);
+		IGraphics::CQuadItem QuadItem(HandPos.x, HandPos.y, 2*BaseSize, 2*BaseSize);
+		Graphics()->QuadsDraw(&QuadItem, 1);
 	}
 
 	Graphics()->QuadsSetRotation(0);
 	Graphics()->QuadsEnd();
 }
 
-inline float normalize_angular(float f)
+inline float NormalizeAngular(float f)
 {
 	return fmod(f+pi*2, pi*2);
 }
 
-inline float angular_mix_direction(float src, float dst) { return sinf(dst-src) >0?1:-1; }
-inline float angular_distance(float src, float dst) { return asinf(sinf(dst-src)); }
+inline float AngularMixDirection (float Src, float Dst) { return sinf(Dst-Src) >0?1:-1; }
+inline float AngularDistance(float Src, float Dst) { return asinf(sinf(Dst-Src)); }
 
-inline float angular_approach(float src, float dst, float amount)
+inline float AngularApproach(float Src, float Dst, float Amount)
 {
-	float d = angular_mix_direction(src, dst);
-	float n = src + amount*d;
-	if(angular_mix_direction(n, dst) != d)
-		return dst;
+	float d = AngularMixDirection (Src, Dst);
+	float n = Src + Amount*d;
+	if(AngularMixDirection (n, Dst) != d)
+		return Dst;
 	return n;
 }
 
-void PLAYERS::render_player(
-	const NETOBJ_CHARACTER *prev_char,
-	const NETOBJ_CHARACTER *player_char,
-	const NETOBJ_PLAYER_INFO *prev_info,
-	const NETOBJ_PLAYER_INFO *player_info
+void CPlayers::RenderHook(
+	const CNetObj_Character *pPrevChar,
+	const CNetObj_Character *pPlayerChar,
+	const CNetObj_PlayerInfo *pPrevInfo,
+	const CNetObj_PlayerInfo *pPlayerInfo
 	)
 {
-	NETOBJ_CHARACTER prev;
-	NETOBJ_CHARACTER player;
-	prev = *prev_char;
-	player = *player_char;
+	CNetObj_Character Prev;
+	CNetObj_Character Player;
+	Prev = *pPrevChar;
+	Player = *pPlayerChar;
 
-	NETOBJ_PLAYER_INFO info = *player_info;
-	TEE_RENDER_INFO render_info = gameclient.clients[info.cid].render_info;
+	CNetObj_PlayerInfo pInfo = *pPlayerInfo;
+	CTeeRenderInfo RenderInfo = m_pClient->m_aClients[pInfo.m_ClientId].m_RenderInfo;
 
 	// check for teamplay modes
-	bool is_teamplay = false;
-	bool new_tick = gameclient.new_tick;
-	if(gameclient.snap.gameobj)
-		is_teamplay = (gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS) != 0;
+	bool IsTeamplay = false;
+	if(m_pClient->m_Snap.m_pGameobj)
+		IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0;
 
 	// check for ninja	
-	if (player.weapon == WEAPON_NINJA)
+	if (Player.m_Weapon == WEAPON_NINJA)
 	{
 		// change the skin for the player to the ninja
-		int skin = gameclient.skins->find("x_ninja");
-		if(skin != -1)
+		int Skin = m_pClient->m_pSkins->Find("x_ninja");
+		if(Skin != -1)
 		{
-			if(is_teamplay)
-				render_info.texture = gameclient.skins->get(skin)->color_texture;
+			if(IsTeamplay)
+				RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_ColorTexture;
 			else
 			{
-				render_info.texture = gameclient.skins->get(skin)->org_texture;
-				render_info.color_body = vec4(1,1,1,1);
-				render_info.color_feet = vec4(1,1,1,1);
+				RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture;
+				RenderInfo.m_ColorBody = vec4(1,1,1,1);
+				RenderInfo.m_ColorFeet = vec4(1,1,1,1);
+			}
+		}	
+	}
+
+	float IntraTick = Client()->IntraGameTick();
+
+	if(Player.m_Health < 0) // dont render dead players
+		return;
+
+	// set size
+	RenderInfo.m_Size = 64.0f;
+
+	
+	// use preditect players if needed
+	if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
+	{
+		if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pLocalCharacter->m_Health < 0) || (m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver))
+		{
+		}
+		else
+		{
+			// apply predicted results
+			m_pClient->m_PredictedChar.Write(&Player);
+			m_pClient->m_PredictedPrevChar.Write(&Prev);
+			IntraTick = Client()->PredIntraGameTick();
+		}
+	}
+
+	vec2 Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick);
+
+	if(Prev.m_Health < 0) // Don't flicker from previous position
+		Position = vec2(Player.m_X, Player.m_Y);
+
+	// draw hook
+	if (Prev.m_HookState>0 && Player.m_HookState>0)
+	{
+		Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
+		Graphics()->QuadsBegin();
+		//Graphics()->QuadsBegin();
+
+		vec2 Pos = Position;
+		vec2 HookPos;
+		
+		if(pPlayerChar->m_HookedPlayer != -1)
+		{
+			if(m_pClient->m_Snap.m_pLocalInfo && pPlayerChar->m_HookedPlayer == m_pClient->m_Snap.m_pLocalInfo->m_ClientId)
+			{
+				if(Client()->State() == IClient::STATE_DEMOPLAYBACK) // only use prediction if needed
+					HookPos = vec2(m_pClient->m_LocalCharacterPos.x, m_pClient->m_LocalCharacterPos.y);
+				else
+					HookPos = mix(vec2(m_pClient->m_PredictedPrevChar.m_Pos.x, m_pClient->m_PredictedPrevChar.m_Pos.y),
+						vec2(m_pClient->m_PredictedChar.m_Pos.x, m_pClient->m_PredictedChar.m_Pos.y), Client()->PredIntraGameTick());
+			}
+			else
+				HookPos = mix(vec2(pPrevChar->m_HookX, pPrevChar->m_HookY), vec2(pPlayerChar->m_HookX, pPlayerChar->m_HookY), Client()->IntraGameTick());
+		}
+		else
+			HookPos = mix(vec2(Prev.m_HookX, Prev.m_HookY), vec2(Player.m_HookX, Player.m_HookY), IntraTick);
+
+		float d = distance(Pos, HookPos);
+		vec2 Dir = normalize(Pos-HookPos);
+
+		Graphics()->QuadsSetRotation(GetAngle(Dir)+pi);
+
+		// render head
+		RenderTools()->SelectSprite(SPRITE_HOOK_HEAD);
+		IGraphics::CQuadItem QuadItem(HookPos.x, HookPos.y, 24,16);
+		Graphics()->QuadsDraw(&QuadItem, 1);
+
+		// render chain
+		RenderTools()->SelectSprite(SPRITE_HOOK_CHAIN);
+		IGraphics::CQuadItem Array[1024];
+		int i = 0;
+		for(float f = 24; f < d && i < 1024; f += 24, i++)
+		{
+			vec2 p = HookPos + Dir*f;
+			Array[i] = IGraphics::CQuadItem(p.x, p.y,24,16);
+		}
+
+		Graphics()->QuadsDraw(Array, i);
+		Graphics()->QuadsSetRotation(0);
+		Graphics()->QuadsEnd();
+
+		RenderHand(&RenderInfo, Position, normalize(HookPos-Pos), -pi/2, vec2(20, 0));
+	}
+}
+
+void CPlayers::RenderPlayer(
+	const CNetObj_Character *pPrevChar,
+	const CNetObj_Character *pPlayerChar,
+	const CNetObj_PlayerInfo *pPrevInfo,
+	const CNetObj_PlayerInfo *pPlayerInfo
+	)
+{
+	CNetObj_Character Prev;
+	CNetObj_Character Player;
+	Prev = *pPrevChar;
+	Player = *pPlayerChar;
+
+	CNetObj_PlayerInfo pInfo = *pPlayerInfo;
+	CTeeRenderInfo RenderInfo = m_pClient->m_aClients[pInfo.m_ClientId].m_RenderInfo;
+
+	// check for teamplay modes
+	bool IsTeamplay = false;
+	bool NewTick = m_pClient->m_NewTick;
+	if(m_pClient->m_Snap.m_pGameobj)
+		IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0;
+
+	// check for ninja	
+	if (Player.m_Weapon == WEAPON_NINJA)
+	{
+		// change the skin for the player to the ninja
+		int Skin = m_pClient->m_pSkins->Find("x_ninja");
+		if(Skin != -1)
+		{
+			if(IsTeamplay)
+				RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_ColorTexture;
+			else
+			{
+				RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture;
+				RenderInfo.m_ColorBody = vec4(1,1,1,1);
+				RenderInfo.m_ColorFeet = vec4(1,1,1,1);
 			}
 		}	
 	}
 	
 	// set size
-	render_info.size = 64.0f;
+	RenderInfo.m_Size = 64.0f;
 
-	float intratick = client_intratick();
+	float IntraTick = Client()->IntraGameTick();
 	
-	if(player.health < 0) // dont render dead players
+	if(Player.m_Health < 0) // dont render dead players
 		return;
 
-	float angle = mix((float)prev.angle, (float)player.angle, intratick)/256.0f;
+	float Angle = mix((float)Prev.m_Angle, (float)Player.m_Angle, IntraTick)/256.0f;
 	
 	//float angle = 0;
 	
-	if(info.local && client_state() != CLIENTSTATE_DEMOPLAYBACK)
+	if(pInfo.m_Local && Client()->State() != IClient::STATE_DEMOPLAYBACK)
 	{
 		// just use the direct input if it's local player we are rendering
-		angle = get_angle(gameclient.controls->mouse_pos);
+		Angle = GetAngle(m_pClient->m_pControls->m_MousePos);
 	}
 	else
 	{
 		/*
-		float mixspeed = client_frametime()*2.5f;
+		float mixspeed = Client()->FrameTime()*2.5f;
 		if(player.attacktick != prev.attacktick) // shooting boosts the mixing speed
 			mixspeed *= 15.0f;
 		
 		// move the delta on a constant speed on a x^2 curve
-		float current = gameclient.clients[info.cid].angle;
+		float current = g_GameClient.m_aClients[info.cid].angle;
 		float target = player.angle/256.0f;
 		float delta = angular_distance(current, target);
 		float sign = delta < 0 ? -1 : 1;
@@ -153,342 +275,305 @@ void PLAYERS::render_player(
 		else
 			angle = angular_approach(current, target, fabs(delta-new_delta));
 
-		gameclient.clients[info.cid].angle = angle;*/
+		g_GameClient.m_aClients[info.cid].angle = angle;*/
 	}
 	
 	// use preditect players if needed
-	if(info.local && config.cl_predict && client_state() != CLIENTSTATE_DEMOPLAYBACK)
+	if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
 	{
-		if(!gameclient.snap.local_character || (gameclient.snap.local_character->health < 0) || (gameclient.snap.gameobj && gameclient.snap.gameobj->game_over))
+		if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pLocalCharacter->m_Health < 0) || (m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver))
 		{
 		}
 		else
 		{
 			// apply predicted results
-			gameclient.predicted_char.write(&player);
-			gameclient.predicted_prev_char.write(&prev);
-			intratick = client_predintratick();
-			new_tick = gameclient.new_predicted_tick;
+			m_pClient->m_PredictedChar.Write(&Player);
+			m_pClient->m_PredictedPrevChar.Write(&Prev);
+			IntraTick = Client()->PredIntraGameTick();
+			NewTick = m_pClient->m_NewPredictedTick;
 		}
 	}
 	
-	vec2 direction = get_direction((int)(angle*256.0f));
-	vec2 position = mix(vec2(prev.x, prev.y), vec2(player.x, player.y), intratick);
-	vec2 vel = mix(vec2(prev.vx/256.0f, prev.vy/256.0f), vec2(player.vx/256.0f, player.vy/256.0f), intratick);
+	vec2 Direction = GetDirection((int)(Angle*256.0f));
+	vec2 Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick);
+	vec2 Vel = mix(vec2(Prev.m_VelX/256.0f, Prev.m_VelY/256.0f), vec2(Player.m_VelX/256.0f, Player.m_VelY/256.0f), IntraTick);
 	
-	gameclient.flow->add(position, vel*100.0f, 10.0f);
+	m_pClient->m_pFlow->Add(Position, Vel*100.0f, 10.0f);
 	
-	render_info.got_airjump = player.jumped&2?0:1;
+	RenderInfo.m_GotAirJump = Player.m_Jumped&2?0:1;
 	
 	
 	// detect events
-	if(new_tick)
+	if(NewTick)
 	{
 		// detect air jump
-		if(!render_info.got_airjump && !(prev.jumped&2))
-			gameclient.effects->air_jump(position);
+		if(!RenderInfo.m_GotAirJump && !(Prev.m_Jumped&2))
+			m_pClient->m_pEffects->AirJump(Position);
 	}
 
-	if(prev.health < 0) // Don't flicker from previous position
-		position = vec2(player.x, player.y);
+	if(Prev.m_Health < 0) // Don't flicker from previous position
+		Position = vec2(Player.m_X, Player.m_Y);
 
-	bool stationary = player.vx < 1 && player.vx > -1;
-	bool inair = col_check_point(player.x, player.y+16) == 0;
-	bool want_other_dir = (player.direction == -1 && vel.x > 0) || (player.direction == 1 && vel.x < 0);
+	bool Stationary = Player.m_VelX <= 1 && Player.m_VelX >= -1;
+	bool InAir = !Collision()->CheckPoint(Player.m_X, Player.m_Y+16);
+	bool WantOtherDir = (Player.m_Direction == -1 && Vel.x > 0) || (Player.m_Direction == 1 && Vel.x < 0);
 
 	// evaluate animation
-	float walk_time = fmod(position.x, 100.0f)/100.0f;
-	ANIMSTATE state;
-	state.set(&data->animations[ANIM_BASE], 0);
-
-	if(inair)
-		state.add(&data->animations[ANIM_INAIR], 0, 1.0f); // TODO: some sort of time here
-	else if(stationary)
-		state.add(&data->animations[ANIM_IDLE], 0, 1.0f); // TODO: some sort of time here
-	else if(!want_other_dir)
-		state.add(&data->animations[ANIM_WALK], walk_time, 1.0f);
-
-	if (player.weapon == WEAPON_HAMMER)
+	float WalkTime = fmod(Position.x, 100.0f)/100.0f;
+	CAnimState State;
+	State.Set(&g_pData->m_aAnimations[ANIM_BASE], 0);
+
+	if(InAir)
+		State.Add(&g_pData->m_aAnimations[ANIM_INAIR], 0, 1.0f); // TODO: some sort of time here
+	else if(Stationary)
+		State.Add(&g_pData->m_aAnimations[ANIM_IDLE], 0, 1.0f); // TODO: some sort of time here
+	else if(!WantOtherDir)
+		State.Add(&g_pData->m_aAnimations[ANIM_WALK], WalkTime, 1.0f);
+
+	if (Player.m_Weapon == WEAPON_HAMMER)
 	{
-		float ct = (client_prevtick()-player.attacktick)/(float)SERVER_TICK_SPEED + client_ticktime();
-		state.add(&data->animations[ANIM_HAMMER_SWING], clamp(ct*5.0f,0.0f,1.0f), 1.0f);
+		float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime();
+		State.Add(&g_pData->m_aAnimations[ANIM_HAMMER_SWING], clamp(ct*5.0f,0.0f,1.0f), 1.0f);
 	}
-	if (player.weapon == WEAPON_NINJA)
+	if (Player.m_Weapon == WEAPON_NINJA)
 	{
-		float ct = (client_prevtick()-player.attacktick)/(float)SERVER_TICK_SPEED + client_ticktime();
-		state.add(&data->animations[ANIM_NINJA_SWING], clamp(ct*2.0f,0.0f,1.0f), 1.0f);
+		float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime();
+		State.Add(&g_pData->m_aAnimations[ANIM_NINJA_SWING], clamp(ct*2.0f,0.0f,1.0f), 1.0f);
 	}
 	
 	// do skidding
-	if(!inair && want_other_dir && length(vel*50) > 500.0f)
+	if(!InAir && WantOtherDir && length(Vel*50) > 500.0f)
 	{
-		static int64 skid_sound_time = 0;
-		if(time_get()-skid_sound_time > time_freq()/10)
+		static int64 SkidSoundTime = 0;
+		if(time_get()-SkidSoundTime > time_freq()/10)
 		{
-			gameclient.sounds->play(SOUNDS::CHN_WORLD, SOUND_PLAYER_SKID, 0.25f, position);
-			skid_sound_time = time_get();
+			m_pClient->m_pSounds->Play(CSounds::CHN_WORLD, SOUND_PLAYER_SKID, 0.25f, Position);
+			SkidSoundTime = time_get();
 		}
 		
-		gameclient.effects->skidtrail(
-			position+vec2(-player.direction*6,12),
-			vec2(-player.direction*100*length(vel),-50)
+		m_pClient->m_pEffects->SkidTrail(
+			Position+vec2(-Player.m_Direction*6,12),
+			vec2(-Player.m_Direction*100*length(Vel),-50)
 		);
 	}
 
-	// draw hook
-	if (prev.hook_state>0 && player.hook_state>0)
-	{
-		Graphics()->TextureSet(data->images[IMAGE_GAME].id);
-		Graphics()->QuadsBegin();
-		//Graphics()->QuadsBegin();
-
-		vec2 pos = position;
-		vec2 hook_pos;
-		
-		if(player_char->hooked_player != -1)
-		{
-			if(gameclient.snap.local_info && player_char->hooked_player == gameclient.snap.local_info->cid)
-			{
-				hook_pos = mix(vec2(gameclient.predicted_prev_char.pos.x, gameclient.predicted_prev_char.pos.y),
-					vec2(gameclient.predicted_char.pos.x, gameclient.predicted_char.pos.y), client_predintratick());
-			}
-			else
-				hook_pos = mix(vec2(prev_char->hook_x, prev_char->hook_y), vec2(player_char->hook_x, player_char->hook_y), client_intratick());
-		}
-		else
-			hook_pos = mix(vec2(prev.hook_x, prev.hook_y), vec2(player.hook_x, player.hook_y), intratick);
-
-		float d = distance(pos, hook_pos);
-		vec2 dir = normalize(pos-hook_pos);
-
-		Graphics()->QuadsSetRotation(get_angle(dir)+pi);
-
-		// render head
-		RenderTools()->select_sprite(SPRITE_HOOK_HEAD);
-		Graphics()->QuadsDraw(hook_pos.x, hook_pos.y, 24,16);
-
-		// render 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;
-			Graphics()->QuadsDraw(p.x, p.y,24,16);
-		}
-
-		Graphics()->QuadsSetRotation(0);
-		Graphics()->QuadsEnd();
-
-		render_hand(&render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
-	}
-
 	// draw gun
 	{
-		Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+		Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 		Graphics()->QuadsBegin();
-		Graphics()->QuadsSetRotation(state.attach.angle*pi*2+angle);
+		Graphics()->QuadsSetRotation(State.GetAttach()->m_Angle*pi*2+Angle);
 
 		// normal weapons
-		int iw = clamp(player.weapon, 0, NUM_WEAPONS-1);
-		RenderTools()->select_sprite(data->weapons.id[iw].sprite_body, direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
+		int iw = clamp(Player.m_Weapon, 0, NUM_WEAPONS-1);
+		RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_pSpriteBody, Direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
 
-		vec2 dir = direction;
-		float recoil = 0.0f;
+		vec2 Dir = Direction;
+		float Recoil = 0.0f;
 		vec2 p;
-		if (player.weapon == WEAPON_HAMMER)
+		if (Player.m_Weapon == WEAPON_HAMMER)
 		{
 			// Static position for hammer
-			p = position + vec2(state.attach.x, state.attach.y);
-			p.y += data->weapons.id[iw].offsety;
+			p = Position + vec2(State.GetAttach()->m_X, State.GetAttach()->m_Y);
+			p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety;
 			// if attack is under way, bash stuffs
-			if(direction.x < 0)
+			if(Direction.x < 0)
 			{
-				Graphics()->QuadsSetRotation(-pi/2-state.attach.angle*pi*2);
-				p.x -= data->weapons.id[iw].offsetx;
+				Graphics()->QuadsSetRotation(-pi/2-State.GetAttach()->m_Angle*pi*2);
+				p.x -= g_pData->m_Weapons.m_aId[iw].m_Offsetx;
 			}
 			else
 			{
-				Graphics()->QuadsSetRotation(-pi/2+state.attach.angle*pi*2);
+				Graphics()->QuadsSetRotation(-pi/2+State.GetAttach()->m_Angle*pi*2);
 			}
-			RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
+			RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize);
 		}
-		else if (player.weapon == WEAPON_NINJA)
+		else if (Player.m_Weapon == WEAPON_NINJA)
 		{
-			p = position;
-			p.y += data->weapons.id[iw].offsety;
+			p = Position;
+			p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety;
 
-			if(direction.x < 0)
+			if(Direction.x < 0)
 			{
-				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));
+				Graphics()->QuadsSetRotation(-pi/2-State.GetAttach()->m_Angle*pi*2);
+				p.x -= g_pData->m_Weapons.m_aId[iw].m_Offsetx;
+				m_pClient->m_pEffects->PowerupShine(p+vec2(32,0), vec2(32,12));
 			}
 			else
 			{
-				Graphics()->QuadsSetRotation(-pi/2+state.attach.angle*pi*2);
-				gameclient.effects->powerupshine(p-vec2(32,0), vec2(32,12));
+				Graphics()->QuadsSetRotation(-pi/2+State.GetAttach()->m_Angle*pi*2);
+				m_pClient->m_pEffects->PowerupShine(p-vec2(32,0), vec2(32,12));
 			}
-			RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
+			RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize);
 
 			// HADOKEN
-			if ((client_tick()-player.attacktick) <= (SERVER_TICK_SPEED / 6) && data->weapons.id[iw].num_sprite_muzzles)
+			if ((Client()->GameTick()-Player.m_AttackTick) <= (SERVER_TICK_SPEED / 6) && g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles)
 			{
-				int itex = rand() % data->weapons.id[iw].num_sprite_muzzles;
-				float alpha = 1.0f;
-				if (alpha > 0.0f && data->weapons.id[iw].sprite_muzzles[itex])
+				int IteX = rand() % g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles;
+				float Alpha = 1.0f;
+				if (Alpha > 0.0f && g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX])
 				{
-					vec2 dir = vec2(player_char->x,player_char->y) - vec2(prev_char->x, prev_char->y);
-					dir = normalize(dir);
-					float hadokenangle = get_angle(dir);
-					Graphics()->QuadsSetRotation(hadokenangle);
+					vec2 Dir = vec2(pPlayerChar->m_X,pPlayerChar->m_Y) - vec2(pPrevChar->m_X, pPrevChar->m_Y);
+					Dir = normalize(Dir);
+					float HadOkenAngle  = GetAngle(Dir);
+					Graphics()->QuadsSetRotation(HadOkenAngle );
 					//float offsety = -data->weapons[iw].muzzleoffsety;
-					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;
-					RenderTools()->draw_sprite(p.x, p.y, 160.0f);
+					RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX], 0);
+					vec2 DirY(-Dir.y,Dir.x);
+					p = Position;
+					float OffsetX = g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx;
+					p -= Dir * OffsetX;
+					RenderTools()->DrawSprite(p.x, p.y, 160.0f);
 				}
 			}
 		}
 		else
 		{
 			// TODO: should be an animation
-			recoil = 0;
-			float a = (client_tick()-player.attacktick+intratick)/5.0f;
+			Recoil = 0;
+			float a = (Client()->GameTick()-Player.m_AttackTick+IntraTick)/5.0f;
 			if(a < 1)
-				recoil = sinf(a*pi);
-			p = position + dir * data->weapons.id[iw].offsetx - dir*recoil*10.0f;
-			p.y += data->weapons.id[iw].offsety;
-			RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size);
+				Recoil = sinf(a*pi);
+			p = Position + Dir * g_pData->m_Weapons.m_aId[iw].m_Offsetx - Dir*Recoil*10.0f;
+			p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety;
+			RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize);
 		}
 
-		if (player.weapon == WEAPON_GUN || player.weapon == WEAPON_SHOTGUN)
+		if (Player.m_Weapon == WEAPON_GUN || Player.m_Weapon == WEAPON_SHOTGUN)
 		{
 			// check if we're firing stuff
-			if(data->weapons.id[iw].num_sprite_muzzles)//prev.attackticks)
+			if(g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles)//prev.attackticks)
 			{
-				float alpha = 0.0f;
-				int phase1tick = (client_tick() - player.attacktick);
-				if (phase1tick < (data->weapons.id[iw].muzzleduration + 3))
+				float Alpha = 0.0f;
+				int Phase1Tick = (Client()->GameTick() - Player.m_AttackTick);
+				if (Phase1Tick < (g_pData->m_Weapons.m_aId[iw].m_Muzzleduration + 3))
 				{
-					float t = ((((float)phase1tick) + intratick)/(float)data->weapons.id[iw].muzzleduration);
-					alpha = LERP(2.0, 0.0f, min(1.0f,max(0.0f,t)));
+					float t = ((((float)Phase1Tick) + IntraTick)/(float)g_pData->m_Weapons.m_aId[iw].m_Muzzleduration);
+					Alpha = mix(2.0f, 0.0f, min(1.0f,max(0.0f,t)));
 				}
 
-				int itex = rand() % data->weapons.id[iw].num_sprite_muzzles;
-				if (alpha > 0.0f && data->weapons.id[iw].sprite_muzzles[itex])
+				int IteX = rand() % g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles;
+				if (Alpha > 0.0f && g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX])
 				{
-					float offsety = -data->weapons.id[iw].muzzleoffsety;
-					RenderTools()->select_sprite(data->weapons.id[iw].sprite_muzzles[itex], direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
-					if(direction.x < 0)
-						offsety = -offsety;
+					float OffsetY = -g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsety;
+					RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[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;
+					vec2 DirY(-Dir.y,Dir.x);
+					vec2 MuzzlePos = p + Dir * g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx + DirY * OffsetY;
 
-					RenderTools()->draw_sprite(muzzlepos.x, muzzlepos.y, data->weapons.id[iw].visual_size);
+					RenderTools()->DrawSprite(MuzzlePos.x, MuzzlePos.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize);
 				}
 			}
 		}
 		Graphics()->QuadsEnd();
 
-		switch (player.weapon)
+		switch (Player.m_Weapon)
 		{
-			case WEAPON_GUN: render_hand(&render_info, p, direction, -3*pi/4, vec2(-15, 4)); break;
-			case WEAPON_SHOTGUN: render_hand(&render_info, p, direction, -pi/2, vec2(-5, 4)); break;
-			case WEAPON_GRENADE: render_hand(&render_info, p, direction, -pi/2, vec2(-4, 7)); break;
+			case WEAPON_GUN: RenderHand(&RenderInfo, p, Direction, -3*pi/4, vec2(-15, 4)); break;
+			case WEAPON_SHOTGUN: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-5, 4)); break;
+			case WEAPON_GRENADE: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-4, 7)); break;
 		}
 
 	}
 
 	// render the "shadow" tee
-	if(info.local && config.debug)
+	if(pInfo.m_Local && g_Config.m_Debug)
 	{
-		vec2 ghost_position = mix(vec2(prev_char->x, prev_char->y), vec2(player_char->x, player_char->y), client_intratick());
-		TEE_RENDER_INFO ghost = render_info;
-		ghost.color_body.a = 0.5f;
-		ghost.color_feet.a = 0.5f;
-		RenderTools()->RenderTee(&state, &ghost, player.emote, direction, ghost_position); // render ghost
+		vec2 GhostPosition = mix(vec2(pPrevChar->m_X, pPrevChar->m_Y), vec2(pPlayerChar->m_X, pPlayerChar->m_Y), Client()->IntraGameTick());
+		CTeeRenderInfo Ghost = RenderInfo;
+		Ghost.m_ColorBody.a = 0.5f;
+		Ghost.m_ColorFeet.a = 0.5f;
+		RenderTools()->RenderTee(&State, &Ghost, Player.m_Emote, Direction, GhostPosition); // render ghost
 	}
 
-	render_info.size = 64.0f; // force some settings
-	render_info.color_body.a = 1.0f;
-	render_info.color_feet.a = 1.0f;
-	RenderTools()->RenderTee(&state, &render_info, player.emote, direction, position);
+	RenderInfo.m_Size = 64.0f; // force some settings
+	RenderInfo.m_ColorBody.a = 1.0f;
+	RenderInfo.m_ColorFeet.a = 1.0f;
+	RenderTools()->RenderTee(&State, &RenderInfo, Player.m_Emote, Direction, Position);
 
-	if(player.player_state == PLAYERSTATE_CHATTING)
+	if(Player.m_PlayerState == PLAYERSTATE_CHATTING)
 	{
-		Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id);
+		Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
 		Graphics()->QuadsBegin();
-		RenderTools()->select_sprite(SPRITE_DOTDOT);
-		Graphics()->QuadsDraw(position.x + 24, position.y - 40, 64,64);
+		RenderTools()->SelectSprite(SPRITE_DOTDOT);
+		IGraphics::CQuadItem QuadItem(Position.x + 24, Position.y - 40, 64,64);
+		Graphics()->QuadsDraw(&QuadItem, 1);
 		Graphics()->QuadsEnd();
 	}
 
-	if (gameclient.clients[info.cid].emoticon_start != -1 && gameclient.clients[info.cid].emoticon_start + 2 * client_tickspeed() > client_tick())
+	if (m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart != -1 && m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart + 2 * Client()->GameTickSpeed() > Client()->GameTick())
 	{
-		Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id);
+		Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_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();
+		int SinceStart = Client()->GameTick() - m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart;
+		int FromEnd = m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart + 2 * Client()->GameTickSpeed() - Client()->GameTick();
 
 		float a = 1;
 
-		if (from_end < client_tickspeed() / 5)
-			a = from_end / (client_tickspeed() / 5.0);
+		if (FromEnd < Client()->GameTickSpeed() / 5)
+			a = FromEnd / (Client()->GameTickSpeed() / 5.0);
 
 		float h = 1;
-		if (since_start < client_tickspeed() / 10)
-			h = since_start / (client_tickspeed() / 10.0);
+		if (SinceStart < Client()->GameTickSpeed() / 10)
+			h = SinceStart / (Client()->GameTickSpeed() / 10.0);
 
-		float wiggle = 0;
-		if (since_start < client_tickspeed() / 5)
-			wiggle = since_start / (client_tickspeed() / 5.0);
+		float Wiggle = 0;
+		if (SinceStart < Client()->GameTickSpeed() / 5)
+			Wiggle = SinceStart / (Client()->GameTickSpeed() / 5.0);
 
-		float wiggle_angle = sin(5*wiggle);
+		float WiggleAngle = sinf(5*Wiggle);
 
-		Graphics()->QuadsSetRotation(pi/6*wiggle_angle);
+		Graphics()->QuadsSetRotation(pi/6*WiggleAngle);
 
 		Graphics()->SetColor(1.0f,1.0f,1.0f,a);
 		// client_datas::emoticon is an offset from the first emoticon
-		RenderTools()->select_sprite(SPRITE_OOP + gameclient.clients[info.cid].emoticon);
-		Graphics()->QuadsDraw(position.x, position.y - 23 - 32*h, 64, 64*h);
+		RenderTools()->SelectSprite(SPRITE_OOP + m_pClient->m_aClients[pInfo.m_ClientId].m_Emoticon);
+		IGraphics::CQuadItem QuadItem(Position.x, Position.y - 23 - 32*h, 64, 64*h);
+		Graphics()->QuadsDraw(&QuadItem, 1);
 		Graphics()->QuadsEnd();
 	}
 }
 
-void PLAYERS::on_render()
+void CPlayers::OnRender()
 {
 	// render other players in two passes, first pass we render the other, second pass we render our self
-	for(int p = 0; p < 2; p++)
+	for(int p = 0; p < 4; p++)
 	{
 		for(int i = 0; i < MAX_CLIENTS; i++)
 		{
 			// only render active characters
-			if(!gameclient.snap.characters[i].active)
+			if(!m_pClient->m_Snap.m_aCharacters[i].m_Active)
 				continue;
 
-			const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, i);
-			const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, i);
+			const void *pPrevInfo = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_PLAYERINFO, i);
+			const void *pInfo = Client()->SnapFindItem(IClient::SNAP_CURRENT, NETOBJTYPE_PLAYERINFO, i);
 
-			if(prev_info && info)
+			if(pPrevInfo && pInfo)
 			{
 				//
-				bool local = ((const NETOBJ_PLAYER_INFO *)info)->local !=0;
-				if(p == 0 && local) continue;
-				if(p == 1 && !local) continue;
+				bool Local = ((const CNetObj_PlayerInfo *)pInfo)->m_Local !=0;
+				if((p % 2) == 0 && Local) continue;
+				if((p % 2) == 1 && !Local) continue;
 				
-				NETOBJ_CHARACTER prev_char = gameclient.snap.characters[i].prev;
-				NETOBJ_CHARACTER cur_char = gameclient.snap.characters[i].cur;
-
-				render_player(
-						&prev_char,
-						&cur_char,
-						(const NETOBJ_PLAYER_INFO *)prev_info,
-						(const NETOBJ_PLAYER_INFO *)info
-					);
+				CNetObj_Character PrevChar = m_pClient->m_Snap.m_aCharacters[i].m_Prev;
+				CNetObj_Character CurChar = m_pClient->m_Snap.m_aCharacters[i].m_Cur;
+
+				if(p<2)
+					RenderHook(
+							&PrevChar,
+							&CurChar,
+							(const CNetObj_PlayerInfo *)pPrevInfo,
+							(const CNetObj_PlayerInfo *)pInfo
+						);
+				else
+					RenderPlayer(
+							&PrevChar,
+							&CurChar,
+							(const CNetObj_PlayerInfo *)pPrevInfo,
+							(const CNetObj_PlayerInfo *)pInfo
+						);
 			}		
 		}
 	}
diff --git a/src/game/client/components/players.h b/src/game/client/components/players.h
new file mode 100644
index 00000000..57501380
--- /dev/null
+++ b/src/game/client/components/players.h
@@ -0,0 +1,25 @@
+#ifndef GAME_CLIENT_COMPONENTS_PLAYERS_H
+#define GAME_CLIENT_COMPONENTS_PLAYERS_H
+#include <game/client/component.h>
+
+class CPlayers : public CComponent
+{	
+	void RenderHand(class CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset);
+	void RenderPlayer(
+		const class CNetObj_Character *pPrevChar,
+		const class CNetObj_Character *pPlayerChar,
+		const class CNetObj_PlayerInfo *pPrevInfo,
+		const class CNetObj_PlayerInfo *pPlayerInfo
+	);	
+	void RenderHook(
+		const CNetObj_Character *pPrevChar,
+		const CNetObj_Character *pPlayerChar,
+		const CNetObj_PlayerInfo *pPrevInfo,
+		const CNetObj_PlayerInfo *pPlayerInfo
+	);
+	
+public:
+	virtual void OnRender();
+};
+
+#endif
diff --git a/src/game/client/components/players.hpp b/src/game/client/components/players.hpp
deleted file mode 100644
index bdce91de..00000000
--- a/src/game/client/components/players.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include <game/client/component.hpp>
-
-class PLAYERS : public COMPONENT
-{	
-	void render_hand(class TEE_RENDER_INFO *info, vec2 center_pos, vec2 dir, float angle_offset, vec2 post_rot_offset);
-	void render_player(
-		const class NETOBJ_CHARACTER *prev_char,
-		const class NETOBJ_CHARACTER *player_char,
-		const class NETOBJ_PLAYER_INFO *prev_info,
-		const class NETOBJ_PLAYER_INFO *player_info
-	);	
-	
-public:
-	virtual void on_render();
-};
-
diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp
index e8db1aed..b7e8aa9a 100644
--- a/src/game/client/components/scoreboard.cpp
+++ b/src/game/client/components/scoreboard.cpp
@@ -1,36 +1,37 @@
-#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>
-#include <game/client/animstate.hpp>
-#include <game/client/render.hpp>
-#include <game/client/components/motd.hpp>
-#include "scoreboard.hpp"
-
-
-SCOREBOARD::SCOREBOARD()
+#include <engine/graphics.h>
+#include <engine/textrender.h>
+#include <engine/shared/config.h>
+#include <game/generated/protocol.h>
+#include <game/generated/client_data.h>
+#include <game/client/gameclient.h>
+#include <game/client/animstate.h>
+#include <game/client/render.h>
+#include <game/client/components/motd.h>
+#include <game/localization.h>
+#include "scoreboard.h"
+
+
+CScoreboard::CScoreboard()
 {
-	on_reset();
+	OnReset();
 }
 
-void SCOREBOARD::con_key_scoreboard(void *result, void *user_data)
+void CScoreboard::ConKeyScoreboard(IConsole::IResult *pResult, void *pUserData)
 {
-	((SCOREBOARD *)user_data)->active = console_arg_int(result, 0) != 0;
+	((CScoreboard *)pUserData)->m_Active = pResult->GetInteger(0) != 0;
 }
 
-void SCOREBOARD::on_reset()
+void CScoreboard::OnReset()
 {
-	active = false;
+	m_Active = false;
 }
 
-void SCOREBOARD::on_console_init()
+void CScoreboard::OnConsoleInit()
 {
-	MACRO_REGISTER_COMMAND("+scoreboard", "", CFGFLAG_CLIENT, con_key_scoreboard, this, "Show scoreboard");
+	Console()->Register("+scoreboard", "", CFGFLAG_CLIENT, ConKeyScoreboard, this, "Show scoreboard");
 }
 
-void SCOREBOARD::render_goals(float x, float y, float w)
+void CScoreboard::RenderGoals(float x, float y, float w)
 {
 	float h = 50.0f;
 
@@ -38,74 +39,77 @@ void SCOREBOARD::render_goals(float x, float y, float w)
 	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);
+	RenderTools()->DrawRoundRect(x-10.f, y-10.f, w, h, 10.0f);
 	Graphics()->QuadsEnd();
 
 	// render goals
 	//y = ystart+h-54;
 	float tw = 0.0f;
-	if(gameclient.snap.gameobj && gameclient.snap.gameobj->score_limit)
+	if(m_pClient->m_Snap.m_pGameobj)
 	{
-		char buf[64];
-		str_format(buf, sizeof(buf), "%s: %d", localize("Score limit"), gameclient.snap.gameobj->score_limit);
-		gfx_text(0, x+20.0f, y, 22.0f, buf, -1);
-		tw += gfx_text_width(0, 22.0f, buf, -1);
-	}
-	if(gameclient.snap.gameobj && gameclient.snap.gameobj->time_limit)
-	{
-		char buf[64];
-		str_format(buf, sizeof(buf), "%s: %d min", localize("Time limit"), gameclient.snap.gameobj->time_limit);
-		gfx_text(0, x+220.0f, y, 22.0f, buf, -1);
-		tw += gfx_text_width(0, 22.0f, buf, -1);
-	}
-	if(gameclient.snap.gameobj && gameclient.snap.gameobj->round_num && gameclient.snap.gameobj->round_current)
-	{
-		char buf[64];
-		str_format(buf, sizeof(buf), "%s %d/%d", localize("Round"), gameclient.snap.gameobj->round_current, gameclient.snap.gameobj->round_num);
-		gfx_text(0, x+450.0f, y, 22.0f, buf, -1);
-		
-	/*[48c3fd4c][game/scoreboard]: timelimit x:219.428558
-	[48c3fd4c][game/scoreboard]: round x:453.142822*/
+		if(m_pClient->m_Snap.m_pGameobj->m_ScoreLimit)
+		{
+			char aBuf[64];
+			str_format(aBuf, sizeof(aBuf), "%s: %d", Localize("Score limit"), m_pClient->m_Snap.m_pGameobj->m_ScoreLimit);
+			TextRender()->Text(0, x+20.0f, y, 22.0f, aBuf, -1);
+			tw += TextRender()->TextWidth(0, 22.0f, aBuf, -1);
+		}
+		if(m_pClient->m_Snap.m_pGameobj->m_TimeLimit)
+		{
+			char aBuf[64];
+			str_format(aBuf, sizeof(aBuf), "%s: %d min", Localize("Time limit"), m_pClient->m_Snap.m_pGameobj->m_TimeLimit);
+			TextRender()->Text(0, x+220.0f, y, 22.0f, aBuf, -1);
+			tw += TextRender()->TextWidth(0, 22.0f, aBuf, -1);
+		}
+		if(m_pClient->m_Snap.m_pGameobj->m_RoundNum && m_pClient->m_Snap.m_pGameobj->m_RoundCurrent)
+		{
+			char aBuf[64];
+			str_format(aBuf, sizeof(aBuf), "%s %d/%d", Localize("Round"), m_pClient->m_Snap.m_pGameobj->m_RoundCurrent, m_pClient->m_Snap.m_pGameobj->m_RoundNum);
+			TextRender()->Text(0, x+450.0f, y, 22.0f, aBuf, -1);
+			
+		/*[48c3fd4c][game/scoreboard]: timelimit x:219.428558
+		[48c3fd4c][game/scoreboard]: round x:453.142822*/
+		}
 	}
 }
 
-void SCOREBOARD::render_spectators(float x, float y, float w)
+void CScoreboard::RenderSpectators(float x, float y, float w)
 {
-	char buffer[1024*4];
-	int count = 0;
+	char aBuffer[1024*4];
+	int Count = 0;
 	float h = 120.0f;
 	
-	str_format(buffer, sizeof(buffer), "%s: ", localize("Spectators"));
+	str_format(aBuffer, sizeof(aBuffer), "%s: ", Localize("Spectators"));
 
 	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);
+	RenderTools()->DrawRoundRect(x-10.f, y-10.f, w, h, 10.0f);
 	Graphics()->QuadsEnd();
 	
-	for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
+	for(int i = 0; i < Client()->SnapNumItems(IClient::SNAP_CURRENT); i++)
 	{
-		SNAP_ITEM item;
-		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
+		IClient::CSnapItem Item;
+		const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item);
 
-		if(item.type == NETOBJTYPE_PLAYER_INFO)
+		if(Item.m_Type == NETOBJTYPE_PLAYERINFO)
 		{
-			const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
-			if(info->team == -1)
+			const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData;
+			if(pInfo->m_Team == -1)
 			{
-				if(count)
-					strcat(buffer, ", ");
-				strcat(buffer, gameclient.clients[info->cid].name);
-				count++;
+				if(Count)
+					str_append(aBuffer, ", ", sizeof(aBuffer));
+				str_append(aBuffer, m_pClient->m_aClients[pInfo->m_ClientId].m_aName, sizeof(aBuffer));
+				Count++;
 			}
 		}
 	}
 	
-	gfx_text(0, x+10, y, 32, buffer, (int)w-20);
+	TextRender()->Text(0, x+10, y, 32, aBuffer, (int)w-20);
 }
 
-void SCOREBOARD::render_scoreboard(float x, float y, float w, int team, const char *title)
+void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const char *pTitle)
 {
 	//float ystart = y;
 	float h = 750.0f;
@@ -114,202 +118,203 @@ void SCOREBOARD::render_scoreboard(float x, float y, float w, int team, const ch
 	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);
+	RenderTools()->DrawRoundRect(x-10.f, y-10.f, w, h, 17.0f);
 	Graphics()->QuadsEnd();
 
 	// render title
-	if(!title)
+	if(!pTitle)
 	{
-		if(gameclient.snap.gameobj->game_over)
-			title = localize("Game over");
+		if(m_pClient->m_Snap.m_pGameobj->m_GameOver)
+			pTitle = Localize("Game over");
 		else
-			title = localize("Score board");
+			pTitle = Localize("Score board");
 	}
 
-	float tw = gfx_text_width(0, 48, title, -1);
+	float tw = TextRender()->TextWidth(0, 48, pTitle, -1);
 
-	if(team == -1)
+	if(Team == -1)
 	{
-		gfx_text(0, x+w/2-tw/2, y, 48, title, -1);
+		TextRender()->Text(0, x+w/2-tw/2, y, 48, pTitle, -1);
 	}
 	else
 	{
-		gfx_text(0, x+10, y, 48, title, -1);
+		TextRender()->Text(0, x+10, y, 48, pTitle, -1);
 
-		if(gameclient.snap.gameobj)
+		if(m_pClient->m_Snap.m_pGameobj)
 		{
-			char buf[128];
-			int score = team ? gameclient.snap.gameobj->teamscore_blue : gameclient.snap.gameobj->teamscore_red;
-			str_format(buf, sizeof(buf), "%d", score);
-			tw = gfx_text_width(0, 48, buf, -1);
-			gfx_text(0, x+w-tw-30, y, 48, buf, -1);
+			char aBuf[128];
+			int Score = Team ? m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue : m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed;
+			str_format(aBuf, sizeof(aBuf), "%d", Score);
+			tw = TextRender()->TextWidth(0, 48, aBuf, -1);
+			TextRender()->Text(0, x+w-tw-30, y, 48, aBuf, -1);
 		}
 	}
 
 	y += 54.0f;
 
 	// find players
-	const NETOBJ_PLAYER_INFO *players[MAX_CLIENTS] = {0};
-	int num_players = 0;
-	for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
+	const CNetObj_PlayerInfo *paPlayers[MAX_CLIENTS] = {0};
+	int NumPlayers = 0;
+	for(int i = 0; i < Client()->SnapNumItems(IClient::SNAP_CURRENT); i++)
 	{
-		SNAP_ITEM item;
-		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
+		IClient::CSnapItem Item;
+		const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item);
 
-		if(item.type == NETOBJTYPE_PLAYER_INFO)
+		if(Item.m_Type == NETOBJTYPE_PLAYERINFO)
 		{
-			const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
-			if(info->team == team)
+			const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData;
+			if(pInfo->m_Team == Team)
 			{
-				players[num_players] = info;
-				num_players++;
+				paPlayers[NumPlayers] = pInfo;
+				NumPlayers++;
 			}
 		}
 	}
 
 	// sort players
-	for(int k = 0; k < num_players; k++) // ffs, bubblesort
+	for(int k = 0; k < NumPlayers; k++) // ffs, bubblesort
 	{
-		for(int i = 0; i < num_players-k-1; i++)
+		for(int i = 0; i < NumPlayers-k-1; i++)
 		{
-			if(players[i]->score < players[i+1]->score)
+			if(paPlayers[i]->m_Score < paPlayers[i+1]->m_Score)
 			{
-				const NETOBJ_PLAYER_INFO *tmp = players[i];
-				players[i] = players[i+1];
-				players[i+1] = tmp;
+				const CNetObj_PlayerInfo *pTmp = paPlayers[i];
+				paPlayers[i] = paPlayers[i+1];
+				paPlayers[i+1] = pTmp;
 			}
 		}
 	}
 
 	// render headlines
-	gfx_text(0, x+10, y, 24.0f, localize("Score"), -1);
-	gfx_text(0, x+125, y, 24.0f, localize("Name"), -1);
-	gfx_text(0, x+w-70, y, 24.0f, localize("Ping"), -1);
+	TextRender()->Text(0, x+10, y, 24.0f, Localize("Score"), -1);
+	TextRender()->Text(0, x+125, y, 24.0f, Localize("Name"), -1);
+	TextRender()->Text(0, x+w-70, y, 24.0f, Localize("Ping"), -1);
 	y += 29.0f;
 
-	float font_size = 35.0f;
-	float line_height = 50.0f;
-	float tee_sizemod = 1.0f;
-	float tee_offset = 0.0f;
+	float FontSize = 35.0f;
+	float LineHeight = 50.0f;
+	float TeeSizeMod = 1.0f;
+	float TeeOffset = 0.0f;
 	
-	if(num_players > 13)
+	if(NumPlayers > 13)
 	{
-		font_size = 30.0f;
-		line_height = 40.0f;
-		tee_sizemod = 0.8f;
-		tee_offset = -5.0f;
+		FontSize = 30.0f;
+		LineHeight = 40.0f;
+		TeeSizeMod = 0.8f;
+		TeeOffset = -5.0f;
 	}
 	
 	// render player scores
-	for(int i = 0; i < num_players; i++)
+	for(int i = 0; i < NumPlayers; i++)
 	{
-		const NETOBJ_PLAYER_INFO *info = players[i];
+		const CNetObj_PlayerInfo *pInfo = paPlayers[i];
 
 		// make sure that we render the correct team
 
-		char buf[128];
-		if(info->local)
+		char aBuf[128];
+		if(pInfo->m_Local)
 		{
 			// background so it's easy to find the local player
 			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);
+			RenderTools()->DrawRoundRect(x, y, w-20, LineHeight*0.95f, 17.0f);
 			Graphics()->QuadsEnd();
 		}
 
-		str_format(buf, sizeof(buf), "%4d", info->score);
-		gfx_text(0, x+60-gfx_text_width(0, font_size,buf,-1), y, font_size, buf, -1);
+		str_format(aBuf, sizeof(aBuf), "%4d", pInfo->m_Score);
+		TextRender()->Text(0, x+60-TextRender()->TextWidth(0, FontSize,aBuf,-1), y, FontSize, aBuf, -1);
 		
-		gfx_text(0, x+128, y, font_size, gameclient.clients[info->cid].name, -1);
+		TextRender()->Text(0, x+128, y, FontSize, m_pClient->m_aClients[pInfo->m_ClientId].m_aName, -1);
 
-		str_format(buf, sizeof(buf), "%4d", info->latency);
-		float tw = gfx_text_width(0, font_size, buf, -1);
-		gfx_text(0, x+w-tw-35, y, font_size, buf, -1);
+		str_format(aBuf, sizeof(aBuf), "%4d", pInfo->m_Latency);
+		float tw = TextRender()->TextWidth(0, FontSize, aBuf, -1);
+		TextRender()->Text(0, x+w-tw-35, y, FontSize, aBuf, -1);
 
 		// render avatar
-		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))
+		if((m_pClient->m_Snap.m_paFlags[0] && m_pClient->m_Snap.m_paFlags[0]->m_CarriedBy == pInfo->m_ClientId) ||
+			(m_pClient->m_Snap.m_paFlags[1] && m_pClient->m_Snap.m_paFlags[1]->m_CarriedBy == pInfo->m_ClientId))
 		{
 			Graphics()->BlendNormal();
-			Graphics()->TextureSet(data->images[IMAGE_GAME].id);
+			Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 			Graphics()->QuadsBegin();
 
-			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);
+			if(pInfo->m_Team == 0) RenderTools()->SelectSprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
+			else RenderTools()->SelectSprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
 			
 			float size = 64.0f;
-			Graphics()->QuadsDrawTL(x+55, y-15, size/2, size);
+			IGraphics::CQuadItem QuadItem(x+55, y-15, size/2, size);
+			Graphics()->QuadsDrawTL(&QuadItem, 1);
 			Graphics()->QuadsEnd();
 		}
 		
-		TEE_RENDER_INFO teeinfo = gameclient.clients[info->cid].render_info;
-		teeinfo.size *= tee_sizemod;
-		RenderTools()->RenderTee(ANIMSTATE::get_idle(), &teeinfo, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28+tee_offset));
+		CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientId].m_RenderInfo;
+		TeeInfo.m_Size *= TeeSizeMod;
+		RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28+TeeOffset));
 
 		
-		y += line_height;
+		y += LineHeight;
 	}
 }
 
-void SCOREBOARD::on_render()
+void CScoreboard::OnRender()
 {
-	bool do_scoreboard = false;
+	bool DoScoreBoard = false;
 
 	// if we activly wanna look on the scoreboard	
-	if(active)
-		do_scoreboard = true;
+	if(m_Active)
+		DoScoreBoard = true;
 		
-	if(gameclient.snap.local_info && gameclient.snap.local_info->team != -1)
+	if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pLocalInfo->m_Team != -1)
 	{
 		// we are not a spectator, check if we are ead
-		if(!gameclient.snap.local_character || gameclient.snap.local_character->health < 0)
-			do_scoreboard = true;
+		if(!m_pClient->m_Snap.m_pLocalCharacter || m_pClient->m_Snap.m_pLocalCharacter->m_Health < 0)
+			DoScoreBoard = true;
 	}
 
 	// if we the game is over
-	if(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over)
-		do_scoreboard = true;
+	if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)
+		DoScoreBoard = true;
 		
-	if(!do_scoreboard)
+	if(!DoScoreBoard)
 		return;
 		
 	// if the score board is active, then we should clear the motd message aswell
-	if(active)
-		gameclient.motd->clear();
+	if(m_Active)
+		m_pClient->m_pMotd->Clear();
 	
 
-	float width = 400*3.0f*Graphics()->ScreenAspect();
-	float height = 400*3.0f;
+	float Width = 400*3.0f*Graphics()->ScreenAspect();
+	float Height = 400*3.0f;
 	
-	Graphics()->MapScreen(0, 0, width, height);
+	Graphics()->MapScreen(0, 0, Width, Height);
 
 	float w = 650.0f;
 
-	if(gameclient.snap.gameobj && !(gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS))
+	if(m_pClient->m_Snap.m_pGameobj && !(m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS))
 	{
-		render_scoreboard(width/2-w/2, 150.0f, w, 0, 0);
+		RenderScoreboard(Width/2-w/2, 150.0f, w, 0, 0);
 		//render_scoreboard(gameobj, 0, 0, -1, 0);
 	}
 	else
 	{
 			
-		if(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over)
+		if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)
 		{
-			const char *text = localize("Draw!");
-			if(gameclient.snap.gameobj->teamscore_red > gameclient.snap.gameobj->teamscore_blue)
-				text = localize("Red team wins!");
-			else if(gameclient.snap.gameobj->teamscore_blue > gameclient.snap.gameobj->teamscore_red)
-				text = localize("Blue team wins!");
+			const char *pText = Localize("Draw!");
+			if(m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed > m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue)
+				pText = Localize("Red team wins!");
+			else if(m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue > m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed)
+				pText = Localize("Blue team wins!");
 				
-			float w = gfx_text_width(0, 92.0f, text, -1);
-			gfx_text(0, width/2-w/2, 45, 92.0f, text, -1);
+			float w = TextRender()->TextWidth(0, 92.0f, pText, -1);
+			TextRender()->Text(0, Width/2-w/2, 45, 92.0f, pText, -1);
 		}
 		
-		render_scoreboard(width/2-w-20, 150.0f, w, 0, localize("Red team"));
-		render_scoreboard(width/2 + 20, 150.0f, w, 1, localize("Blue team"));
+		RenderScoreboard(Width/2-w-20, 150.0f, w, 0, Localize("Red team"));
+		RenderScoreboard(Width/2 + 20, 150.0f, w, 1, Localize("Blue team"));
 	}
 
-	render_goals(width/2-w/2, 150+750+25, w);
-	render_spectators(width/2-w/2, 150+750+25+50+25, w);
+	RenderGoals(Width/2-w/2, 150+750+25, w);
+	RenderSpectators(Width/2-w/2, 150+750+25+50+25, w);
 }
diff --git a/src/game/client/components/scoreboard.h b/src/game/client/components/scoreboard.h
new file mode 100644
index 00000000..5aa2f0a7
--- /dev/null
+++ b/src/game/client/components/scoreboard.h
@@ -0,0 +1,22 @@
+#ifndef GAME_CLIENT_COMPONENTS_SCOREBOARD_H
+#define GAME_CLIENT_COMPONENTS_SCOREBOARD_H
+#include <game/client/component.h>
+
+class CScoreboard : public CComponent
+{
+	void RenderGoals(float x, float y, float w);
+	void RenderSpectators(float x, float y, float w);
+	void RenderScoreboard(float x, float y, float w, int Team, const char *pTitle);
+
+	static void ConKeyScoreboard(IConsole::IResult *pResult, void *pUserData);
+	
+	bool m_Active;
+	
+public:
+	CScoreboard();
+	virtual void OnReset();
+	virtual void OnConsoleInit();
+	virtual void OnRender();
+};
+
+#endif
diff --git a/src/game/client/components/scoreboard.hpp b/src/game/client/components/scoreboard.hpp
deleted file mode 100644
index 222dab9d..00000000
--- a/src/game/client/components/scoreboard.hpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <game/client/component.hpp>
-
-class SCOREBOARD : public COMPONENT
-{
-	void render_goals(float x, float y, float w);
-	void render_spectators(float x, float y, float w);
-	void render_scoreboard(float x, float y, float w, int team, const char *title);
-
-	static void con_key_scoreboard(void *result, void *user_data);
-	
-	bool active;
-	
-public:
-	SCOREBOARD();
-	virtual void on_reset();
-	virtual void on_console_init();
-	virtual void on_render();
-};
-
diff --git a/src/game/client/components/skins.cpp b/src/game/client/components/skins.cpp
index ad3607a1..582adb10 100644
--- a/src/game/client/components/skins.cpp
+++ b/src/game/client/components/skins.cpp
@@ -1,153 +1,150 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-#include <string.h>
-#include <stdio.h>
+// copyright (c) 2007 magnus auvinen, see licence.txt for more info
 #include <math.h>
 
 #include <base/system.h>
-#include <base/math.hpp>
+#include <base/math.h>
 
-#include <engine/client/graphics.h>
-#include <engine/e_client_interface.h>
+#include <engine/graphics.h>
+#include <engine/storage.h>
+#include <engine/shared/engine.h>
 
-#include <engine/e_engine.h>
+#include "skins.h"
 
-#include "skins.hpp"
-
-SKINS::SKINS()
+CSkins::CSkins()
 {
-	num_skins = 0;
+	m_NumSkins = 0;
 }
 
-void SKINS::skinscan(const char *name, int is_dir, void *user)
+void CSkins::SkinScan(const char *pName, int IsDir, void *pUser)
 {
-	SKINS *self = (SKINS *)user;
-	int l = strlen(name);
-	if(l < 4 || is_dir || self->num_skins == MAX_SKINS)
+	CSkins *pSelf = (CSkins *)pUser;
+	int l = str_length(pName);
+	if(l < 4 || IsDir || pSelf->m_NumSkins == MAX_SKINS)
 		return;
-	if(strcmp(name+l-4, ".png") != 0)
+	if(str_comp(pName+l-4, ".png") != 0)
 		return;
 		
-	char buf[512];
-	str_format(buf, sizeof(buf), "skins/%s", name);
-	IMAGE_INFO info;
-	if(!self->Graphics()->LoadPNG(&info, buf))
+	char aBuf[512];
+	str_format(aBuf, sizeof(aBuf), "skins/%s", pName);
+	CImageInfo Info;
+	if(!pSelf->Graphics()->LoadPNG(&Info, aBuf))
 	{
-		dbg_msg("game", "failed to load skin from %s", name);
+		dbg_msg("game", "failed to load skin from %s", pName);
 		return;
 	}
 	
-	self->skins[self->num_skins].org_texture = self->Graphics()->LoadTextureRaw(info.width, info.height, info.format, info.data, info.format, 0);
+	pSelf->m_aSkins[pSelf->m_NumSkins].m_OrgTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
 	
-	int body_size = 96; // body size
-	unsigned char *d = (unsigned char *)info.data;
-	int pitch = info.width*4;
+	int BodySize = 96; // body size
+	unsigned char *d = (unsigned char *)Info.m_pData;
+	int Pitch = Info.m_Width*4;
 
 	// dig out blood color
 	{
-		int colors[3] = {0};
-		for(int y = 0; y < body_size; y++)
-			for(int x = 0; x < body_size; x++)
+		int aColors[3] = {0};
+		for(int y = 0; y < BodySize; y++)
+			for(int x = 0; x < BodySize; x++)
 			{
-				if(d[y*pitch+x*4+3] > 128)
+				if(d[y*Pitch+x*4+3] > 128)
 				{
-					colors[0] += d[y*pitch+x*4+0];
-					colors[1] += d[y*pitch+x*4+1];
-					colors[2] += d[y*pitch+x*4+2];
+					aColors[0] += d[y*Pitch+x*4+0];
+					aColors[1] += d[y*Pitch+x*4+1];
+					aColors[2] += d[y*Pitch+x*4+2];
 				}
 			}
 			
-		self->skins[self->num_skins].blood_color = normalize(vec3(colors[0], colors[1], colors[2]));
+		pSelf->m_aSkins[pSelf->m_NumSkins].m_BloodColor = normalize(vec3(aColors[0], aColors[1], aColors[2]));
 	}
 	
 	// create colorless version
-	int step = info.format == IMG_RGBA ? 4 : 3;
+	int Step = Info.m_Format == CImageInfo::FORMAT_RGBA ? 4 : 3;
 
 	// make the texture gray scale
-	for(int i = 0; i < info.width*info.height; i++)
+	for(int i = 0; i < Info.m_Width*Info.m_Height; i++)
 	{
-		int v = (d[i*step]+d[i*step+1]+d[i*step+2])/3;
-		d[i*step] = v;
-		d[i*step+1] = v;
-		d[i*step+2] = v;
+		int v = (d[i*Step]+d[i*Step+1]+d[i*Step+2])/3;
+		d[i*Step] = v;
+		d[i*Step+1] = v;
+		d[i*Step+2] = v;
 	}
 
 	
 	if(1)
 	{
-		int freq[256] = {0};
-		int org_weight = 0;
-		int new_weight = 192;
+		int Freq[256] = {0};
+		int OrgWeight = 0;
+		int NewWeight = 192;
 		
 		// find most common frequence
-		for(int y = 0; y < body_size; y++)
-			for(int x = 0; x < body_size; x++)
+		for(int y = 0; y < BodySize; y++)
+			for(int x = 0; x < BodySize; x++)
 			{
-				if(d[y*pitch+x*4+3] > 128)
-					freq[d[y*pitch+x*4]]++;
+				if(d[y*Pitch+x*4+3] > 128)
+					Freq[d[y*Pitch+x*4]]++;
 			}
 		
 		for(int i = 1; i < 256; i++)
 		{
-			if(freq[org_weight] < freq[i])
-				org_weight = i;
+			if(Freq[OrgWeight] < Freq[i])
+				OrgWeight = i;
 		}
 
 		// reorder
-		int inv_org_weight = 255-org_weight;
-		int inv_new_weight = 255-new_weight;
-		for(int y = 0; y < body_size; y++)
-			for(int x = 0; x < body_size; x++)
+		int InvOrgWeight = 255-OrgWeight;
+		int InvNewWeight = 255-NewWeight;
+		for(int y = 0; y < BodySize; y++)
+			for(int x = 0; x < BodySize; x++)
 			{
-				int v = d[y*pitch+x*4];
-				if(v <= org_weight)
-					v = (int)(((v/(float)org_weight) * new_weight));
+				int v = d[y*Pitch+x*4];
+				if(v <= OrgWeight)
+					v = (int)(((v/(float)OrgWeight) * NewWeight));
 				else
-					v = (int)(((v-org_weight)/(float)inv_org_weight)*inv_new_weight + new_weight);
-				d[y*pitch+x*4] = v;
-				d[y*pitch+x*4+1] = v;
-				d[y*pitch+x*4+2] = v;
+					v = (int)(((v-OrgWeight)/(float)InvOrgWeight)*InvNewWeight + NewWeight);
+				d[y*Pitch+x*4] = v;
+				d[y*Pitch+x*4+1] = v;
+				d[y*Pitch+x*4+2] = v;
 			}
 	}
 	
-	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);
+	pSelf->m_aSkins[pSelf->m_NumSkins].m_ColorTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
+	mem_free(Info.m_pData);
 
 	// set skin data	
-	strncpy(self->skins[self->num_skins].name, name, min((int)sizeof(self->skins[self->num_skins].name),l-4));
-	dbg_msg("game", "load skin %s", self->skins[self->num_skins].name);
-	self->num_skins++;
+	str_copy(pSelf->m_aSkins[pSelf->m_NumSkins].m_aName, pName, min((int)sizeof(pSelf->m_aSkins[pSelf->m_NumSkins].m_aName),l-3));
+	dbg_msg("game", "load skin %s", pSelf->m_aSkins[pSelf->m_NumSkins].m_aName);
+	pSelf->m_NumSkins++;
 }
 
 
-void SKINS::init()
+void CSkins::Init()
 {
 	// load skins
-	num_skins = 0;
-	engine_listdir(LISTDIRTYPE_ALL, "skins", skinscan, this);
+	m_NumSkins = 0;
+	Storage()->ListDirectory(IStorage::TYPE_ALL, "skins", SkinScan, this);
 }
 
-int SKINS::num()
+int CSkins::Num()
 {
-	return num_skins;	
+	return m_NumSkins;	
 }
 
-const SKINS::SKIN *SKINS::get(int index)
+const CSkins::CSkin *CSkins::Get(int Index)
 {
-	return &skins[index%num_skins];
+	return &m_aSkins[Index%m_NumSkins];
 }
 
-int SKINS::find(const char *name)
+int CSkins::Find(const char *pName)
 {
-	for(int i = 0; i < num_skins; i++)
+	for(int i = 0; i < m_NumSkins; i++)
 	{
-		if(strcmp(skins[i].name, name) == 0)
+		if(str_comp(m_aSkins[i].m_aName, pName) == 0)
 			return i;
 	}
 	return -1;
 }
 
 // these converter functions were nicked from some random internet pages
-static float hue_to_rgb(float v1, float v2, float h)
+static float HueToRgb(float v1, float v2, float h)
 {
    if(h < 0) h += 1;
    if(h > 1) h -= 1;
@@ -157,16 +154,16 @@ static float hue_to_rgb(float v1, float v2, float h)
    return v1;
 }
 
-static vec3 hsl_to_rgb(vec3 in)
+static vec3 HslToRgb(vec3 in)
 {
 	float v1, v2;
-	vec3 out;
+	vec3 Out;
 
 	if(in.s == 0)
 	{
-		out.r = in.l;
-		out.g = in.l;
-		out.b = in.l;
+		Out.r = in.l;
+		Out.g = in.l;
+		Out.b = in.l;
 	}
 	else
 	{
@@ -177,16 +174,16 @@ static vec3 hsl_to_rgb(vec3 in)
 
 		v1 = 2 * in.l - v2;
 
-		out.r = hue_to_rgb(v1, v2, in.h + (1.0f/3.0f));
-		out.g = hue_to_rgb(v1, v2, in.h);
-		out.b = hue_to_rgb(v1, v2, in.h - (1.0f/3.0f));
+		Out.r = HueToRgb(v1, v2, in.h + (1.0f/3.0f));
+		Out.g = HueToRgb(v1, v2, in.h);
+		Out.b = HueToRgb(v1, v2, in.h - (1.0f/3.0f));
 	} 
 
-	return out;
+	return Out;
 }
 
-vec4 SKINS::get_color(int v)
+vec4 CSkins::GetColor(int v)
 {
-	vec3 r = hsl_to_rgb(vec3((v>>16)/255.0f, ((v>>8)&0xff)/255.0f, 0.5f+(v&0xff)/255.0f*0.5f));
+	vec3 r = HslToRgb(vec3(((v>>16)&0xff)/255.0f, ((v>>8)&0xff)/255.0f, 0.5f+(v&0xff)/255.0f*0.5f));
 	return vec4(r.r, r.g, r.b, 1.0f);
 }
diff --git a/src/game/client/components/skins.h b/src/game/client/components/skins.h
new file mode 100644
index 00000000..f733140f
--- /dev/null
+++ b/src/game/client/components/skins.h
@@ -0,0 +1,39 @@
+#ifndef GAME_CLIENT_COMPONENTS_SKINS_H
+#define GAME_CLIENT_COMPONENTS_SKINS_H
+#include <base/vmath.h>
+#include <game/client/component.h>
+
+class CSkins : public CComponent
+{
+public:
+	// do this better and nicer
+	struct CSkin
+	{
+		int m_OrgTexture;
+		int m_ColorTexture;
+		char m_aName[31];
+		char m_aTerm[1];
+		vec3 m_BloodColor;
+	} ;
+
+	CSkins();
+	
+	void Init();
+	
+	vec4 GetColor(int v);
+	int Num();
+	const CSkin *Get(int Index);
+	int Find(const char *pName);
+	
+private:
+	enum
+	{
+		MAX_SKINS=256,
+	};
+
+	CSkin m_aSkins[MAX_SKINS];
+	int m_NumSkins;
+
+	static void SkinScan(const char *pName, int IsDir, void *pUser);
+};
+#endif
diff --git a/src/game/client/components/skins.hpp b/src/game/client/components/skins.hpp
deleted file mode 100644
index 078fd71d..00000000
--- a/src/game/client/components/skins.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <base/vmath.hpp>
-#include <game/client/component.hpp>
-
-class SKINS : public COMPONENT
-{
-public:
-	// do this better and nicer
-	typedef struct 
-	{
-		int org_texture;
-		int color_texture;
-		char name[31];
-		char term[1];
-		vec3 blood_color;
-	} SKIN;
-
-	SKINS();
-	
-	void init();
-	
-	vec4 get_color(int v);
-	int num();
-	const SKIN *get(int index);
-	int find(const char *name);
-	
-private:
-	enum
-	{
-		MAX_SKINS=256,
-	};
-
-	SKIN skins[MAX_SKINS];
-	int num_skins;
-
-	static void skinscan(const char *name, int is_dir, void *user);
-};
diff --git a/src/game/client/components/sounds.cpp b/src/game/client/components/sounds.cpp
index dfa7e31b..84e45efa 100644
--- a/src/game/client/components/sounds.cpp
+++ b/src/game/client/components/sounds.cpp
@@ -1,54 +1,91 @@
-#include <engine/e_client_interface.h>
-#include <game/generated/gc_data.hpp>
-#include <game/client/gameclient.hpp>
-#include <game/client/components/camera.hpp>
-#include "sounds.hpp"
+#include <engine/sound.h>
+#include <game/generated/client_data.h>
+#include <game/client/gameclient.h>
+#include <game/client/components/camera.h>
+#include "sounds.h"
 
-void SOUNDS::on_init()
+void CSounds::OnInit()
 {
 	// setup sound channels
-	snd_set_channel(SOUNDS::CHN_GUI, 1.0f, 0.0f);
-	snd_set_channel(SOUNDS::CHN_MUSIC, 1.0f, 0.0f);
-	snd_set_channel(SOUNDS::CHN_WORLD, 0.9f, 1.0f);
-	snd_set_channel(SOUNDS::CHN_GLOBAL, 1.0f, 0.0f);
+	Sound()->SetChannel(CSounds::CHN_GUI, 1.0f, 0.0f);
+	Sound()->SetChannel(CSounds::CHN_MUSIC, 1.0f, 0.0f);
+	Sound()->SetChannel(CSounds::CHN_WORLD, 0.9f, 1.0f);
+	Sound()->SetChannel(CSounds::CHN_GLOBAL, 1.0f, 0.0f);
 
-	snd_set_listener_pos(0.0f, 0.0f);
+	Sound()->SetListenerPos(0.0f, 0.0f);
+
+	ClearQueue();
+}
+
+void CSounds::OnReset()
+{
+	Sound()->StopAll();
+	ClearQueue();
 }
 
-void SOUNDS::on_render()
+void CSounds::OnRender()
 {
 	// set listner pos
-	snd_set_listener_pos(gameclient.camera->center.x, gameclient.camera->center.y);
+	Sound()->SetListenerPos(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y);
+
+	// play sound from queue
+	if(m_QueuePos > 0)
+	{
+		int64 Now =  time_get();
+		if(m_QueueWaitTime <= Now)
+		{
+			Play(CHN_GLOBAL, m_aQueue[0], 1.0f, vec2(0,0));
+			m_QueueWaitTime = Now+time_freq()*3/10; // wait 300ms before playing the next one
+			if(--m_QueuePos > 0)
+				mem_move(m_aQueue, m_aQueue+1, m_QueuePos*sizeof(int));
+		}
+	}
 }
 
-void SOUNDS::play_and_record(int chn, int setid, float vol, vec2 pos)
+void CSounds::ClearQueue()
 {
-	NETMSG_SV_SOUNDGLOBAL msg;
-	msg.soundid = setid;
-	msg.pack(MSGFLAG_NOSEND|MSGFLAG_RECORD);
-	client_send_msg();
+	mem_zero(m_aQueue, sizeof(m_aQueue));
+	m_QueuePos = 0;
+	m_QueueWaitTime = time_get();
+}
+
+void CSounds::Enqueue(int SetId)
+{
+	// add sound to the queue
+	if(m_QueuePos < QUEUE_SIZE)
+		m_aQueue[m_QueuePos++] = SetId;
+}
+
+void CSounds::PlayAndRecord(int Chn, int SetId, float Vol, vec2 Pos)
+{
+	CNetMsg_Sv_SoundGlobal Msg;
+	Msg.m_Soundid = SetId;
+	Client()->SendPackMsg(&Msg, MSGFLAG_NOSEND|MSGFLAG_RECORD);
 	
-	play(chn, setid, vol, pos);
+	Play(Chn, SetId, Vol, Pos);
 }
 
-void SOUNDS::play(int chn, int setid, float vol, vec2 pos)
+void CSounds::Play(int Chn, int SetId, float Vol, vec2 Pos)
 {
-	SOUNDSET *set = &data->sounds[setid];
+	if(SetId < 0 || SetId >= g_pData->m_NumSounds)
+		return;
+
+	SOUNDSET *pSet = &g_pData->m_aSounds[SetId];
 
-	if(!set->num_sounds)
+	if(!pSet->m_NumSounds)
 		return;
 
-	if(set->num_sounds == 1)
+	if(pSet->m_NumSounds == 1)
 	{
-		snd_play_at(chn, set->sounds[0].id, 0, pos.x, pos.y);
+		Sound()->PlayAt(Chn, pSet->m_aSounds[0].m_Id, 0, Pos.x, Pos.y);
 		return;
 	}
 
 	// play a random one
 	int id;
 	do {
-		id = rand() % set->num_sounds;
-	} while(id == set->last);
-	snd_play_at(chn, set->sounds[id].id, 0, pos.x, pos.y);
-	set->last = id;
+		id = rand() % pSet->m_NumSounds;
+	} while(id == pSet->m_Last);
+	Sound()->PlayAt(Chn, pSet->m_aSounds[id].m_Id, 0, Pos.x, Pos.y);
+	pSet->m_Last = id;
 }
diff --git a/src/game/client/components/sounds.h b/src/game/client/components/sounds.h
new file mode 100644
index 00000000..ce74b85e
--- /dev/null
+++ b/src/game/client/components/sounds.h
@@ -0,0 +1,36 @@
+#ifndef GAME_CLIENT_COMPONENTS_SOUNDS_H
+#define GAME_CLIENT_COMPONENTS_SOUNDS_H
+#include <game/client/component.h>
+
+class CSounds : public CComponent
+{
+	enum
+	{
+		QUEUE_SIZE = 32,
+	};
+	int m_aQueue[QUEUE_SIZE];
+	int m_QueuePos;
+	int64 m_QueueWaitTime;
+
+public:
+	// sound channels
+	enum
+	{
+		CHN_GUI=0,
+		CHN_MUSIC,
+		CHN_WORLD,
+		CHN_GLOBAL,
+	};
+
+	virtual void OnInit();
+	virtual void OnReset();
+	virtual void OnRender();
+	
+	void ClearQueue();
+	void Enqueue(int SetId);
+	void Play(int Channel, int SetId, float Vol, vec2 Pos);
+	void PlayAndRecord(int Channel, int SetId, float Vol, vec2 Pos);
+};
+
+
+#endif
diff --git a/src/game/client/components/sounds.hpp b/src/game/client/components/sounds.hpp
deleted file mode 100644
index 95ddb1ec..00000000
--- a/src/game/client/components/sounds.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <game/client/component.hpp>
-
-class SOUNDS : public COMPONENT
-{
-public:
-	// sound channels
-	enum
-	{
-		CHN_GUI=0,
-		CHN_MUSIC,
-		CHN_WORLD,
-		CHN_GLOBAL,
-	};
-
-	virtual void on_init();
-	virtual void on_render();
-	
-	void play(int chn, int setid, float vol, vec2 pos);
-	void play_and_record(int chn, int setid, float vol, vec2 pos);
-};
-
-
diff --git a/src/game/client/components/voting.cpp b/src/game/client/components/voting.cpp
index dcf5c954..17c0fe31 100644
--- a/src/game/client/components/voting.cpp
+++ b/src/game/client/components/voting.cpp
@@ -1,200 +1,219 @@
-#include <engine/e_client_interface.h>
-#include <game/generated/g_protocol.hpp>
-#include <base/vmath.hpp>
-#include <game/client/render.hpp>
-//#include <game/client/gameclient.hpp>
-#include "voting.hpp"
-
-void VOTING::con_callvote(void *result, void *user_data)
+#include <engine/shared/config.h>
+
+#include <game/generated/protocol.h>
+#include <base/vmath.h>
+#include <game/client/render.h>
+//#include <game/client/gameclient.h>
+#include "voting.h"
+
+void CVoting::ConCallvote(IConsole::IResult *pResult, void *pUserData)
+{
+	CVoting *pSelf = (CVoting*)pUserData;
+	pSelf->Callvote(pResult->GetString(0), pResult->GetString(1));
+}
+
+void CVoting::ConVote(IConsole::IResult *pResult, void *pUserData)
+{
+	CVoting *pSelf = (CVoting *)pUserData;
+	if(str_comp_nocase(pResult->GetString(0), "yes") == 0)
+		pSelf->Vote(1);
+	else if(str_comp_nocase(pResult->GetString(0), "no") == 0)
+		pSelf->Vote(-1);
+}
+
+void CVoting::Callvote(const char *pType, const char *pValue)
 {
-	VOTING *self = (VOTING*)user_data;
-	self->callvote(console_arg_string(result, 0), console_arg_string(result, 1));
+	CNetMsg_Cl_CallVote Msg = {0};
+	Msg.m_Type = pType;
+	Msg.m_Value = pValue;
+	Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
 }
 
-void VOTING::con_vote(void *result, void *user_data)
+void CVoting::CallvoteKick(int ClientId)
 {
-	VOTING *self = (VOTING *)user_data;
-	if(str_comp_nocase(console_arg_string(result, 0), "yes") == 0)
-		self->vote(1);
-	else if(str_comp_nocase(console_arg_string(result, 0), "no") == 0)
-		self->vote(-1);
+	char Buf[32];
+	str_format(Buf, sizeof(Buf), "%d", ClientId);
+	Callvote("kick", Buf);
 }
 
-void VOTING::callvote(const char *type, const char *value)
+void CVoting::CallvoteOption(int OptionId)
 {
-	NETMSG_CL_CALLVOTE msg = {0};
-	msg.type = type;
-	msg.value = value;
-	msg.pack(MSGFLAG_VITAL);
-	client_send_msg();
+	CVoteOption *pOption = m_pFirst;
+	while(pOption && OptionId >= 0)
+	{
+		if(OptionId == 0)
+		{
+			Callvote("option", pOption->m_aCommand);
+			break;
+		}
+		
+		OptionId--;
+		pOption = pOption->m_pNext;
+	}
 }
 
-void VOTING::callvote_kick(int client_id)
+void CVoting::ForcevoteKick(int ClientId)
 {
-	char buf[32];
-	str_format(buf, sizeof(buf), "%d", client_id);
-	callvote("kick", buf);
+	char Buf[32];
+	str_format(Buf, sizeof(Buf), "kick %d", ClientId);
+	Client()->Rcon(Buf);
 }
 
-void VOTING::callvote_option(int option_id)
+void CVoting::ForcevoteOption(int OptionId)
 {
-	VOTEOPTION *option = this->first;
-	while(option && option_id >= 0)
+	CVoteOption *pOption = m_pFirst;
+	while(pOption && OptionId >= 0)
 	{
-		if(option_id == 0)
+		if(OptionId == 0)
 		{
-			callvote("option", option->command);
+			Client()->Rcon(pOption->m_aCommand);
 			break;
 		}
 		
-		option_id--;
-		option = option->next;
+		OptionId--;
+		pOption = pOption->m_pNext;
 	}
 }
 
-void VOTING::vote(int v)
+void CVoting::Vote(int v)
 {
-	NETMSG_CL_VOTE msg = {v};
-	msg.pack(MSGFLAG_VITAL);
-	client_send_msg();
+	CNetMsg_Cl_Vote Msg = {v};
+	Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
 }
 
-VOTING::VOTING()
+CVoting::CVoting()
 {
-	heap = 0;
-	clearoptions();
-	on_reset();
+	ClearOptions();
+	OnReset();
 }
 
 
-void VOTING::clearoptions()
+void CVoting::ClearOptions()
 {
-	if(heap)
-		memheap_destroy(heap);
-	heap = memheap_create();
+	m_Heap.Reset();
 	
-	first = 0;
-	last = 0;
+	m_pFirst = 0;
+	m_pLast = 0;
 }
 
-void VOTING::on_reset()
+void CVoting::OnReset()
 {
-	closetime = 0;
-	description[0] = 0;
-	command[0] = 0;
-	yes = no = pass = total = 0;
-	voted = 0;
+	m_Closetime = 0;
+	m_aDescription[0] = 0;
+	m_aCommand[0] = 0;
+	m_Yes = m_No = m_Pass = m_Total = 0;
+	m_Voted = 0;
 }
 
-void VOTING::on_console_init()
+void CVoting::OnConsoleInit()
 {
-	MACRO_REGISTER_COMMAND("callvote", "sr", CFGFLAG_CLIENT, con_callvote, this, "Call vote");
-	MACRO_REGISTER_COMMAND("vote", "r", CFGFLAG_CLIENT, con_vote, this, "Vote yes/no");
+	Console()->Register("callvote", "sr", CFGFLAG_CLIENT, ConCallvote, this, "Call vote");
+	Console()->Register("vote", "r", CFGFLAG_CLIENT, ConVote, this, "Vote yes/no");
 }
 
-void VOTING::on_message(int msgtype, void *rawmsg)
+void CVoting::OnMessage(int MsgType, void *pRawMsg)
 {
-	if(msgtype == NETMSGTYPE_SV_VOTE_SET)
+	if(MsgType == NETMSGTYPE_SV_VOTESET)
 	{
-		NETMSG_SV_VOTE_SET *msg = (NETMSG_SV_VOTE_SET *)rawmsg;
-		if(msg->timeout)
+		CNetMsg_Sv_VoteSet *pMsg = (CNetMsg_Sv_VoteSet *)pRawMsg;
+		if(pMsg->m_Timeout)
 		{
-			on_reset();
-			str_copy(description, msg->description, sizeof(description));
-			str_copy(command, msg->command, sizeof(description));
-			closetime = time_get() + time_freq() * msg->timeout;
+			OnReset();
+			str_copy(m_aDescription, pMsg->m_pDescription, sizeof(m_aDescription));
+			str_copy(m_aCommand, pMsg->m_pCommand, sizeof(m_aCommand));
+			m_Closetime = time_get() + time_freq() * pMsg->m_Timeout;
 		}
 		else
-			on_reset();
+			OnReset();
 	}
-	else if(msgtype == NETMSGTYPE_SV_VOTE_STATUS)
+	else if(MsgType == NETMSGTYPE_SV_VOTESTATUS)
 	{
-		NETMSG_SV_VOTE_STATUS *msg = (NETMSG_SV_VOTE_STATUS *)rawmsg;
-		yes = msg->yes;
-		no = msg->no;
-		pass = msg->pass;
-		total = msg->total;
+		CNetMsg_Sv_VoteStatus *pMsg = (CNetMsg_Sv_VoteStatus *)pRawMsg;
+		m_Yes = pMsg->m_Yes;
+		m_No = pMsg->m_No;
+		m_Pass = pMsg->m_Pass;
+		m_Total = pMsg->m_Total;
 	}	
-	else if(msgtype == NETMSGTYPE_SV_VOTE_CLEAROPTIONS)
+	else if(MsgType == NETMSGTYPE_SV_VOTECLEAROPTIONS)
 	{
-		clearoptions();
+		ClearOptions();
 	}
-	else if(msgtype == NETMSGTYPE_SV_VOTE_OPTION)
+	else if(MsgType == NETMSGTYPE_SV_VOTEOPTION)
 	{
-		NETMSG_SV_VOTE_OPTION *msg = (NETMSG_SV_VOTE_OPTION *)rawmsg;
-		int len = str_length(msg->command);
+		CNetMsg_Sv_VoteOption *pMsg = (CNetMsg_Sv_VoteOption *)pRawMsg;
+		int Len = str_length(pMsg->m_pCommand);
 	
-		VOTEOPTION *option = (VOTEOPTION *)memheap_allocate(heap, sizeof(VOTEOPTION) + len);
-		option->next = 0;
-		option->prev = last;
-		if(option->prev)
-			option->prev->next = option;
-		last = option;
-		if(!first)
-			first = option;
+		CVoteOption *pOption = (CVoteOption *)m_Heap.Allocate(sizeof(CVoteOption) + Len);
+		pOption->m_pNext = 0;
+		pOption->m_pPrev = m_pLast;
+		if(pOption->m_pPrev)
+			pOption->m_pPrev->m_pNext = pOption;
+		m_pLast = pOption;
+		if(!m_pFirst)
+			m_pFirst = pOption;
 		
-		mem_copy(option->command, msg->command, len+1);
+		mem_copy(pOption->m_aCommand, pMsg->m_pCommand, Len+1);
 
 	}
 }
 
-void VOTING::on_render()
+void CVoting::OnRender()
 {
 }
 
 
-void VOTING::render_bars(CUIRect bars, bool text)
+void CVoting::RenderBars(CUIRect Bars, bool Text)
 {
-	RenderTools()->DrawUIRect(&bars, vec4(0.8f,0.8f,0.8f,0.5f), CUI::CORNER_ALL, bars.h/3);
+	RenderTools()->DrawUIRect(&Bars, vec4(0.8f,0.8f,0.8f,0.5f), CUI::CORNER_ALL, Bars.h/3);
 	
-	CUIRect splitter = bars;
-	splitter.x = splitter.x+splitter.w/2;
-	splitter.w = splitter.h/2.0f;
-	splitter.x -= splitter.w/2;
-	RenderTools()->DrawUIRect(&splitter, vec4(0.4f,0.4f,0.4f,0.5f), CUI::CORNER_ALL, splitter.h/4);
+	CUIRect Splitter = Bars;
+	Splitter.x = Splitter.x+Splitter.w/2;
+	Splitter.w = Splitter.h/2.0f;
+	Splitter.x -= Splitter.w/2;
+	RenderTools()->DrawUIRect(&Splitter, vec4(0.4f,0.4f,0.4f,0.5f), CUI::CORNER_ALL, Splitter.h/4);
 			
-	if(total)
+	if(m_Total)
 	{
-		CUIRect pass_area = bars;
-		if(yes)
+		CUIRect PassArea = Bars;
+		if(m_Yes)
 		{
-			CUIRect yes_area = bars;
-			yes_area.w *= yes/(float)total;
-			RenderTools()->DrawUIRect(&yes_area, vec4(0.2f,0.9f,0.2f,0.85f), CUI::CORNER_ALL, bars.h/3);
+			CUIRect YesArea = Bars;
+			YesArea.w *= m_Yes/(float)m_Total;
+			RenderTools()->DrawUIRect(&YesArea, vec4(0.2f,0.9f,0.2f,0.85f), CUI::CORNER_ALL, Bars.h/3);
 			
-			if(text)
+			if(Text)
 			{
-				char buf[256];
-				str_format(buf, sizeof(buf), "%d", yes);
-				UI()->DoLabel(&yes_area, buf, bars.h*0.75f, 0);
+				char Buf[256];
+				str_format(Buf, sizeof(Buf), "%d", m_Yes);
+				UI()->DoLabel(&YesArea, Buf, Bars.h*0.75f, 0);
 			}
 			
-			pass_area.x += yes_area.w;
-			pass_area.w -= yes_area.w;
+			PassArea.x += YesArea.w;
+			PassArea.w -= YesArea.w;
 		}
 		
-		if(no)
+		if(m_No)
 		{
-			CUIRect no_area = bars;
-			no_area.w *= no/(float)total;
-			no_area.x = (bars.x + bars.w)-no_area.w;
-			RenderTools()->DrawUIRect(&no_area, vec4(0.9f,0.2f,0.2f,0.85f), CUI::CORNER_ALL, bars.h/3);
+			CUIRect NoArea = Bars;
+			NoArea.w *= m_No/(float)m_Total;
+			NoArea.x = (Bars.x + Bars.w)-NoArea.w;
+			RenderTools()->DrawUIRect(&NoArea, vec4(0.9f,0.2f,0.2f,0.85f), CUI::CORNER_ALL, Bars.h/3);
 			
-			if(text)
+			if(Text)
 			{
-				char buf[256];
-				str_format(buf, sizeof(buf), "%d", no);
-				UI()->DoLabel(&no_area, buf, bars.h*0.75f, 0);
+				char Buf[256];
+				str_format(Buf, sizeof(Buf), "%d", m_No);
+				UI()->DoLabel(&NoArea, Buf, Bars.h*0.75f, 0);
 			}
 
-			pass_area.w -= no_area.w;
+			PassArea.w -= NoArea.w;
 		}
 
-		if(text && pass)
+		if(Text && m_Pass)
 		{
-			char buf[256];
-			str_format(buf, sizeof(buf), "%d", pass);
-			UI()->DoLabel(&pass_area, buf, bars.h*0.75f, 0);
+			char Buf[256];
+			str_format(Buf, sizeof(Buf), "%d", m_Pass);
+			UI()->DoLabel(&PassArea, Buf, Bars.h*0.75f, 0);
 		}
 	}	
 }
diff --git a/src/game/client/components/voting.h b/src/game/client/components/voting.h
new file mode 100644
index 00000000..1f5d2fc5
--- /dev/null
+++ b/src/game/client/components/voting.h
@@ -0,0 +1,58 @@
+#ifndef GAME_CLIENT_COMPONENTS_VOTING_H
+#define GAME_CLIENT_COMPONENTS_VOTING_H
+#include <game/client/component.h>
+#include <game/client/ui.h>
+#include <engine/shared/memheap.h>
+
+class CVoting : public CComponent
+{
+	CHeap m_Heap;
+
+	static void ConCallvote(IConsole::IResult *pResult, void *pUserData);
+	static void ConVote(IConsole::IResult *pResult, void *pUserData);
+	
+	int64 m_Closetime;
+	char m_aDescription[512];
+	char m_aCommand[512];
+	int m_Voted;
+	
+	void ClearOptions();
+	void Callvote(const char *pType, const char *pValue);
+	
+public:
+
+	struct CVoteOption
+	{
+		CVoteOption *m_pNext;
+		CVoteOption *m_pPrev;
+		char m_aCommand[1];
+	};
+	
+	CVoteOption *m_pFirst;
+	CVoteOption *m_pLast;
+
+	CVoting();
+	virtual void OnReset();
+	virtual void OnConsoleInit();
+	virtual void OnMessage(int Msgtype, void *pRawMsg);
+	virtual void OnRender();
+	
+	void RenderBars(CUIRect Bars, bool Text);
+	
+	void CallvoteKick(int ClientId);
+	void CallvoteOption(int Option);
+	void ForcevoteKick(int ClientId);
+	void ForcevoteOption(int Option);
+	
+	void Vote(int v); // -1 = no, 1 = yes
+	
+	int SecondsLeft() { return (m_Closetime - time_get())/time_freq(); }
+	bool IsVoting() { return m_Closetime != 0; }
+	int TakenChoice() const { return m_Voted; }
+	const char *VoteDescription() const { return m_aDescription; }
+	const char *VoteCommand() const { return m_aCommand; }
+	
+	int m_Yes, m_No, m_Pass, m_Total;
+};
+
+#endif
diff --git a/src/game/client/components/voting.hpp b/src/game/client/components/voting.hpp
deleted file mode 100644
index e04e1840..00000000
--- a/src/game/client/components/voting.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <game/client/component.hpp>
-#include <game/client/ui.hpp>
-#include <engine/e_memheap.h>
-
-class VOTING : public COMPONENT
-{
-	HEAP *heap;
-
-	static void con_callvote(void *result, void *user_data);
-	static void con_vote(void *result, void *user_data);
-	
-	int64 closetime;
-	char description[512];
-	char command[512];
-	int voted;
-	
-	void clearoptions();
-	void callvote(const char *type, const char *value);
-	
-public:
-
-	struct VOTEOPTION
-	{
-		VOTEOPTION *next;
-		VOTEOPTION *prev;
-		char command[1];
-	};
-	VOTEOPTION *first;
-	VOTEOPTION *last;
-
-	VOTING();
-	virtual void on_reset();
-	virtual void on_console_init();
-	virtual void on_message(int msgtype, void *rawmsg);
-	virtual void on_render();
-	
-	void render_bars(CUIRect bars, bool text);
-	
-	void callvote_kick(int client_id);
-	void callvote_option(int option);
-	
-	void vote(int v); // -1 = no, 1 = yes
-	
-	int seconds_left() { return (closetime - time_get())/time_freq(); }
-	bool is_voting() { return closetime != 0; }
-	int taken_choice() const { return voted; }
-	const char *vote_description() const { return description; }
-	const char *vote_command() const { return command; }
-	
-	int yes, no, pass, total;
-};
-