about summary refs log tree commit diff
path: root/src/game/client/gc_client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/client/gc_client.cpp')
-rw-r--r--src/game/client/gc_client.cpp1629
1 files changed, 3 insertions, 1626 deletions
diff --git a/src/game/client/gc_client.cpp b/src/game/client/gc_client.cpp
index f9900ab3..2418b6ea 100644
--- a/src/game/client/gc_client.cpp
+++ b/src/game/client/gc_client.cpp
@@ -6,8 +6,6 @@
 #include <string.h>
 
 extern "C" {
-	#include <engine/e_config.h> // TODO: this shouldn't be here
-	#include <engine/client/ec_font.h> // TODO: this shouldn't be here
 	#include <engine/e_client_interface.h>
 };
 
@@ -16,70 +14,16 @@ extern "C" {
 #include "../layers.hpp"
 #include "gc_map_image.hpp"
 #include "../generated/gc_data.hpp"
-#include "gc_menu.hpp"
-#include "gc_skin.hpp"
 #include "gc_ui.hpp"
 #include "gc_client.hpp"
 #include "gc_render.hpp"
-#include "gc_anim.hpp"
-#include "gc_console.hpp"
 
-//struct data_container *data = 0;
-int64 debug_firedelay = 0;
-
-NETOBJ_PLAYER_INPUT input_data = {0};
-int input_target_lock = 0;
-int input_direction_left = 0;
-int input_direction_right = 0;
-
-int chat_mode = CHATMODE_NONE;
-bool menu_active = false;
-bool menu_game_active = false;
-int emoticon_selector_active = 0;
-int scoreboard_active = 0;
-static int emoticon_selected_emote = -1;
+#include "components/skins.hpp"
+#include "components/damageind.hpp"
+#include "gameclient.hpp"
 
 TUNING_PARAMS tuning;
 
-vec2 mouse_pos;
-vec2 local_character_pos;
-vec2 local_target_pos;
-
-/*
-const NETOBJ_PLAYER_CHARACTER *local_character = 0;
-const NETOBJ_PLAYER_CHARACTER *local_prev_character = 0;
-const NETOBJ_PLAYER_INFO *local_info = 0;
-const NETOBJ_FLAG *flags[2] = {0,0};
-const NETOBJ_GAME *gameobj = 0;
-*/
-
-SNAPSTATE netobjects;
-
-int picked_up_weapon = -1;
-
-CLIENT_DATA client_datas[MAX_CLIENTS];
-void CLIENT_DATA::update_render_info()
-{
-	render_info = skin_info;
-
-	// force team colors
-	if(netobjects.gameobj && netobjects.gameobj->gametype != GAMETYPE_DM)
-	{
-		const int team_colors[2] = {65387, 10223467};
-		if(team >= 0 || team <= 1)
-		{
-			render_info.texture = skin_get(skin_id)->color_texture;
-			render_info.color_body = skin_get_color(team_colors[team]);
-			render_info.color_feet = skin_get_color(team_colors[team]);
-		}
-	}		
-}
-
-
-// broadcasts
-char broadcast_text[1024] = {0};
-int64 broadcast_time = 0;
-
 void snd_play_random(int chn, int setid, float vol, vec2 pos)
 {
 	SOUNDSET *set = &data->sounds[setid];
@@ -101,1570 +45,3 @@ void snd_play_random(int chn, int setid, float vol, vec2 pos)
 	snd_play_at(chn, set->sounds[id].id, 0, pos.x, pos.y);
 	set->last = id;
 }
-
-
-void send_switch_team(int team)
-{
-	NETMSG_CL_SETTEAM msg;
-	msg.team = team;
-	msg.pack(MSGFLAG_VITAL);
-	client_send_msg();	
-}
-
-class damage_indicators
-{
-public:
-	int64 lastupdate;
-	struct item
-	{
-		vec2 pos;
-		vec2 dir;
-		float life;
-		float startangle;
-	};
-
-	enum
-	{
-		MAX_ITEMS=64,
-	};
-
-	damage_indicators()
-	{
-		lastupdate = 0;
-		num_items = 0;
-	}
-
-	item items[MAX_ITEMS];
-	int num_items;
-
-	item *create_i()
-	{
-		if (num_items < MAX_ITEMS)
-		{
-			item *p = &items[num_items];
-			num_items++;
-			return p;
-		}
-		return 0;
-	}
-
-	void destroy_i(item *i)
-	{
-		num_items--;
-		*i = items[num_items];
-	}
-
-	void create(vec2 pos, vec2 dir)
-	{
-		item *i = create_i();
-		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;
-		}
-	}
-
-	void render()
-	{
-		gfx_texture_set(data->images[IMAGE_GAME].id);
-		gfx_quads_begin();
-		for(int i = 0; i < num_items;)
-		{
-			vec2 pos = mix(items[i].pos+items[i].dir*75.0f, items[i].pos, clamp((items[i].life-0.60f)/0.15f, 0.0f, 1.0f));
-
-			items[i].life -= client_frametime();
-			if(items[i].life < 0.0f)
-				destroy_i(&items[i]);
-			else
-			{
-				gfx_setcolor(1.0f,1.0f,1.0f, items[i].life/0.1f);
-				gfx_quads_setrotation(items[i].startangle + items[i].life * 2.0f);
-				select_sprite(SPRITE_STAR1);
-				draw_sprite(pos.x, pos.y, 48.0f);
-				i++;
-			}
-		}
-		gfx_quads_end();
-	}
-
-};
-
-static damage_indicators dmgind;
-
-void effect_damage_indicator(vec2 pos, vec2 dir)
-{
-	dmgind.create(pos, dir);
-}
-
-void render_damage_indicators()
-{
-	dmgind.render();
-}
-
-static line_input chat_input;
-static const int chat_max_lines = 10;
-
-bool chat_input_handle(INPUT_EVENT e, void *user_data)
-{
-	if(chat_mode == CHATMODE_NONE)
-		return false;
-
-	if(e.flags&INPFLAG_PRESS && (e.key == KEY_ENTER || e.key == KEY_KP_ENTER))
-	{
-		if(chat_input.get_string()[0])
-			chat_say(chat_mode == CHATMODE_ALL ? 0 : 1, chat_input.get_string());
-		chat_mode = CHATMODE_NONE;
-	}
-	else
-		chat_input.process_input(e);
-	
-	return true;
-}
-
-struct chatline
-{
-	int tick;
-	int client_id;
-	int team;
-	int name_color;
-	char name[64];
-	char text[512];
-};
-
-chatline chat_lines[chat_max_lines];
-static int chat_current_line = 0;
-
-void chat_reset()
-{
-	for(int i = 0; i < chat_max_lines; i++)
-		chat_lines[i].tick = -1000000;
-	chat_current_line = 0;
-}
-
-void chat_add_line(int client_id, int team, const char *line)
-{
-	chat_current_line = (chat_current_line+1)%chat_max_lines;
-	chat_lines[chat_current_line].tick = client_tick();
-	chat_lines[chat_current_line].client_id = client_id;
-	chat_lines[chat_current_line].team = team;
-	chat_lines[chat_current_line].name_color = -2;
-
-	if(client_id == -1) // server message
-	{
-		str_copy(chat_lines[chat_current_line].name, "*** ", sizeof(chat_lines[chat_current_line].name));
-		str_format(chat_lines[chat_current_line].text, sizeof(chat_lines[chat_current_line].text), "%s", line);
-	}
-	else
-	{
-		if(client_datas[client_id].team == -1)
-			chat_lines[chat_current_line].name_color = -1;
-
-		if(netobjects.gameobj && netobjects.gameobj->gametype != GAMETYPE_DM)
-		{
-			if(client_datas[client_id].team == 0)
-				chat_lines[chat_current_line].name_color = 0;
-			else if(client_datas[client_id].team == 1)
-				chat_lines[chat_current_line].name_color = 1;
-		}
-		
-		str_copy(chat_lines[chat_current_line].name, client_datas[client_id].name, sizeof(chat_lines[chat_current_line].name));
-		str_format(chat_lines[chat_current_line].text, sizeof(chat_lines[chat_current_line].text), ": %s", line);
-	}
-	
-	if(config.debug)
-		dbg_msg("message", "chat cid=%d team=%d line='%s'", client_id, team, line);
-	dbg_msg("chat", "%s%s", chat_lines[chat_current_line].name, chat_lines[chat_current_line].text);
-	
-}
-
-
-KILLMSG killmsgs[killmsg_max];
-int killmsg_current = 0;
-
-//bool add_trail = false;
-
-line_input::line_input()
-{
-	clear();
-}
-
-void line_input::clear()
-{
-	mem_zero(str, sizeof(str));
-	len = 0;
-	cursor_pos = 0;
-}
-
-void line_input::set(const char *string)
-{
-	str_copy(str, string, sizeof(str));
-	len = strlen(str);
-	cursor_pos = len;
-}
-
-void line_input::process_input(INPUT_EVENT e)
-{
-	if(cursor_pos > len)
-		cursor_pos = len;
-	
-	char c = e.ch;
-	int k = e.key;
-	
-	if (!(c >= 0 && c < 32))
-	{
-		if (len < sizeof(str) - 1 && cursor_pos < sizeof(str) - 1)
-		{
-			memmove(str + cursor_pos + 1, str + cursor_pos, len - cursor_pos + 1);
-			str[cursor_pos] = c;
-			cursor_pos++;
-			len++;
-		}
-	}
-	
-	if(e.flags&INPFLAG_PRESS)
-	{
-		if (k == KEY_BACKSPACE && cursor_pos > 0)
-		{
-			memmove(str + cursor_pos - 1, str + cursor_pos, len - cursor_pos + 1);
-			cursor_pos--;
-			len--;
-		}
-		else if (k == KEY_DEL && cursor_pos < len)
-		{
-			memmove(str + cursor_pos, str + cursor_pos + 1, len - cursor_pos);
-			len--;
-		}
-		else if (k == KEY_LEFT && cursor_pos > 0)
-			cursor_pos--;
-		else if (k == KEY_RIGHT && cursor_pos < len)
-			cursor_pos++;
-		else if (k == KEY_HOME)
-			cursor_pos = 0;
-		else if (k == KEY_END)
-			cursor_pos = len;
-	}
-}
-
-INPUT_STACK_HANDLER::INPUT_STACK_HANDLER()
-{
-	num_handlers = 0;
-}
-
-void INPUT_STACK_HANDLER::add_handler(CALLBACK cb, void *user)
-{
-	user_data[num_handlers] = user;
-	handlers[num_handlers++] = cb;
-}
-
-void INPUT_STACK_HANDLER::dispatch_input()
-{
-	for(int i = 0; i < inp_num_events(); i++)
-	{
-		INPUT_EVENT e = inp_get_event(i);
-		
-		for(int h = 0; h < num_handlers; h++)
-		{
-			if(handlers[h](e, user_data[h]))
-			{
-				//dbg_msg("", "%d char=%d key=%d flags=%d", h, e.ch, e.key, e.flags);
-				break;
-			}
-		}
-	}
-	
-	inp_clear_events();
-}
-
-
-INPUT_STACK_HANDLER input_stack;
-
-extern int render_popup(const char *caption, const char *text, const char *button_text);
-
-void process_events(int snaptype)
-{
-	int num = snap_num_items(snaptype);
-	for(int index = 0; index < num; index++)
-	{
-		SNAP_ITEM item;
-		const void *data = snap_get_item(snaptype, index, &item);
-
-		if(item.type == NETEVENTTYPE_DAMAGEIND)
-		{
-			NETEVENT_DAMAGEIND *ev = (NETEVENT_DAMAGEIND *)data;
-			effect_damage_indicator(vec2(ev->x, ev->y), get_direction(ev->angle));
-		}
-		else if(item.type == NETEVENTTYPE_AIRJUMP)
-		{
-			NETEVENT_COMMON *ev = (NETEVENT_COMMON *)data;
-			effect_air_jump(vec2(ev->x, ev->y));
-		}
-		else if(item.type == NETEVENTTYPE_EXPLOSION)
-		{
-			NETEVENT_EXPLOSION *ev = (NETEVENT_EXPLOSION *)data;
-			effect_explosion(vec2(ev->x, ev->y));
-		}
-		/*else if(item.type == EVENT_SMOKE)
-		{
-			EV_EXPLOSION *ev = (EV_EXPLOSION *)data;
-			vec2 p(ev->x, ev->y);
-		}*/
-		else if(item.type == NETEVENTTYPE_SPAWN)
-		{
-			NETEVENT_SPAWN *ev = (NETEVENT_SPAWN *)data;
-			effect_playerspawn(vec2(ev->x, ev->y));
-		}
-		else if(item.type == NETEVENTTYPE_DEATH)
-		{
-			NETEVENT_DEATH *ev = (NETEVENT_DEATH *)data;
-			effect_playerdeath(vec2(ev->x, ev->y), ev->cid);
-		}
-		else if(item.type == NETEVENTTYPE_SOUNDWORLD)
-		{
-			NETEVENT_SOUNDWORLD *ev = (NETEVENT_SOUNDWORLD *)data;
-			snd_play_random(CHN_WORLD, ev->soundid, 1.0f, vec2(ev->x, ev->y));
-		}
-	}
-}
-
-void clear_object_pointers()
-{
-	// clear out the invalid pointers
-	mem_zero(&netobjects, sizeof(netobjects));
-}
-
-void send_info(bool start)
-{
-	if(start)
-	{
-		NETMSG_CL_STARTINFO msg;
-		msg.name = config.player_name;
-		msg.skin = config.player_skin;
-		msg.use_custom_color = config.player_use_custom_color;
-		msg.color_body = config.player_color_body;
-		msg.color_feet = config.player_color_feet;
-		msg.pack(MSGFLAG_VITAL|MSGFLAG_FLUSH);
-	}
-	else
-	{
-		NETMSG_CL_CHANGEINFO msg;
-		msg.name = config.player_name;
-		msg.skin = config.player_skin;
-		msg.use_custom_color = config.player_use_custom_color;
-		msg.color_body = config.player_color_body;
-		msg.color_feet = config.player_color_feet;
-		msg.pack(MSGFLAG_VITAL);
-	}
-	client_send_msg();
-}
-
-void send_emoticon(int emoticon)
-{
-	NETMSG_CL_EMOTICON msg;
-	msg.emoticon = emoticon;
-	msg.pack(MSGFLAG_VITAL);
-	client_send_msg();
-}
-
-void send_kill(int client_id)
-{
-	NETMSG_CL_KILL msg;
-	msg.pack(MSGFLAG_VITAL);
-	client_send_msg();
-}
-
-void anim_seq_eval(ANIM_SEQUENCE *seq, float time, ANIM_KEYFRAME *frame)
-{
-	if(seq->num_frames == 0)
-	{
-		frame->time = 0;
-		frame->x = 0;
-		frame->y = 0;
-		frame->angle = 0;
-	}
-	else if(seq->num_frames == 1)
-	{
-		*frame = seq->frames[0];
-	}
-	else
-	{
-		//time = max(0.0f, min(1.0f, time / duration)); // TODO: use clamp
-		ANIM_KEYFRAME *frame1 = 0;
-		ANIM_KEYFRAME *frame2 = 0;
-		float blend = 0.0f;
-
-		// TODO: make this smarter.. binary search
-		for (int i = 1; i < seq->num_frames; i++)
-		{
-			if (seq->frames[i-1].time <= time && seq->frames[i].time >= time)
-			{
-				frame1 = &seq->frames[i-1];
-				frame2 = &seq->frames[i];
-				blend = (time - frame1->time) / (frame2->time - frame1->time);
-				break;
-			}
-		}
-
-		if (frame1 && frame2)
-		{
-			frame->time = time;
-			frame->x = mix(frame1->x, frame2->x, blend);
-			frame->y = mix(frame1->y, frame2->y, blend);
-			frame->angle = mix(frame1->angle, frame2->angle, blend);
-		}
-	}
-}
-
-void anim_eval(ANIMATION *anim, float time, ANIM_STATE *state)
-{
-	anim_seq_eval(&anim->body, time, &state->body);
-	anim_seq_eval(&anim->back_foot, time, &state->back_foot);
-	anim_seq_eval(&anim->front_foot, time, &state->front_foot);
-	anim_seq_eval(&anim->attach, time, &state->attach);
-}
-
-void anim_add_keyframe(ANIM_KEYFRAME *seq, ANIM_KEYFRAME *added, float amount)
-{
-	seq->x += added->x*amount;
-	seq->y += added->y*amount;
-	seq->angle += added->angle*amount;
-}
-
-void anim_add(ANIM_STATE *state, ANIM_STATE *added, float amount)
-{
-	anim_add_keyframe(&state->body, &added->body, amount);
-	anim_add_keyframe(&state->back_foot, &added->back_foot, amount);
-	anim_add_keyframe(&state->front_foot, &added->front_foot, amount);
-	anim_add_keyframe(&state->attach, &added->attach, amount);
-}
-
-void anim_eval_add(ANIM_STATE *state, ANIMATION *anim, float time, float amount)
-{
-	ANIM_STATE add;
-	anim_eval(anim, time, &add);
-	anim_add(state, &add, amount);
-}
-
-static void draw_circle(float x, float y, float r, int segments)
-{
-	float f_segments = (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);
-
-		gfx_quads_draw_freeform(
-			x, y,
-			x+ca1*r, y+sa1*r,
-			x+ca3*r, y+sa3*r,
-			x+ca2*r, y+sa2*r);
-	}
-}
-
-static vec2 emoticon_selector_mouse;
-
-void emoticon_selector_render()
-{
-	int x, y;
-	inp_mouse_relative(&x, &y);
-
-	emoticon_selector_mouse.x += x;
-	emoticon_selector_mouse.y += y;
-
-	if (length(emoticon_selector_mouse) > 140)
-		emoticon_selector_mouse = normalize(emoticon_selector_mouse) * 140;
-
-	float selected_angle = get_angle(emoticon_selector_mouse) + 2*pi/24;
-	if (selected_angle < 0)
-		selected_angle += 2*pi;
-
-	if (length(emoticon_selector_mouse) > 100)
-		emoticon_selected_emote = (int)(selected_angle / (2*pi) * 12.0f);
-
-    RECT screen = *ui_screen();
-
-	gfx_mapscreen(screen.x, screen.y, screen.w, screen.h);
-
-	gfx_blend_normal();
-
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.3f);
-	draw_circle(screen.w/2, screen.h/2, 160, 64);
-	gfx_quads_end();
-
-	gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
-	gfx_quads_begin();
-
-	for (int i = 0; i < 12; i++)
-	{
-		float angle = 2*pi*i/12.0;
-		if (angle > pi)
-			angle -= 2*pi;
-
-		bool selected = emoticon_selected_emote == i;
-
-		float size = selected ? 96 : 64;
-
-		float nudge_x = 120 * cos(angle);
-		float nudge_y = 120 * sin(angle);
-		select_sprite(SPRITE_OOP + i);
-		gfx_quads_draw(screen.w/2 + nudge_x, screen.h/2 + nudge_y, size, size);
-	}
-
-	gfx_quads_end();
-
-    gfx_texture_set(data->images[IMAGE_CURSOR].id);
-    gfx_quads_begin();
-    gfx_setcolor(1,1,1,1);
-    gfx_quads_drawTL(emoticon_selector_mouse.x+screen.w/2,emoticon_selector_mouse.y+screen.h/2,24,24);
-    gfx_quads_end();
-}
-
-void render_goals(float x, float y, float w)
-{
-	float h = 50.0f;
-
-	gfx_blend_normal();
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.5f);
-	draw_round_rect(x-10.f, y-10.f, w, h, 10.0f);
-	gfx_quads_end();
-
-	// render goals
-	//y = ystart+h-54;
-	if(netobjects.gameobj && netobjects.gameobj->time_limit)
-	{
-		char buf[64];
-		str_format(buf, sizeof(buf), "Time Limit: %d min", netobjects.gameobj->time_limit);
-		gfx_text(0, x+w/2, y, 24.0f, buf, -1);
-	}
-	if(netobjects.gameobj && netobjects.gameobj->score_limit)
-	{
-		char buf[64];
-		str_format(buf, sizeof(buf), "Score Limit: %d", netobjects.gameobj->score_limit);
-		gfx_text(0, x+40, y, 24.0f, buf, -1);
-	}
-}
-
-void render_spectators(float x, float y, float w)
-{
-	char buffer[1024*4];
-	int count = 0;
-	float h = 120.0f;
-	
-	str_copy(buffer, "Spectators: ", sizeof(buffer));
-
-	gfx_blend_normal();
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.5f);
-	draw_round_rect(x-10.f, y-10.f, w, h, 10.0f);
-	gfx_quads_end();
-	
-	for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
-	{
-		SNAP_ITEM item;
-		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
-
-		if(item.type == NETOBJTYPE_PLAYER_INFO)
-		{
-			const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
-			if(info->team == -1)
-			{
-				if(count)
-					strcat(buffer, ", ");
-				strcat(buffer, client_datas[info->cid].name);
-				count++;
-			}
-		}
-	}
-	
-	gfx_text(0, x+10, y, 32, buffer, (int)w-20);
-}
-
-void render_scoreboard(float x, float y, float w, int team, const char *title)
-{
-	ANIM_STATE idlestate;
-	anim_eval(&data->animations[ANIM_BASE], 0, &idlestate);
-	anim_eval_add(&idlestate, &data->animations[ANIM_IDLE], 0, 1.0f);
-
-	//float ystart = y;
-	float h = 750.0f;
-
-	gfx_blend_normal();
-	gfx_texture_set(-1);
-	gfx_quads_begin();
-	gfx_setcolor(0,0,0,0.5f);
-	draw_round_rect(x-10.f, y-10.f, w, h, 40.0f);
-	gfx_quads_end();
-
-	// render title
-	if(!title)
-	{
-		if(netobjects.gameobj->game_over)
-			title = "Game Over";
-		else
-			title = "Score Board";
-	}
-
-	float tw = gfx_text_width(0, 48, title, -1);
-
-	if(team == -1)
-	{
-		gfx_text(0, x+w/2-tw/2, y, 48, title, -1);
-	}
-	else
-	{
-		gfx_text(0, x+10, y, 48, title, -1);
-
-		if(netobjects.gameobj)
-		{
-			char buf[128];
-			int score = team ? netobjects.gameobj->teamscore_blue : netobjects.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);
-		}
-	}
-
-	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++)
-	{
-		SNAP_ITEM item;
-		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
-
-		if(item.type == NETOBJTYPE_PLAYER_INFO)
-		{
-			players[num_players] = (const NETOBJ_PLAYER_INFO *)data;
-			num_players++;
-		}
-	}
-
-	// sort players
-	for(int k = 0; k < num_players; k++) // ffs, bubblesort
-	{
-		for(int i = 0; i < num_players-k-1; i++)
-		{
-			if(players[i]->score < players[i+1]->score)
-			{
-				const NETOBJ_PLAYER_INFO *tmp = players[i];
-				players[i] = players[i+1];
-				players[i+1] = tmp;
-			}
-		}
-	}
-
-	// render headlines
-	gfx_text(0, x+10, y, 24.0f, "Score", -1);
-	gfx_text(0, x+125, y, 24.0f, "Name", -1);
-	gfx_text(0, x+w-70, y, 24.0f, "Ping", -1);
-	y += 29.0f;
-
-	// render player scores
-	for(int i = 0; i < num_players; i++)
-	{
-		const NETOBJ_PLAYER_INFO *info = players[i];
-
-		// make sure that we render the correct team
-		if(team == -1 || info->team != team)
-			continue;
-
-		char buf[128];
-		float font_size = 35.0f;
-		if(info->local)
-		{
-			// background so it's easy to find the local player
-			gfx_texture_set(-1);
-			gfx_quads_begin();
-			gfx_setcolor(1,1,1,0.25f);
-			draw_round_rect(x, y, w-20, 48, 20.0f);
-			gfx_quads_end();
-		}
-
-		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);
-		
-		gfx_text(0, x+128, y, font_size, client_datas[info->cid].name, -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);
-
-		// render avatar
-		if((netobjects.flags[0] && netobjects.flags[0]->carried_by == info->cid) ||
-			(netobjects.flags[1] && netobjects.flags[1]->carried_by == info->cid))
-		{
-			gfx_blend_normal();
-			gfx_texture_set(data->images[IMAGE_GAME].id);
-			gfx_quads_begin();
-
-			if(info->team == 0) select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
-			else select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
-			
-			float size = 64.0f;
-			gfx_quads_drawTL(x+55, y-15, size/2, size);
-			gfx_quads_end();
-		}
-		
-		render_tee(&idlestate, &client_datas[info->cid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28));
-
-		
-		y += 50.0f;
-	}
-}
-/*
-static int do_input(int *v, int key)
-{
-	*v += inp_key_presses(key) + inp_key_releases(key);
-	if((*v&1) != inp_key_state(key))
-		(*v)++;
-	*v &= INPUT_STATE_MASK;
-	
-	return (*v&1);
-}*/
-
-void chat_say(int team, const char *line)
-{
-	// send chat message
-	NETMSG_CL_SAY msg;
-	msg.team = team;
-	msg.message = line;
-	msg.pack(MSGFLAG_VITAL);
-	client_send_msg();
-}
-
-void chat_enable_mode(int team)
-{
-	if(chat_mode == CHATMODE_NONE)
-	{
-		if(team)
-			chat_mode = CHATMODE_TEAM;
-		else
-			chat_mode = CHATMODE_ALL;
-		
-		chat_input.clear();
-		inp_clear_events();
-	}
-}
-
-void render_game()
-{
-	// update the effects
-	effects_update();
-	particle_update(client_frametime());
-
-	
-	float width = 400*3.0f*gfx_screenaspect();
-	float height = 400*3.0f;
-
-	bool spectate = false;
-
-	if(config.cl_predict)
-	{
-		if(!netobjects.local_character || (netobjects.local_character->health < 0) || (netobjects.gameobj && netobjects.gameobj->game_over))
-		{
-			// don't use predicted
-		}
-		else
-			local_character_pos = mix(predicted_prev_char.pos, predicted_char.pos, client_predintratick());
-	}
-	else if(netobjects.local_character && netobjects.local_prev_character)
-	{
-		local_character_pos = mix(
-			vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y),
-			vec2(netobjects.local_character->x, netobjects.local_character->y), client_intratick());
-	}
-	
-	if(netobjects.local_info && netobjects.local_info->team == -1)
-		spectate = true;
-
-	ANIM_STATE idlestate;
-	anim_eval(&data->animations[ANIM_BASE], 0, &idlestate);
-	anim_eval_add(&idlestate, &data->animations[ANIM_IDLE], 0, 1.0f);
-
-	if(inp_key_down(KEY_ESC))
-	{
-		if(server_motd_time)
-			server_motd_time = 0;
-		else if (chat_mode)
-			chat_mode = CHATMODE_NONE;
-		else if(!console_active())
-		{
-			menu_active = !menu_active;
-			if(menu_active)
-				menu_game_active = true;
-		}
-	}
-
-	// make sure to send our info again if the menu closes	
-	static bool menu_was_active = false;
-	if(menu_active)
-		menu_was_active = true;
-	else if(menu_was_active)
-	{
-		send_info(false);
-		menu_was_active = false;
-	}
-
-	//
-	float camera_max_distance = 200.0f;
-	float deadzone = config.cl_mouse_deadzone;
-	float follow_factor = config.cl_mouse_followfactor/100.0f;
-	float mouse_max = min(camera_max_distance/follow_factor + deadzone, (float)config.cl_mouse_max_distance);
-	vec2 camera_offset(0, 0);
-
-	// fetch new input
-	if(!menu_active)
-	{
-		int x, y;
-		if(!emoticon_selector_active)
-		{
-			inp_mouse_relative(&x, &y);
-			mouse_pos += vec2(x, y);
-		}
-		
-		if(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;
-		}
-		else
-		{
-			float l = length(mouse_pos);
-			
-			if(l > mouse_max)
-			{
-				mouse_pos = normalize(mouse_pos)*mouse_max;
-				l = mouse_max;
-			}
-
-			float offset_amount = max(l-deadzone, 0) * follow_factor;
-			if(l > 0.0001f) // make sure that this isn't 0
-				camera_offset = normalize(mouse_pos)*offset_amount;
-		}
-	}
-
-	// set listner pos
-	if(spectate)
-	{
-		local_target_pos = mouse_pos;
-		snd_set_listener_pos(mouse_pos.x, mouse_pos.y);
-	}
-	else
-	{
-		local_target_pos = local_character_pos + mouse_pos;
-		snd_set_listener_pos(local_character_pos.x, local_character_pos.y);
-	}
-
-	// center at char but can be moved when mouse is far away
-	/*
-	float offx = 0, offy = 0;
-	if (config.cl_dynamic_camera)
-	{
-		if(mouse_pos.x > deadzone) offx = mouse_pos.x-deadzone;
-		if(mouse_pos.x <-deadzone) offx = mouse_pos.x+deadzone;
-		if(mouse_pos.y > deadzone) offy = mouse_pos.y-deadzone;
-		if(mouse_pos.y <-deadzone) offy = mouse_pos.y+deadzone;
-		offx = offx*2/3;
-		offy = offy*2/3;
-	}*/
-
-	// render the world
-	float zoom = 1.0f;
-
-	if(spectate)
-		render_world(mouse_pos.x, mouse_pos.y, zoom);
-	else
-	{
-		render_world(local_character_pos.x+camera_offset.x, local_character_pos.y+camera_offset.y, zoom);
-
-		// draw screen box
-		if(0)
-		{
-			gfx_texture_set(-1);
-			gfx_blend_normal();
-			gfx_lines_begin();
-				float cx = local_character_pos.x+camera_offset.x;
-				float cy = local_character_pos.y+camera_offset.y;
-				float w = 400*3/2;
-				float h = 300*3/2;
-				gfx_lines_draw(cx-w,cy-h,cx+w,cy-h);
-				gfx_lines_draw(cx+w,cy-h,cx+w,cy+h);
-				gfx_lines_draw(cx+w,cy+h,cx-w,cy+h);
-				gfx_lines_draw(cx-w,cy+h,cx-w,cy-h);
-			gfx_lines_end();
-		}
-	}
-
-
-	// pseudo format
-	// ZOOM ZOOM
-	/*
-	float zoom = 3.0;
-
-	// DEBUG TESTING
-	if(zoom > 3.01f)
-	{
-		gfx_clear_mask(0);
-
-		gfx_texture_set(-1);
-		gfx_blend_normal();
-
-		gfx_mask_op(MASK_NONE, 1);
-
-		gfx_quads_begin();
-		gfx_setcolor(0.65f,0.78f,0.9f,1.0f);
-
-		float fov;
-		if (zoom > 3.01f)
-			fov = pi * (zoom - 3.0f) / 6.0f;
-		else
-			fov = pi / 6.0f;
-
-		float fade = 0.7f;
-
-
-		float a = get_angle(normalize(vec2(mouse_pos.x, mouse_pos.y)));
-		vec2 d = get_dir(a);
-		vec2 d0 = get_dir(a-fov/2.0f);
-		vec2 d1 = get_dir(a+fov/2.0f);
-
-		vec2 cd0 = get_dir(a-(fov*fade)/2.0f); // center direction
-		vec2 cd1 = get_dir(a+(fov*fade)/2.0f);
-
-		vec2 p0n = local_character_pos + d0*32.0f;
-		vec2 p1n = local_character_pos + d1*32.0f;
-		vec2 p0f = local_character_pos + d0*1000.0f;
-		vec2 p1f = local_character_pos + d1*1000.0f;
-
-		vec2 cn = local_character_pos + d*32.0f;
-		vec2 cf = local_character_pos + d*1000.0f;
-
-		vec2 cp0n = local_character_pos + cd0*32.0f;
-		vec2 cp0f = local_character_pos + cd0*1000.0f;
-		vec2 cp1n = local_character_pos + cd1*32.0f;
-		vec2 cp1f = local_character_pos + cd1*1000.0f;
-
-		gfx_quads_draw_freeform(
-			p0n.x,p0n.y,
-			p1n.x,p1n.y,
-			p0f.x,p0f.y,
-			p1f.x,p1f.y);
-		gfx_quads_end();
-
-		gfx_mask_op(MASK_SET, 0);
-
-		render_world(local_character_pos.x+offx, local_character_pos.y+offy, 2.0f);
-
-		gfx_mask_op(MASK_NONE, 0);
-
-		mapscreen_to_world(local_character_pos.x+offx, local_character_pos.y+offy, 1.0f);
-
-		gfx_texture_set(-1);
-		gfx_blend_normal();
-		gfx_quads_begin();
-		gfx_setcolor(0.5f,0.9f,0.5f,0.25f);
-		float r=0.5f, g=1.0f, b=0.5f;
-		float r2=r*0.25f, g2=g*0.25f, b2=b*0.25f;
-
-		gfx_setcolor(r,g,b,0.2f);
-		gfx_quads_draw_freeform(
-			cn.x,cn.y,
-			cn.x,cn.y,
-			cp0f.x,cp0f.y,
-			cp1f.x,cp1f.y);
-
-		gfx_setcolorvertex(0, r, g, b, 0.2f);
-		gfx_setcolorvertex(1, r2, g2, b2, 0.9f);
-		gfx_setcolorvertex(2, r, g, b, 0.2f);
-		gfx_setcolorvertex(3, r2, g2, b2, 0.9f);
-		gfx_quads_draw_freeform(
-			cn.x,cn.y,
-			p0n.x,p0n.y,
-			cp0f.x,cp0f.y,
-			p0f.x,p0f.y);
-
-		gfx_quads_draw_freeform(
-			cn.x,cn.y,
-			p1n.x,p1n.y,
-			cp1f.x,cp1f.y,
-			p1f.x,p1f.y);
-
-		gfx_quads_end();
-	}*/
-
-	if(netobjects.local_character && !spectate && !(netobjects.gameobj && netobjects.gameobj->game_over))
-	{
-		gfx_texture_set(data->images[IMAGE_GAME].id);
-		gfx_quads_begin();
-
-		// render cursor
-		if (!menu_active && !emoticon_selector_active)
-		{
-			select_sprite(data->weapons.id[netobjects.local_character->weapon%NUM_WEAPONS].sprite_cursor);
-			float cursorsize = 64;
-			draw_sprite(local_target_pos.x, local_target_pos.y, cursorsize);
-		}
-		
-		float x = 5;
-		float y = 5;
-
-		// render ammo count
-		// render gui stuff
-		gfx_quads_end();
-		gfx_quads_begin();
-		gfx_mapscreen(0,0,300*gfx_screenaspect(),300);
-		
-		// if weaponstage is active, put a "glow" around the stage ammo
-		select_sprite(data->weapons.id[netobjects.local_character->weapon%NUM_WEAPONS].sprite_proj);
-		for (int i = 0; i < min(netobjects.local_character->ammocount, 10); i++)
-			gfx_quads_drawTL(x+i*12,y+24,10,10);
-
-		gfx_quads_end();
-
-		gfx_texture_set(data->images[IMAGE_GAME].id);
-		gfx_quads_begin();
-		int h = 0;
-
-		// render health
-		select_sprite(SPRITE_HEALTH_FULL);
-		for(; h < netobjects.local_character->health; h++)
-			gfx_quads_drawTL(x+h*12,y,10,10);
-
-		select_sprite(SPRITE_HEALTH_EMPTY);
-		for(; h < 10; h++)
-			gfx_quads_drawTL(x+h*12,y,10,10);
-
-		// render armor meter
-		h = 0;
-		select_sprite(SPRITE_ARMOR_FULL);
-		for(; h < netobjects.local_character->armor; h++)
-			gfx_quads_drawTL(x+h*12,y+12,10,10);
-
-		select_sprite(SPRITE_ARMOR_EMPTY);
-		for(; h < 10; h++)
-			gfx_quads_drawTL(x+h*12,y+12,10,10);
-		gfx_quads_end();
-	}
-
-	// render kill messages
-	{
-		gfx_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++)
-		{
-
-			int r = (killmsg_current+i+1)%killmsg_max;
-			if(client_tick() > killmsgs[r].tick+50*10)
-				continue;
-
-			float font_size = 36.0f;
-			float killername_w = gfx_text_width(0, font_size, client_datas[killmsgs[r].killer].name, -1);
-			float victimname_w = gfx_text_width(0, font_size, client_datas[killmsgs[r].victim].name, -1);
-
-			float x = startx;
-
-			// render victim name
-			x -= victimname_w;
-			gfx_text(0, x, y, font_size, client_datas[killmsgs[r].victim].name, -1);
-
-			// render victim tee
-			x -= 24.0f;
-			
-			if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_CTF)
-			{
-				if(killmsgs[r].mode_special&1)
-				{
-					gfx_blend_normal();
-					gfx_texture_set(data->images[IMAGE_GAME].id);
-					gfx_quads_begin();
-
-					if(client_datas[killmsgs[r].victim].team == 0) select_sprite(SPRITE_FLAG_BLUE);
-					else select_sprite(SPRITE_FLAG_RED);
-					
-					float size = 56.0f;
-					gfx_quads_drawTL(x, y-16, size/2, size);
-					gfx_quads_end();					
-				}
-			}
-			
-			render_tee(&idlestate, &client_datas[killmsgs[r].victim].render_info, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28));
-			x -= 32.0f;
-			
-			// render weapon
-			x -= 44.0f;
-			if (killmsgs[r].weapon >= 0)
-			{
-				gfx_texture_set(data->images[IMAGE_GAME].id);
-				gfx_quads_begin();
-				select_sprite(data->weapons.id[killmsgs[r].weapon].sprite_body);
-				draw_sprite(x, y+28, 96);
-				gfx_quads_end();
-			}
-			x -= 52.0f;
-
-			if(killmsgs[r].victim != killmsgs[r].killer)
-			{
-				if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_CTF)
-				{
-					if(killmsgs[r].mode_special&2)
-					{
-						gfx_blend_normal();
-						gfx_texture_set(data->images[IMAGE_GAME].id);
-						gfx_quads_begin();
-
-						if(client_datas[killmsgs[r].killer].team == 0) select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
-						else select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
-						
-						float size = 56.0f;
-						gfx_quads_drawTL(x-56, y-16, size/2, size);
-						gfx_quads_end();				
-					}
-				}				
-				
-				// render killer tee
-				x -= 24.0f;
-				render_tee(&idlestate, &client_datas[killmsgs[r].killer].render_info, 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, client_datas[killmsgs[r].killer].name, -1);
-			}
-
-			y += 44;
-		}
-	}
-
-	// render chat
-	{
-		gfx_mapscreen(0,0,300*gfx_screenaspect(),300);
-		float x = 10.0f;
-		float y = 300.0f-30.0f;
-		if(chat_mode != CHATMODE_NONE)
-		{
-			// render chat input
-			TEXT_CURSOR cursor;
-			gfx_text_set_cursor(&cursor, x, y, 8.0f, TEXTFLAG_RENDER);
-			cursor.line_width = 300.0f;
-			
-			if(chat_mode == CHATMODE_ALL)
-				gfx_text_ex(&cursor, "All: ", -1);
-			else if(chat_mode == CHATMODE_TEAM)
-				gfx_text_ex(&cursor, "Team: ", -1);
-			else
-				gfx_text_ex(&cursor, "Chat: ", -1);
-				
-			gfx_text_ex(&cursor, chat_input.get_string(), chat_input.cursor_offset());
-			TEXT_CURSOR marker = cursor;
-			gfx_text_ex(&marker, "|", -1);
-			gfx_text_ex(&cursor, chat_input.get_string()+chat_input.cursor_offset(), -1);
-		}
-
-		y -= 8;
-
-		int i;
-		for(i = 0; i < chat_max_lines; i++)
-		{
-			int r = ((chat_current_line-i)+chat_max_lines)%chat_max_lines;
-			if(client_tick() > chat_lines[r].tick+50*15)
-				break;
-
-			float begin = x;
-			float fontsize = 8.0f;
-			
-			// get the y offset
-			TEXT_CURSOR cursor;
-			gfx_text_set_cursor(&cursor, begin, 0, fontsize, 0);
-			cursor.line_width = 300.0f;
-			gfx_text_ex(&cursor, chat_lines[r].name, -1);
-			gfx_text_ex(&cursor, chat_lines[r].text, -1);
-			y -= cursor.y + cursor.font_size;
-
-			// reset the cursor
-			gfx_text_set_cursor(&cursor, begin, y, fontsize, TEXTFLAG_RENDER);
-			cursor.line_width = 300.0f;
-
-			// render name
-			gfx_text_color(0.8f,0.8f,0.8f,1);
-			if(chat_lines[r].client_id == -1)
-				gfx_text_color(1,1,0.5f,1); // system
-			else if(chat_lines[r].team)
-				gfx_text_color(0.45f,0.9f,0.45f,1); // team message
-			else if(chat_lines[r].name_color == 0)
-				gfx_text_color(1.0f,0.5f,0.5f,1); // red
-			else if(chat_lines[r].name_color == 1)
-				gfx_text_color(0.7f,0.7f,1.0f,1); // blue
-			else if(chat_lines[r].name_color == -1)
-				gfx_text_color(0.75f,0.5f,0.75f, 1); // spectator
-				
-			// render name
-			gfx_text_ex(&cursor, chat_lines[r].name, -1);
-
-			// render line
-			gfx_text_color(1,1,1,1);
-			if(chat_lines[r].client_id == -1)
-				gfx_text_color(1,1,0.5f,1); // system
-			else if(chat_lines[r].team)
-				gfx_text_color(0.65f,1,0.65f,1); // team message
-
-			gfx_text_ex(&cursor, chat_lines[r].text, -1);
-		}
-
-		gfx_text_color(1,1,1,1);
-	}
-
-	// render goals
-	if(netobjects.gameobj)
-	{
-		int gametype = netobjects.gameobj->gametype;
-		
-		float whole = 300*gfx_screenaspect();
-		float half = whole/2.0f;
-		
-		gfx_mapscreen(0,0,300*gfx_screenaspect(),300);
-		if(!netobjects.gameobj->sudden_death)
-		{
-			char buf[32];
-			int time = 0;
-			if(netobjects.gameobj->time_limit)
-			{
-				time = netobjects.gameobj->time_limit*60 - ((client_tick()-netobjects.gameobj->round_start_tick)/client_tickspeed());
-
-				if(netobjects.gameobj->game_over)
-					time  = 0;
-			}
-			else
-				time = (client_tick()-netobjects.gameobj->round_start_tick)/client_tickspeed();
-
-			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);
-		}
-
-		if(netobjects.gameobj->sudden_death)
-		{
-			const char *text = "Sudden Death";
-			float w = gfx_text_width(0, 16, text, -1);
-			gfx_text(0, half-w/2, 2, 16, text, -1);
-		}
-
-		// render small score hud
-		if(!(netobjects.gameobj && netobjects.gameobj->game_over) && (gametype == GAMETYPE_TDM || gametype == GAMETYPE_CTF))
-		{
-			for(int t = 0; t < 2; t++)
-			{
-				gfx_blend_normal();
-				gfx_texture_set(-1);
-				gfx_quads_begin();
-				if(t == 0)
-					gfx_setcolor(1,0,0,0.25f);
-				else
-					gfx_setcolor(0,0,1,0.25f);
-				draw_round_rect(whole-40, 300-40-15+t*20, 50, 18, 5.0f);
-				gfx_quads_end();
-
-				char buf[32];
-				str_format(buf, sizeof(buf), "%d", t?netobjects.gameobj->teamscore_blue:netobjects.gameobj->teamscore_red);
-				float w = gfx_text_width(0, 14, buf, -1);
-				
-				if(gametype == GAMETYPE_CTF)
-				{
-					gfx_text(0, whole-20-w/2+5, 300-40-15+t*20, 14, buf, -1);
-					if(netobjects.flags[t])
-					{
- 						if(netobjects.flags[t]->carried_by == -2 || (netobjects.flags[t]->carried_by == -1 && ((client_tick()/10)&1)))
- 						{
-							gfx_blend_normal();
-							gfx_texture_set(data->images[IMAGE_GAME].id);
-							gfx_quads_begin();
-
-							if(t == 0) select_sprite(SPRITE_FLAG_RED);
-							else select_sprite(SPRITE_FLAG_BLUE);
-							
-							float size = 16;					
-							gfx_quads_drawTL(whole-40+5, 300-40-15+t*20+1, size/2, size);
-							gfx_quads_end();
-						}
-						else if(netobjects.flags[t]->carried_by >= 0)
-						{
-							int id = netobjects.flags[t]->carried_by%MAX_CLIENTS;
-							const char *name = client_datas[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 = client_datas[id].render_info;
-							info.size = 18.0f;
-							
-							render_tee(&idlestate, &info, EMOTE_NORMAL, vec2(1,0),
-								vec2(whole-40+10, 300-40-15+9+t*20+1));
-						}
-					}
-				}
-				else
-					gfx_text(0, whole-20-w/2, 300-40-15+t*20, 14, buf, -1);
-			}
-		}
-
-		// render warmup timer
-		if(netobjects.gameobj->warmup)
-		{
-			char buf[256];
-			float w = gfx_text_width(0, 24, "Warmup", -1);
-			gfx_text(0, 150*gfx_screenaspect()+-w/2, 50, 24, "Warmup", -1);
-
-			int seconds = netobjects.gameobj->warmup/SERVER_TICK_SPEED;
-			if(seconds < 5)
-				str_format(buf, sizeof(buf), "%d.%d", seconds, (netobjects.gameobj->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*gfx_screenaspect()+-w/2, 75, 24, buf, -1);
-		}
-	}
-
-	if (menu_active)
-	{
-		menu_render();
-		return;
-	}
-
-	// do emoticon
-	if(emoticon_selector_active)
-		emoticon_selector_render();
-	else
-	{
-		emoticon_selector_mouse = vec2(0,0);	
-	
-		if(emoticon_selected_emote != -1)
-		{
-			send_emoticon(emoticon_selected_emote);
-			emoticon_selected_emote = -1;
-		}
-	}
-	
-	// render debug stuff
-	
-	{
-		float w = 300*gfx_screenaspect();
-		gfx_mapscreen(0, 0, w, 300);
-
-		char buf[512];
-		if(config.cl_showfps)
-		{
-			str_format(buf, sizeof(buf), "%d", (int)(1.0f/client_frametime()));
-			gfx_text(0, w-10-gfx_text_width(0,12,buf,-1), 10, 12, buf, -1);
-		}
-	}
-	
-	if(config.debug && netobjects.local_character && netobjects.local_prev_character)
-	{
-		gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300);
-		
-		/*float speed = distance(vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y),
-			vec2(netobjects.local_character->x, netobjects.local_character->y));*/
-
-		float velspeed = length(vec2(netobjects.local_character->vx/256.0f, netobjects.local_character->vy/256.0f))*50;
-		
-		float ramp = velocity_ramp(velspeed, tuning.velramp_start, tuning.velramp_range, tuning.velramp_curvature);
-		
-		char buf[512];
-		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(),
-			netobjects.local_character->x,
-			netobjects.local_character->y
-		);
-		gfx_text(0, 150, 50, 12, buf, -1);
-	}
-
-
-	bool do_scoreboard = false;
-
-	// if we are dead
-	if(!spectate && (!netobjects.local_character || netobjects.local_character->health < 0))
-		do_scoreboard = true;
-	
-	// if we the game is over
-	if(netobjects.gameobj && netobjects.gameobj->game_over)
-		do_scoreboard = true;
-	
-	// showing motd, skip it
-	if(time_get() < server_motd_time)
-		do_scoreboard = false;
-	
-	// always show if we really want
-	if(scoreboard_active)
-	{
-		server_motd_time = 0; // disables the motd
-		do_scoreboard = true;
-	}
-		
-	// render motd
-	if(!do_scoreboard && time_get() < server_motd_time)
-	{
-		gfx_mapscreen(0, 0, width, height);
-		
-		float h = 800.0f;
-		float w = 650.0f;
-		float x = width/2 - w/2;
-		float y = 150.0f;
-
-		gfx_blend_normal();
-		gfx_texture_set(-1);
-		gfx_quads_begin();
-		gfx_setcolor(0,0,0,0.5f);
-		draw_round_rect(x, y, w, h, 40.0f);
-		gfx_quads_end();
-
-		gfx_text(0, x+40.0f, y+40.0f, 32.0f, server_motd, (int)(w-80.0f));
-	}
-
-	// render scoreboard
-	if(do_scoreboard)
-	{
-		gfx_mapscreen(0, 0, width, height);
-
-		float w = 650.0f;
-
-		if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_DM)
-		{
-			render_scoreboard(width/2-w/2, 150.0f, w, 0, 0);
-			//render_scoreboard(gameobj, 0, 0, -1, 0);
-		}
-		else
-		{
-				
-			if(netobjects.gameobj && netobjects.gameobj->game_over)
-			{
-				const char *text = "DRAW!";
-				if(netobjects.gameobj->teamscore_red > netobjects.gameobj->teamscore_blue)
-					text = "Red Team Wins!";
-				else if(netobjects.gameobj->teamscore_blue > netobjects.gameobj->teamscore_red)
-					text = "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);
-			}
-			
-			render_scoreboard(width/2-w-20, 150.0f, w, 0, "Red Team");
-			render_scoreboard(width/2 + 20, 150.0f, w, 1, "Blue Team");
-		}
-
-		render_goals(width/2-w/2, 150+750+25, w);
-		render_spectators(width/2-w/2, 150+750+25+50+25, w);
-	}
-	
-	{
-		gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300);
-
-		if(client_connection_problems())
-		{
-			const char *text = "Connection Problems...";
-			float w = gfx_text_width(0, 24, text, -1);
-			gfx_text(0, 150*gfx_screenaspect()-w/2, 50, 24, text, -1);
-		}
-		
-		if(time_get() < broadcast_time)
-		{
-			float w = gfx_text_width(0, 14, broadcast_text, -1);
-			gfx_text(0, 150*gfx_screenaspect()-w/2, 35, 14, broadcast_text, -1);
-		}
-		
-		TUNING_PARAMS standard_tuning;
-
-		// render warning about non standard tuning
-		bool flash = time_get()/(time_freq()/2)%2 == 0;
-		if(config.cl_warning_tuning && memcmp(&standard_tuning, &tuning, sizeof(TUNING_PARAMS)) != 0)
-		{
-			const char *text = "Warning! Server is running non-standard tuning.";
-			if(flash)
-				gfx_text_color(1,0.4f,0.4f,1.0f);
-			else
-				gfx_text_color(0.75f,0.2f,0.2f,1.0f);
-			gfx_text(0x0, 5, 40, 6, text, -1);
-			gfx_text_color(1,1,1,1);
-		}
-		
-		// render tuning debugging
-		if(config.dbg_tuning)
-		{
-			float y = 50.0f;
-			int count = 0;
-			for(int i = 0; i < tuning.num(); i++)
-			{
-				char buf[128];
-				float current, standard;
-				tuning.get(i, &current);
-				standard_tuning.get(i, &standard);
-				
-				if(standard == current)
-					gfx_text_color(1,1,1,1.0f);
-				else
-					gfx_text_color(1,0.25f,0.25f,1.0f);
-		
-				float w;
-				float x = 5.0f;
-				
-				str_format(buf, sizeof(buf), "%.2f", standard);
-				x += 20.0f;
-				w = gfx_text_width(0, 5, buf, -1);
-				gfx_text(0x0, x-w, y+count*6, 5, buf, -1);
-
-				str_format(buf, sizeof(buf), "%.2f", current);
-				x += 20.0f;
-				w = gfx_text_width(0, 5, buf, -1);
-				gfx_text(0x0, x-w, y+count*6, 5, buf, -1);
-
-				x += 5.0f;
-				gfx_text(0x0, x, y+count*6, 5, tuning.names[i], -1);
-				
-				count++;
-			}
-			
-			y = y+count*6;
-			
-			gfx_texture_set(-1);
-			gfx_blend_normal();
-			gfx_lines_begin();
-			float height = 50.0f;
-			float pv = 1;
-			for(int i = 0; i < 100; i++)
-			{
-				float speed = i/100.0f * 3000;
-				float ramp = velocity_ramp(speed, tuning.velramp_start, tuning.velramp_range, tuning.velramp_curvature);
-				float rampedspeed = (speed * ramp)/1000.0f;
-				gfx_lines_draw((i-1)*2, y+height-pv*height, i*2, y+height-rampedspeed*height);
-				//gfx_lines_draw((i-1)*2, 200, i*2, 200);
-				pv = rampedspeed;
-			}
-			gfx_lines_end();
-		}
-		
-		gfx_text_color(1,1,1,1);
-	}
-	
-}
-
-
-extern "C" const char *modc_getitemname(int type)
-{
-	return netobj_get_name(type);
-}