about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--datasrc/teewars.ds15
-rw-r--r--src/engine/client/client.c105
-rw-r--r--src/engine/client/gfx.c12
-rw-r--r--src/engine/client/srvbrowse.c20
-rw-r--r--src/engine/config.c23
-rw-r--r--src/engine/config_variables.h2
-rw-r--r--src/engine/engine.c65
-rw-r--r--src/engine/engine.h4
-rw-r--r--src/engine/interface.h5
-rw-r--r--src/engine/server/server.c29
-rw-r--r--src/engine/system.c33
-rw-r--r--src/engine/system.h2
-rw-r--r--src/game/client/game_client.cpp5
-rw-r--r--src/game/client/menu2.cpp45
-rw-r--r--src/game/game_protocol.h6
15 files changed, 200 insertions, 171 deletions
diff --git a/datasrc/teewars.ds b/datasrc/teewars.ds
index 2a28d89e..cb08ab85 100644
--- a/datasrc/teewars.ds
+++ b/datasrc/teewars.ds
@@ -349,21 +349,6 @@ projectileparticles {
 	}
 }
 
-playerstats {
-	dm {
-		maxhealth 10
-		maxarmor 10
-	}
-	tdm {
-		maxhealth 10
-		maxarmor 10
-	}
-	ctf {
-		maxhealth 10
-		maxarmor 10
-	}
-}
-
 weapons {
 	hammer {
 		sprite_body sprites.game.weapon_hammer_body
diff --git a/src/engine/client/client.c b/src/engine/client/client.c
index df53d142..3246a7d6 100644
--- a/src/engine/client/client.c
+++ b/src/engine/client/client.c
@@ -6,6 +6,7 @@
 #include <math.h>
 
 #include <engine/system.h>
+#include <engine/engine.h>
 #include <engine/interface.h>
 #include "ui.h"
 
@@ -301,7 +302,6 @@ static void client_send_error(const char *error)
 	*/
 }
 
-
 void client_rcon(const char *cmd)
 {
 	msg_pack_start_system(NETMSG_CMD, MSGFLAG_VITAL);
@@ -452,10 +452,10 @@ static void client_debug_render()
 	static int64 last_snap = 0;
 	static float frametime_avg = 0;
 	char buffer[512];
-
+	
 	if(!config.debug)
 		return;
-		
+	
 	gfx_blend_normal();
 	gfx_texture_set(debug_font);
 	gfx_mapscreen(0,0,gfx_screenwidth(),gfx_screenheight());
@@ -478,7 +478,6 @@ static void client_debug_render()
 		(int)(1.0f/frametime_avg));
 	gfx_quads_text(2, 2, 16, buffer);
 	
-	
 	/* render graphs */
 	gfx_mapscreen(0,0,400.0f,300.0f);
 	graph_render(&predict_graph, 300, 10, 90, 50);
@@ -596,12 +595,6 @@ static void client_process_packet(NETPACKET *packet)
 					dbg_msg("client/network", "loading done");
 					client_send_ready();
 					modc_connected();
-					
-					/*
-					modc_entergame();
-					client_send_entergame();
-					*/
-					/*client_on_enter_game();*/
 				}
 				else
 				{
@@ -739,11 +732,6 @@ static void client_process_packet(NETPACKET *packet)
 						
 						/* add new */
 						snapstorage_add(&snapshot_storage, game_tick, time_get(), snapsize, (SNAPSHOT*)tmpbuffer3);
-						/*SNAPSTORAGE_HOLDER *snap = client_snapshot_add(game_tick, time_get(), tmpbuffer3, snapsize); */
-						
-						/*int ncrc = snapshot_crc((snapshot*)tmpbuffer3); */
-						/*if(crc != ncrc) */
-						/*	dbg_msg("client", "client snapshot crc failure %d %d", crc, ncrc); */
 						
 						/* apply snapshot, cycle pointers */
 						recived_snapshots++;
@@ -818,7 +806,7 @@ static void client_pump_network()
 		client_process_packet(&packet);
 }
 
-static void client_run(const char *direct_connect_server)
+static void client_run()
 {
 	NETADDR4 bindaddr;
 	int64 reporttime = time_get();
@@ -832,15 +820,13 @@ static void client_run(const char *direct_connect_server)
 	if(!gfx_init())
 		return;
 
-	snd_init(); /* sound is allowed to fail */
+	/* sound is allowed to fail */
+	snd_init();
 	
 	/* load data */
 	if(!client_load_data())
 		return;
 
-	/* init menu */
-	modmenu_init(); /* TODO: remove */
-	
 	/* init the mod */
 	modc_init();
 	dbg_msg("client", "version %s", modc_net_version());
@@ -850,14 +836,15 @@ static void client_run(const char *direct_connect_server)
 	net = netclient_open(bindaddr, 0);
 	
 	/* connect to the server if wanted */
-	if(direct_connect_server)
-		client_connect(direct_connect_server);
+	if(config.cl_connect)
+		client_connect(config.cl_connect);
 		
 	inp_mouse_mode_relative();
 	
 	while (1)
 	{	
 		int64 frame_start_time = time_get();
+		frames++;
 
 		/* switch snapshot */
 		if(recived_snapshots >= 3)
@@ -865,9 +852,6 @@ static void client_run(const char *direct_connect_server)
 			int repredict = 0;
 			int64 now = st_get(&game_time, time_get());
 
-			frames++;
-
-			/*int64 now = time_get(); */
 			while(1)
 			{
 				SNAPSTORAGE_HOLDER *cur = snapshots[SNAP_CURRENT];
@@ -923,8 +907,6 @@ static void client_run(const char *direct_connect_server)
 					client_send_input();
 				}
 			}
-			
-			/*intrapredtick = current_predtick */
 
 			/* only do sane predictions */
 			if(repredict)
@@ -968,7 +950,7 @@ static void client_run(const char *direct_connect_server)
 		if(inp_key_down(config.key_screenshot))
 			gfx_screenshot();
 
-		/* panic button */
+		/* some debug keys */
 		if(config.debug)
 		{
 			if(inp_key_pressed(KEY_F1))
@@ -1034,8 +1016,6 @@ static void client_run(const char *direct_connect_server)
 	modc_shutdown();
 	client_disconnect();
 
-	modmenu_shutdown(); /* TODO: remove this */
-	
 	gfx_shutdown();
 	snd_shutdown();
 }
@@ -1043,70 +1023,17 @@ static void client_run(const char *direct_connect_server)
 
 int editor_main(int argc, char **argv);
 
-/*client main_client; */
-/*
-const char *user_directory()
-{
-	static char path[512] = {0};
-	
-}*/
-
-
-
 int main(int argc, char **argv)
 {
-#ifdef CONF_PLATFORM_MACOSX
-	const char *config_filename = "~/.teewars";
-#else
-	const char *config_filename = "default.cfg";
-#endif
-	int i;
-	const char *direct_connect_server = 0x0;
-	int editor = 0;
-
+	/* init the engine */
 	dbg_msg("client", "starting...");
+	engine_init("Teewars", argc, argv);
 	
-	config_reset();
-
-	for(i = 1; i < argc; i++)
-	{
-		if(argv[i][0] == '-' && argv[i][1] == 'f' && argv[i][2] == 0 && argc - i > 1)
-		{
-			config_filename = argv[i+1];
-			i++;
-		}
-	}
-
-	config_load(config_filename);
-
-	snd_set_master_volume(config.volume / 255.0f);
-
-	/* init network, need to be done first so we can do lookups */
-	net_init();
-
-	/* parse arguments */
-	for(i = 1; i < argc; i++)
-	{
-		if(argv[i][0] == '-' && argv[i][1] == 'c' && argv[i][2] == 0 && argc - i > 1)
-		{
-			/* -c SERVER:PORT */
-			i++;
-			direct_connect_server = argv[i];
-		}
-		else if(argv[i][0] == '-' && argv[i][1] == 'e' && argv[i][2] == 0)
-		{
-			editor = 1;
-		}
-		else
-			config_set(argv[i]);
-	}
-	
-	if(editor)
+	if(config.cl_editor)
 		editor_main(argc, argv);
 	else
-	{
-		/* start the client */
-		client_run(direct_connect_server);
-	}
+		client_run();
+		
+	engine_writeconfig();
 	return 0;
 }
diff --git a/src/engine/client/gfx.c b/src/engine/client/gfx.c
index 31a87611..58dc050b 100644
--- a/src/engine/client/gfx.c
+++ b/src/engine/client/gfx.c
@@ -3,6 +3,7 @@
 
 #include <engine/system.h>
 #include <engine/interface.h>
+#include <engine/engine.h>
 #include <engine/config.h>
 #include <engine/keys.h>
 
@@ -530,16 +531,18 @@ void gfx_swap()
 		
 		/* find filename */
 		{
-			char filename[64];
+			char wholepath[1024];
+			char filename[128];
 			static int index = 1;
 			png_t png;
 
 			for(; index < 1000; index++)
 			{
 				IOHANDLE io;
-				sprintf(filename, "screenshot%04d.png", index);
-				io = io_open(filename, IOFLAG_READ);
+				sprintf(filename, "screenshots/screenshot%04d.png", index);
+				engine_savepath(filename, wholepath, sizeof(wholepath));
 				
+				io = io_open(wholepath, IOFLAG_READ);
 				if(io)
 					io_close(io);
 				else
@@ -547,7 +550,8 @@ void gfx_swap()
 			}
 		
 			/* save png */
-			png_open_file_write(&png, filename);
+			dbg_msg("client", "saved screenshot to '%s'", wholepath);
+			png_open_file_write(&png, wholepath);
 			png_set_data(&png, w, h, 8, PNG_TRUECOLOR, (unsigned char *)pixel_data);
 			png_close_file(&png);
 		}
diff --git a/src/engine/client/srvbrowse.c b/src/engine/client/srvbrowse.c
index 471fdfd6..b3ff635a 100644
--- a/src/engine/client/srvbrowse.c
+++ b/src/engine/client/srvbrowse.c
@@ -94,6 +94,20 @@ static int client_serverbrowse_sort_compare_ping(const void *ai, const void *bi)
 	return a->info.latency > b->info.latency;
 }
 
+static int client_serverbrowse_sort_compare_gametype(const void *ai, const void *bi)
+{
+	SERVERENTRY *a = serverlist[*(const int*)ai];
+	SERVERENTRY *b = serverlist[*(const int*)bi];
+	return a->info.game_type > b->info.game_type;
+}
+
+static int client_serverbrowse_sort_compare_progression(const void *ai, const void *bi)
+{
+	SERVERENTRY *a = serverlist[*(const int*)ai];
+	SERVERENTRY *b = serverlist[*(const int*)bi];
+	return a->info.progression > b->info.progression;
+}
+
 static int client_serverbrowse_sort_compare_numplayers(const void *ai, const void *bi)
 {
 	SERVERENTRY *a = serverlist[*(const int*)ai];
@@ -139,7 +153,7 @@ static void client_serverbrowse_filter()
 
 static int client_serverbrowse_sorthash()
 {
-	int i = config.b_sort&3;
+	int i = config.b_sort&0xf;
 	i |= config.b_filter_empty<<4;
 	i |= config.b_filter_full<<5;
 	i |= config.b_filter_pw<<6;
@@ -162,6 +176,10 @@ static void client_serverbrowse_sort()
 		qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_map);
 	else if(config.b_sort == BROWSESORT_NUMPLAYERS)
 		qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_numplayers);
+	else if(config.b_sort == BROWSESORT_GAMETYPE)
+		qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_gametype);
+	else if(config.b_sort == BROWSESORT_PROGRESSION)
+		qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_progression);
 	
 	/* set indexes */
 	for(i = 0; i < num_sorted_servers; i++)
diff --git a/src/engine/config.c b/src/engine/config.c
index eabb8583..97241e48 100644
--- a/src/engine/config.c
+++ b/src/engine/config.c
@@ -135,18 +135,7 @@ void config_set(const char *line)
 
 void config_load(const char *filename)
 {
-	char full_path[1024];
 	IOHANDLE file;
-	if (filename[0] == '~')
-	{
-		char *home = getenv("HOME");
-		if (home)
-		{
-			sprintf(full_path, "%s%s", home, filename+1);
-			filename = full_path;
-		}
-	}
-
 	dbg_msg("config/load", "loading %s", filename);
 	file = io_open(filename, IOFLAG_READ);
 	
@@ -165,19 +154,7 @@ void config_load(const char *filename)
 
 void config_save(const char *filename)
 {
-	char full_path[1024];
 	IOHANDLE file;
-	if (filename[0] == '~')
-	{
-		char *home = getenv("HOME");
-		if (home)
-		{
-			sprintf(full_path, "%s%s", home, filename+1);
-			filename = full_path;
-		}
-	}
-
-
 	dbg_msg("config/save", "saving config to %s", filename);
 
 	file = io_open(filename, IOFLAG_WRITE);
diff --git a/src/engine/config_variables.h b/src/engine/config_variables.h
index eb2837af..0bc0c89c 100644
--- a/src/engine/config_variables.h
+++ b/src/engine/config_variables.h
@@ -13,6 +13,8 @@ MACRO_CONFIG_STR(rcon_password, 32, "")
 MACRO_CONFIG_INT(debug, 0, 0, 1)
 MACRO_CONFIG_INT(stress, 0, 0, 0)
 MACRO_CONFIG_STR(cl_stress_server, 32, "localhost")
+MACRO_CONFIG_STR(cl_connect, 32, "")
+MACRO_CONFIG_INT(cl_editor, 0, 0, 1)
 
 MACRO_CONFIG_STR(b_filter_string, 64, "")
 
diff --git a/src/engine/engine.c b/src/engine/engine.c
new file mode 100644
index 00000000..f3bee450
--- /dev/null
+++ b/src/engine/engine.c
@@ -0,0 +1,65 @@
+#include <string.h>
+#include <stdio.h>
+
+#include <engine/system.h>
+#include <engine/interface.h>
+#include <engine/config.h>
+
+static char application_save_path[512] = {0};
+
+const char *engine_savepath(const char *filename, char *buffer, int max)
+{
+	snprintf(buffer, max, "%s/%s", application_save_path, filename);
+	return buffer;
+}
+
+void engine_init(const char *appname, int argc, char **argv)
+{
+	/* init the network */
+	net_init();
+
+	/* create storage location */
+	{
+		char path[1024] = {0};
+		fs_storage_path(appname, application_save_path, sizeof(application_save_path));
+		if(fs_makedir(application_save_path) == 0)
+		{		
+			strcpy(path, application_save_path);
+			strcat(path, "/screenshots");
+			fs_makedir(path);
+		}
+	}
+	
+	/* reset the config */
+	config_reset();
+	
+	/* load the configuration */
+	{
+		int i;
+		const char *config_filename = "default.cfg";
+		char buf[1024];
+		for(i = 1; i < argc; i++)
+		{
+			if(argv[i][0] == '-' && argv[i][1] == 'f' && argv[i][2] == 0 && argc - i > 1)
+			{
+				config_filename = argv[i+1];
+				i++;
+			}
+		}
+
+		config_load(engine_savepath(config_filename, buf, sizeof(buf)));
+	}
+	
+	/* search arguments for overrides */
+	{
+		int i;
+		for(i = 1; i < argc; i++)
+			config_set(argv[i]);
+	}
+}
+
+void engine_writeconfig()
+{
+	char buf[1024];
+	config_save(engine_savepath("default.cfg", buf, sizeof(buf)));
+}
diff --git a/src/engine/engine.h b/src/engine/engine.h
new file mode 100644
index 00000000..7b93ae85
--- /dev/null
+++ b/src/engine/engine.h
@@ -0,0 +1,4 @@
+
+const char *engine_savepath(const char *filename, char *buffer, int max);
+void engine_init(const char *appname, int argc, char **argv);
+void engine_writeconfig();
diff --git a/src/engine/interface.h b/src/engine/interface.h
index 0eaabc20..277c6d16 100644
--- a/src/engine/interface.h
+++ b/src/engine/interface.h
@@ -35,10 +35,11 @@ enum
 	CLIENTSTATE_ONLINE,
 	CLIENTSTATE_QUITING,
 	
-	BROWSESORT_NONE = 0,
-	BROWSESORT_NAME,
+	BROWSESORT_NAME = 0,
 	BROWSESORT_PING,
 	BROWSESORT_MAP,
+	BROWSESORT_GAMETYPE,
+	BROWSESORT_PROGRESSION,
 	BROWSESORT_NUMPLAYERS
 };
 
diff --git a/src/engine/server/server.c b/src/engine/server/server.c
index b1bf5e4d..8b591de6 100644
--- a/src/engine/server/server.c
+++ b/src/engine/server/server.c
@@ -4,7 +4,7 @@
 
 #include <engine/system.h>
 #include <engine/config.h>
-
+#include <engine/engine.h>
 #include <engine/interface.h>
 
 #include <engine/protocol.h>
@@ -29,7 +29,6 @@ static NETADDR4 master_server;
 
 static char current_map[64];
 
-
 void *snap_new_item(int type, int id, int size)
 {
 	dbg_assert(type >= 0 && type <=0xffff, "incorrect type");
@@ -822,32 +821,8 @@ static int server_run()
 
 int main(int argc, char **argv)
 {
-#ifdef CONF_PLATFORM_MACOSX
-	const char *config_filename = "~/.teewars";
-#else
-	const char *config_filename = "default.cfg";
-#endif
-	int i;
-
 	dbg_msg("server", "starting...");
-
-	config_reset();
-
-	for(i = 1; i < argc; i++)
-	{
-		if(argv[i][0] == '-' && argv[i][1] == 'f' && argv[i][2] == 0 && argc - i > 1)
-		{
-			config_filename = argv[i+1];
-			i++;
-		}
-	}
-
-	config_load(config_filename);
-
-	/* parse arguments */
-	for(i = 1; i < argc; i++)
-		config_set(argv[i]);
-
+	engine_init("Teewars", argc, argv);
 	server_run();
 	return 0;
 }
diff --git a/src/engine/system.c b/src/engine/system.c
index 71f5b545..a6fb362c 100644
--- a/src/engine/system.c
+++ b/src/engine/system.c
@@ -2,6 +2,7 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
+#include <ctype.h>
 #include <time.h>
 
 #include "detect.h"
@@ -12,6 +13,7 @@
 	#include <unistd.h>
 
 	/* unix net includes */
+	#include <sys/stat.h>
 	#include <sys/types.h>
 	#include <sys/socket.h>
 	#include <sys/ioctl.h>
@@ -643,6 +645,37 @@ int fs_listdir(const char *dir, fs_listdir_callback cb, void *user)
 #endif
 }
 
+int fs_storage_path(const char *appname, char *path, int max)
+{
+#if defined(CONF_FAMILY_WINDOWS)
+	#error not implement
+#else
+	char *home = getenv("HOME");
+	int i;
+	if(!home)
+		return 0;
+	
+	snprintf(path, max, "%s/.%s", home, appname);
+	for(i = strlen(home)+2; path[i]; i++)
+		path[i] = tolower(path[i]);
+	
+	return 1;
+#endif
+}
+
+int fs_makedir(const char *path)
+{
+#if defined(CONF_FAMILY_WINDOWS)
+	#error not implement
+#else
+	if(mkdir(path, 0755) == 0)
+		return 0;
+	if(errno == EEXIST)
+		return 0;
+	return 1;
+#endif
+}
+
 void swap_endian(void *data, unsigned elem_size, unsigned num)
 {
 	char *src = (char*) data;
diff --git a/src/engine/system.h b/src/engine/system.h
index a20277a3..e8c46e09 100644
--- a/src/engine/system.h
+++ b/src/engine/system.h
@@ -515,6 +515,8 @@ int net_init();
 /* NOT DOCUMENTED */
 typedef void (*fs_listdir_callback)(const char *name, int is_dir, void *user);
 int fs_listdir(const char *dir, fs_listdir_callback cb, void *user);
+int fs_storage_path(const char *appname, char *path, int max);
+int fs_makedir(const char *path);
 int net_addr4_cmp(const NETADDR4 *a, const NETADDR4 *b);
 
 void mem_debug_dump();
diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp
index 8b6231b5..1e0c81e6 100644
--- a/src/game/client/game_client.cpp
+++ b/src/game/client/game_client.cpp
@@ -583,6 +583,9 @@ static void skinscan(const char *name, int is_dir, void *user)
 
 extern "C" void modc_init()
 {
+	// init menu
+	modmenu_init();
+	
 	// setup sound channels
 	snd_set_channel(CHN_GUI, 1.0f, 0.0f);
 	snd_set_channel(CHN_MUSIC, 1.0f, 0.0f);
@@ -634,6 +637,8 @@ extern "C" void modc_entergame()
 
 extern "C" void modc_shutdown()
 {
+	// shutdown the menu
+	modmenu_shutdown();
 }
 
 static void process_events(int s)
diff --git a/src/game/client/menu2.cpp b/src/game/client/menu2.cpp
index 5fed04f8..2e44df6b 100644
--- a/src/game/client/menu2.cpp
+++ b/src/game/client/menu2.cpp
@@ -15,6 +15,7 @@ extern "C" {
 
 #include "../mapres.h"
 #include "../version.h"
+#include "../game_protocol.h"
 
 #include "mapres_image.h"
 #include "mapres_tilemap.h"
@@ -680,18 +681,23 @@ static void menu2_render_serverbrowser(RECT main_view)
 		FIXED=1,
 		SPACER=2,
 		
-		COL_START=0,
+		COL_FLAGS=0,
 		COL_NAME,
+		COL_GAMETYPE,
 		COL_MAP,
 		COL_PLAYERS,
 		COL_PING,
+		COL_PROGRESS,
 	};
 	
 	static column cols[] = {
-		{0, 			BROWSESORT_NONE,		" ",		-1, 30.0f, 0, {0}, {0}},
+		{-1,			-1,						" ",		-1, 10.0f, 0, {0}, {0}},
+		{COL_FLAGS,		-1,						" ",		-1, 15.0f, 0, {0}, {0}},
 		{COL_NAME,		BROWSESORT_NAME,		"Name",		0, 300.0f, 0, {0}, {0}},
+		{COL_GAMETYPE,	BROWSESORT_GAMETYPE,	"Type",		1, 50.0f, 0, {0}, {0}},
 		{COL_MAP,		BROWSESORT_MAP,			"Map", 		1, 100.0f, 0, {0}, {0}},
 		{COL_PLAYERS,	BROWSESORT_NUMPLAYERS,	"Players",	1, 60.0f, 0, {0}, {0}},
+		{COL_PROGRESS,	BROWSESORT_PROGRESSION,	"%",		1, 40.0f, FIXED, {0}, {0}},
 		{COL_PING,		BROWSESORT_PING,		"Ping",		1, 40.0f, FIXED, {0}, {0}},
 	};
 	
@@ -731,7 +737,10 @@ static void menu2_render_serverbrowser(RECT main_view)
 	for(int i = 0; i < num_cols; i++)
 	{
 		if(ui2_do_button(cols[i].caption, cols[i].caption, config.b_sort == cols[i].sort, &cols[i].rect, ui2_draw_grid_header, 0))
-			config.b_sort = cols[i].sort;
+		{
+			if(cols[i].sort != -1)
+				config.b_sort = cols[i].sort;
+		}
 	}
 	
 	
@@ -754,6 +763,8 @@ static void menu2_render_serverbrowser(RECT main_view)
 		start = 0;
 	
 	//int r = -1;
+	int new_selected = selected_index;
+	
 	for (int i = start, k = 0; i < num_servers && k < num; i++, k++)
 	{
 		int item_index = i;
@@ -764,8 +775,10 @@ static void menu2_render_serverbrowser(RECT main_view)
 		
 		if(l)
 		{
+			// selected server, draw the players on it
 			RECT whole;
 			int h = (item->num_players+2)/3;
+			
 			ui2_hsplit_t(&view, 25.0f+h*15.0f, &whole, &view);
 			
 			RECT r = whole;
@@ -798,8 +811,8 @@ static void menu2_render_serverbrowser(RECT main_view)
 				}
 			}
 			
-			k += h;
-			i += h;
+			k += h*3/4;
+			i += h*3/4;
 		}
 		else
 			ui2_hsplit_t(&view, 20.0f, &row, &view);
@@ -816,8 +829,10 @@ static void menu2_render_serverbrowser(RECT main_view)
 			int s = 0;
 			int id = cols[c].id;
 
-			if(c == 0)
+			if(id == COL_FLAGS)
 			{
+				if(item->flags&1)
+					s = ui2_do_button(item, "P", l, &button, ui2_draw_grid_cell, 0);
 			}
 			else if(id == COL_NAME)
 				s = ui2_do_button(item, item->name, l, &button, ui2_draw_grid_cell, 0);
@@ -833,15 +848,31 @@ static void menu2_render_serverbrowser(RECT main_view)
 				sprintf(temp, "%i", item->latency);
 				s = ui2_do_button(item, temp, l, &button, ui2_draw_grid_cell, 0);
 			}
+			else if(id == COL_PROGRESS)
+			{
+				sprintf(temp, "%i", item->progression);
+				s = ui2_do_button(item, temp, l, &button, ui2_draw_grid_cell, 0);
+			}
+			else if(id == COL_GAMETYPE)
+			{
+				const char *type = "???";
+				if(item->game_type == GAMETYPE_DM) type = "DM";
+				else if(item->game_type == GAMETYPE_TDM) type = "TDM";
+				else if(item->game_type == GAMETYPE_CTF) type = "CTF";
+				s = ui2_do_button(item, type, l, &button, ui2_draw_grid_cell, 0);
+			}
 			
 			if(s)
 			{
-				selected_index = item_index;
+				new_selected = item_index;
 				strncpy(address, item->address, sizeof(address));
 			}
 		}
 	}
 	
+	selected_index = new_selected;
+
+	
 	// render quick search
 	RECT button;
 	ui2_hsplit_t(&filters, 20.0f, &button, &filters);
diff --git a/src/game/game_protocol.h b/src/game/game_protocol.h
index 982a14b2..7c9f648f 100644
--- a/src/game/game_protocol.h
+++ b/src/game/game_protocol.h
@@ -73,9 +73,9 @@ enum
 	STATE_IN_MENU,
 	STATE_CHATTING,
 
-	//GAMETYPE_DM=0,
-	//GAMETYPE_TDM,
-	//GAMETYPE_CTF,
+	GAMETYPE_DM=0,
+	GAMETYPE_TDM,
+	GAMETYPE_CTF,
 };
 
 struct player_input