about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2007-07-26 19:09:31 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2007-07-26 19:09:31 +0000
commit1d346661640036531a0c06960d4347468572ea53 (patch)
treef9fbe5dbe5486fffa053b2da7bc25b397d915b41
parente588bd3b3b7b1f5f8d9c484d1f28bfe66e6a20f1 (diff)
downloadzcatch-1d346661640036531a0c06960d4347468572ea53.tar.gz
zcatch-1d346661640036531a0c06960d4347468572ea53.zip
fixed latency stuff, some gfx stuff
-rw-r--r--src/engine/client/client.cpp189
-rw-r--r--src/engine/client/gfx.cpp31
-rw-r--r--src/engine/config_variables.h4
-rw-r--r--src/engine/packet.h58
-rw-r--r--src/game/client/game_client.cpp4
-rw-r--r--src/game/client/mapres_tilemap.cpp2
-rw-r--r--src/tools/crapnet.cpp4
7 files changed, 191 insertions, 101 deletions
diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp
index dd7e895d..4c584ba2 100644
--- a/src/engine/client/client.cpp
+++ b/src/engine/client/client.cpp
@@ -65,17 +65,84 @@ void snap_input(void *data, int size)
 // -- snapshot handling ---
 enum
 {
-	SNAP_INCOMMING=2,
-	NUM_SNAPSHOT_TYPES=3,
+	NUM_SNAPSHOT_TYPES=2,
 };
 
-static snapshot_storage snapshots_new;
+struct snapshot_info
+{
+	snapshot_info *prev;
+	snapshot_info *next;
+	
+	int tick;
+	int64 recvtime;
+	snapshot *snap;
+};
+
+static snapshot_info *first_snapshot = 0;
+static snapshot_info *last_snapshot = 0;
+
+static snapshot_info *client_snapshot_add(int tick, int64 time, void *data, int data_size)
+{
+	snapshot_info *holder = (snapshot_info*)mem_alloc(sizeof(snapshot_info) + data_size, 1);
+	holder->tick = tick;
+	holder->recvtime = time;
+	holder->snap = (snapshot *)(holder+1);
+	mem_copy(holder->snap, data, data_size);
+	
+	
+	holder->next =0x0;
+	holder->prev = last_snapshot;
+	if(last_snapshot)
+		last_snapshot->next = holder;
+	else
+		first_snapshot = holder;
+	last_snapshot = holder;
+	
+	return holder;
+}
+
+static snapshot_info *client_snapshot_find(int tick)
+{
+	snapshot_info *current = first_snapshot;
+	while(current)
+	{
+		if(current->tick == tick)
+			return current;
+		current = current->next;
+	}
+	
+	return 0;
+}
+
+static void client_snapshot_purge_until(int tick)
+{
+	snapshot_info *current = first_snapshot;
+	while(current)
+	{
+		snapshot_info *next = current->next;
+		if(current->tick < tick)
+			mem_free(current);
+		else
+			break;
+		
+		current = next;
+		current->prev = 0;
+		first_snapshot = current;
+	}
+	
+	if(!first_snapshot)
+		last_snapshot = 0;
+}
+
+static snapshot_info *snapshots[NUM_SNAPSHOT_TYPES];
 static int current_tick;
-static snapshot *snapshots[NUM_SNAPSHOT_TYPES];
-static char snapshot_data[NUM_SNAPSHOT_TYPES][MAX_SNAPSHOT_SIZE];
 static int recived_snapshots;
 static int64 snapshot_start_time;
 static int64 local_start_time;
+static int64 game_start_time;
+static float latency = 0;
+static int extra_polating = 0;
+static char snapshot_incomming_data[MAX_SNAPSHOT_SIZE];
 
 float client_localtime()
 {
@@ -85,7 +152,7 @@ float client_localtime()
 void *snap_get_item(int snapid, int index, snap_item *item)
 {
 	dbg_assert(snapid >= 0 && snapid < NUM_SNAPSHOT_TYPES, "invalid snapid");
-	snapshot::item *i = snapshots[snapid]->get_item(index);
+	snapshot::item *i = snapshots[snapid]->snap->get_item(index);
 	item->type = i->type();
 	item->id = i->id();
 	return (void *)i->data();
@@ -94,16 +161,16 @@ void *snap_get_item(int snapid, int index, snap_item *item)
 int snap_num_items(int snapid)
 {
 	dbg_assert(snapid >= 0 && snapid < NUM_SNAPSHOT_TYPES, "invalid snapid");
-	return snapshots[snapid]->num_items;
+	return snapshots[snapid]->snap->num_items;
 }
 
 static void snap_init()
 {
-	snapshots[SNAP_INCOMMING] = (snapshot*)snapshot_data[0];
-	snapshots[SNAP_CURRENT] = (snapshot*)snapshot_data[1];
-	snapshots[SNAP_PREV] = (snapshot*)snapshot_data[2];
-	mem_zero(snapshot_data, NUM_SNAPSHOT_TYPES*MAX_SNAPSHOT_SIZE);
+	snapshots[SNAP_CURRENT] = 0;
+	snapshots[SNAP_PREV] = 0;
 	recived_snapshots = 0;
+	game_start_time = -1;
+	
 }
 
 float client_intratick()
@@ -124,9 +191,9 @@ int client_tickspeed()
 void *snap_find_item(int snapid, int type, int id)
 {
 	// TODO: linear search. should be fixed.
-	for(int i = 0; i < snapshots[snapid]->num_items; i++)
+	for(int i = 0; i < snapshots[snapid]->snap->num_items; i++)
 	{
-		snapshot::item *itm = snapshots[snapid]->get_item(i);
+		snapshot::item *itm = snapshots[snapid]->snap->get_item(i);
 		if(itm->type() == type && itm->id() == id)
 			return (void *)itm->data();
 	}
@@ -276,6 +343,7 @@ void client_connect(const char *server_address_str)
 void client::send_info()
 {
 	recived_snapshots = 0;
+	game_start_time = -1;
 
 	msg_pack_start_system(NETMSG_INFO, MSGFLAG_VITAL);
 	msg_pack_string(config.player_name, 128);
@@ -333,6 +401,9 @@ bool client::load_data()
 
 void client::debug_render()
 {
+	if(!config.debug)
+		return;
+		
 	gfx_blend_normal();
 	gfx_texture_set(debug_font);
 	gfx_mapscreen(0,0,gfx_screenwidth(),gfx_screenheight());
@@ -347,9 +418,10 @@ void client::debug_render()
 	}
 	
 	char buffer[512];
-	sprintf(buffer, "send: %8d recv: %8d",
+	sprintf(buffer, "send: %8d recv: %8d latency: %4.0f %c",
 		(current.send_bytes-prev.send_bytes)*10,
-		(current.recv_bytes-prev.recv_bytes)*10);
+		(current.recv_bytes-prev.recv_bytes)*10,
+		latency*1000.0f, extra_polating?'E':' ');
 	gfx_quads_text(10, 10, 16, buffer);
 	
 }
@@ -461,6 +533,30 @@ void client::run(const char *direct_connect_server)
 		frames++;
 		int64 frame_start_time = time_get();
 
+		// switch snapshot
+		if(recived_snapshots >= 3)
+		{
+			snapshot_info *cur = snapshots[SNAP_CURRENT];
+			int64 t = game_start_time + (cur->tick+1)*time_freq()/50;
+			if(latency > 0)
+				t += (int64)(time_freq()*(latency*1.1f));
+
+			if(t < time_get())
+			{
+				snapshot_info *next = snapshots[SNAP_CURRENT]->next;
+				if(next)
+				{
+					snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT];
+					snapshots[SNAP_CURRENT] = next;
+					snapshot_start_time = t;
+				}
+				else
+					extra_polating = 1;
+			}
+			else
+				extra_polating = 0;
+		}
+
 		// send input
 		if(get_state() == STATE_ONLINE)
 		{
@@ -508,7 +604,8 @@ void client::run(const char *direct_connect_server)
 			break;
 
 		// be nice
-		thread_sleep(1);
+		if(config.cpu_throttle)
+			thread_sleep(1);
 		
 		if(reporttime < time_get())
 		{
@@ -704,14 +801,11 @@ void client::process_packet(NETPACKET *packet)
 				{
 					// TODO: clean this up abit
 					const char *d = (const char *)msg_unpack_raw(part_size);
-					mem_copy((char*)snapshots[SNAP_INCOMMING] + part*MAX_SNAPSHOT_PACKSIZE, d, part_size);
+					mem_copy((char*)snapshot_incomming_data + part*MAX_SNAPSHOT_PACKSIZE, d, part_size);
 					snapshot_part++;
 				
 					if(snapshot_part == num_parts)
 					{
-						snapshot *tmp = snapshots[SNAP_PREV];
-						snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT];
-						snapshots[SNAP_CURRENT] = tmp;
 						current_tick = game_tick;
 
 						// decompress snapshot
@@ -722,7 +816,7 @@ void client::process_packet(NETPACKET *packet)
 						unsigned char tmpbuffer2[MAX_SNAPSHOT_SIZE];
 						if(part_size)
 						{
-							int compsize = zerobit_decompress(snapshots[SNAP_INCOMMING], part_size, tmpbuffer);
+							int compsize = zerobit_decompress(snapshot_incomming_data, part_size, tmpbuffer);
 							int intsize = intpack_decompress(tmpbuffer, compsize, tmpbuffer2);
 							deltadata = tmpbuffer2;
 							deltasize = intsize;
@@ -734,44 +828,65 @@ void client::process_packet(NETPACKET *packet)
 						emptysnap.num_items = 0;
 						
 						snapshot *deltashot = &emptysnap;
-						int deltashot_size;
 
 						if(delta_tick >= 0)
 						{
-							void *delta_data;
-							deltashot_size = snapshots_new.get(delta_tick, 0, &delta_data);
-							if(deltashot_size >= 0)
-							{
-								deltashot = (snapshot *)delta_data;
-							}
+							//void *delta_data;
+							snapshot_info *delta_info = client_snapshot_find(delta_tick);
+							//deltashot_size = snapshots_new.get(delta_tick, 0, &delta_data);
+							if(delta_info)
+								deltashot = delta_info->snap;
 							else
 							{
 								// TODO: handle this
 								dbg_msg("client", "error, couldn't find the delta snapshot");
 							}
 						}
-
-						int snapsize = snapshot_unpack_delta(deltashot, (snapshot*)snapshots[SNAP_CURRENT], deltadata, deltasize);
-						//snapshot *shot = (snapshot *)snapshots[SNAP_CURRENT];
-
-						// purge old snapshots					
-						snapshots_new.purge_until(delta_tick);
-						snapshots_new.purge_until(game_tick-50); // TODO: change this to server tickrate
+						
+						unsigned char tmpbuffer3[MAX_SNAPSHOT_SIZE];
+						int snapsize = snapshot_unpack_delta(deltashot, (snapshot*)tmpbuffer3, deltadata, deltasize);
+
+						// purge old snapshots				
+						int purgetick = delta_tick;
+						if(snapshots[SNAP_PREV] && snapshots[SNAP_PREV]->tick < purgetick)
+							purgetick = snapshots[SNAP_PREV]->tick;
+						if(snapshots[SNAP_CURRENT] && snapshots[SNAP_CURRENT]->tick < purgetick)
+							purgetick = snapshots[SNAP_PREV]->tick;
+						client_snapshot_purge_until(purgetick);
+						//client_snapshot_purge_until(game_tick-50);
 						
 						// add new
-						snapshots_new.add(game_tick, time_get(), snapsize, snapshots[SNAP_CURRENT]);
+						snapshot_info *snap = client_snapshot_add(game_tick, time_get(), tmpbuffer3, snapsize);
 						
 						// apply snapshot, cycle pointers
 						recived_snapshots++;
-						snapshot_start_time = time_get();
 						
 						// we got two snapshots until we see us self as connected
+						if(recived_snapshots <= 2)
+						{
+							snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT];
+							snapshots[SNAP_CURRENT] = snap;
+							snapshot_start_time = time_get();
+						}
+						
 						if(recived_snapshots == 2)
 						{
 							local_start_time = time_get();
 							set_state(STATE_ONLINE);
 						}
 						
+						int64 now = time_get();
+						int64 t = now - game_tick*time_freq()/50;
+						if(game_start_time == -1 || t < game_start_time)
+						{
+							dbg_msg("client", "adjusted time");
+							game_start_time = t;
+						}
+						
+						int64 wanted = game_start_time+(game_tick*time_freq())/50;
+						float current_latency = (now-wanted)/(float)time_freq();
+						latency = latency*0.95f+current_latency*0.05f;
+						
 						if(recived_snapshots > 2)
 							modc_newsnapshot();
 						
diff --git a/src/engine/client/gfx.cpp b/src/engine/client/gfx.cpp
index 657f7874..a691863b 100644
--- a/src/engine/client/gfx.cpp
+++ b/src/engine/client/gfx.cpp
@@ -212,6 +212,8 @@ bool gfx_init()
 		textures[i].next = i+1;
 	textures[MAX_TEXTURES-1].next = -1;
 	
+	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	
 	// create null texture, will get id=0
 	gfx_load_texture_raw(4,4,IMG_RGBA,null_texture_data);
 
@@ -221,8 +223,37 @@ bool gfx_init()
 	return true;
 }
 
+video_mode fakemodes[] = {
+	{320,240,8,8,8}, {400,300,8,8,8}, {640,480,8,8,8},
+	{720,400,8,8,8}, {768,576,8,8,8}, {800,600,8,8,8},
+	{1024,600,8,8,8}, {1024,768,8,8,8}, {1152,864,8,8,8},
+	{1280,768,8,8,8}, {1280,800,8,8,8}, {1280,960,8,8,8},
+	{1280,1024,8,8,8}, {1368,768,8,8,8}, {1400,1050,8,8,8},
+	{1440,900,8,8,8}, {1440,1050,8,8,8}, {1600,1000,8,8,8},
+	{1600,1200,8,8,8}, {1680,1050,8,8,8}, {1792,1344,8,8,8},
+	{1800,1440,8,8,8}, {1856,1392,8,8,8}, {1920,1080,8,8,8},
+	{1920,1200,8,8,8}, {1920,1440,8,8,8}, {1920,2400,8,8,8},
+	{2048,1536,8,8,8},
+		
+	{320,240,5,6,5}, {400,300,5,6,5}, {640,480,5,6,5},
+	{720,400,5,6,5}, {768,576,5,6,5}, {800,600,5,6,5},
+	{1024,600,5,6,5}, {1024,768,5,6,5}, {1152,864,5,6,5},
+	{1280,768,5,6,5}, {1280,800,5,6,5}, {1280,960,5,6,5},
+	{1280,1024,5,6,5}, {1368,768,5,6,5}, {1400,1050,5,6,5},
+	{1440,900,5,6,5}, {1440,1050,5,6,5}, {1600,1000,5,6,5},
+	{1600,1200,5,6,5}, {1680,1050,5,6,5}, {1792,1344,5,6,5},
+	{1800,1440,5,6,5}, {1856,1392,5,6,5}, {1920,1080,5,6,5},
+	{1920,1200,5,6,5}, {1920,1440,5,6,5}, {1920,2400,5,6,5},
+	{2048,1536,5,6,5}
+};
+
 int gfx_get_video_modes(video_mode *list, int maxcount)
 {
+	if(config.display_all_modes)
+	{
+		mem_copy(list, fakemodes, sizeof(fakemodes));
+		return min((int)(sizeof(fakemodes)/sizeof(video_mode)), maxcount);
+	}
 	return context.getvideomodes((opengl::videomode *)list, maxcount);
 }
 
diff --git a/src/engine/config_variables.h b/src/engine/config_variables.h
index 23cb30a4..7af316c2 100644
--- a/src/engine/config_variables.h
+++ b/src/engine/config_variables.h
@@ -5,11 +5,15 @@ MACRO_CONFIG_INT(screen_height, 600, 0, 0)
 MACRO_CONFIG_INT(fullscreen, 1, 0, 1)
 MACRO_CONFIG_INT(color_depth, 24, 16, 24)
 MACRO_CONFIG_INT(vsync, 1, 0, 1)
+MACRO_CONFIG_INT(debug, 0, 0, 1)
+MACRO_CONFIG_INT(display_all_modes, 0, 0, 1)
 MACRO_CONFIG_INT(volume, 200, 0, 255)
+MACRO_CONFIG_INT(cpu_throttle, 0, 0, 1)
 MACRO_CONFIG_STR(player_name, 32, "nameless tee")
 MACRO_CONFIG_STR(clan_name, 32, "")
 MACRO_CONFIG_STR(password, 32, "")
 
+
 MACRO_CONFIG_STR(masterserver, 128, "master.teewars.com")
 
 MACRO_CONFIG_INT(sv_port, 8303, 0, 0)
diff --git a/src/engine/packet.h b/src/engine/packet.h
index 485dee42..9c3bb422 100644
--- a/src/engine/packet.h
+++ b/src/engine/packet.h
@@ -102,64 +102,6 @@ public:
 		return -1;
 	}
 };
-/*
-class snapshot_delta_builder
-{
-public:
-	static const int MAX_ITEMS = 512;
-
-	char data[MAX_SNAPSHOT_SIZE];
-	int data_size;
-
-	int offsets[MAX_ITEMS];
-	int num_items;
-
-	int top_size;
-	int top_items;
-
-	int snapnum;
-
-	snapshot_delta_builder()
-	{
-		top_size = 0;
-		top_items = 0;
-		snapnum = 0;
-	}
-
-	void start()
-	{
-		data_size = 0;
-		num_items = 0;
-	}
-
-	int finish(void *snapdata)
-	{
-		snapnum++;
-
-		// flattern and make the snapshot
-		snapshot *snap = (snapshot *)snapdata;
-		snap->data_size = data_size;
-		snap->num_items = num_items;
-		int offset_size = sizeof(int)*num_items;
-		mem_copy(snap->offsets, offsets, offset_size);
-		mem_copy(snap->data_start(), data, data_size);
-		return sizeof(int) + offset_size + data_size;
-	}
-
-	void *new_item(int type, int id, int size)
-	{
-		snapshot::item *obj = (snapshot::item *)(data+data_size);
-		obj->type_and_id = (type<<16)|id;
-		offsets[num_items] = data_size;
-		data_size += sizeof(int) + size;
-		num_items++;
-		dbg_assert(data_size < MAX_SNAPSHOT_SIZE, "too much data");
-		dbg_assert(num_items < MAX_ITEMS, "too many items");
-
-		return &obj->data;
-	}
-};
-*/
 
 class snapshot_builder
 {
diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp
index c500cb70..45bd2ad2 100644
--- a/src/game/client/game_client.cpp
+++ b/src/game/client/game_client.cpp
@@ -951,7 +951,7 @@ static void render_player(obj_player *prev, obj_player *player)
 					if (dir.x < 0.0f)
 						hadokenangle += pi;
 					gfx_quads_setrotation(hadokenangle);
-					float offsety = -data->weapons[iw].muzzleoffsety;
+					//float offsety = -data->weapons[iw].muzzleoffsety;
 					select_sprite(data->weapons[iw].sprite_muzzle[itex].psprite, 0);
 					vec2 diry(-dir.y,dir.x);
 					p = position;
@@ -1707,7 +1707,7 @@ void modc_render()
 						render_tee(&idlestate, skin, vec2(1,0), vec2(offsetx + x+90, offsets[player->team]+24));
 
 						sprintf(buf, "%4d", player->latency);
-						float tw = gfx_pretty_text_width(48.0f, buf);
+						//float tw = gfx_pretty_text_width(48.0f, buf);
 						gfx_pretty_text(offsetx + x + 240, offsets[player->team], 48, buf);
 
 						offsets[player->team] += 58.0f;
diff --git a/src/game/client/mapres_tilemap.cpp b/src/game/client/mapres_tilemap.cpp
index 357e8870..bc7cbe6d 100644
--- a/src/game/client/mapres_tilemap.cpp
+++ b/src/game/client/mapres_tilemap.cpp
@@ -40,8 +40,6 @@ void tilemap_render(float scale, int fg)
 		{
 			gfx_texture_set(img_get(tmap->image));
 			
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-			
 			if(!batches[t])
 			{
 				gfx_quads_begin();
diff --git a/src/tools/crapnet.cpp b/src/tools/crapnet.cpp
index f87803b5..ba7b55b9 100644
--- a/src/tools/crapnet.cpp
+++ b/src/tools/crapnet.cpp
@@ -102,8 +102,8 @@ int run(int port, netaddr4 dest)
 				// update lag
 				double flux = rand()/(double)RAND_MAX;
 				int ms_spike = 0;
-				int ms_flux = 100;
-				int ms_ping = 50;
+				int ms_flux = 20;
+				int ms_ping = 20;
 				current_latency = ((time_freq()*ms_ping)/1000) + (int64)(((time_freq()*ms_flux)/1000)*flux); // 50ms
 				
 				if((p->id%100) == 0)