about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2007-12-18 20:12:25 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2007-12-18 20:12:25 +0000
commitf3a60b6df95aafb460ad2705f83453b325b84adb (patch)
tree89ad1f2894366e021faeb0f3d41a1c4cb8aa4eeb /src
parentbde0c6c6f82c8edfac79c34e46f0009c6cc80241 (diff)
downloadzcatch-f3a60b6df95aafb460ad2705f83453b325b84adb.tar.gz
zcatch-f3a60b6df95aafb460ad2705f83453b325b84adb.zip
changed how the input snapping works. fixed a bug in the projectile rendering when using 25 snapping rate
Diffstat (limited to 'src')
-rw-r--r--src/engine/client/ec_client.c33
-rw-r--r--src/engine/e_interface.h7
-rw-r--r--src/game/client/gc_client.cpp134
3 files changed, 97 insertions, 77 deletions
diff --git a/src/engine/client/ec_client.c b/src/engine/client/ec_client.c
index 855a334e..7251c1d8 100644
--- a/src/engine/client/ec_client.c
+++ b/src/engine/client/ec_client.c
@@ -62,6 +62,7 @@ static int current_recv_tick = 0;
 /* current time */
 static int current_tick = 0;
 static float intratick = 0;
+static float ticktime = 0;
 
 /* predicted time */
 static int current_predtick = 0;
@@ -191,17 +192,7 @@ GRAPH intra_graph;
 GRAPH predict_graph;
 
 /* --- input snapping --- */
-static int input_data[MAX_INPUT_SIZE] = {0};
-static int input_data_size;
-static int input_is_changed = 1;
 static GRAPH input_late_graph;
-void snap_input(void *data, int size)
-{
-	if(input_data_size != size || memcmp(input_data, data, size))
-		input_is_changed = 1;
-	mem_copy(input_data, data, size);
-	input_data_size = size;
-}
 
 /* -- snapshot handling --- */
 enum
@@ -248,6 +239,7 @@ int snap_num_items(int snapid)
 /* ------ time functions ------ */
 float client_intratick() { return intratick; }
 float client_intrapredtick() { return intrapredtick; }
+float client_ticktime() { return ticktime; }
 int client_tick() { return current_tick; }
 int client_predtick() { return current_predtick; }
 int client_tickspeed() { return SERVER_TICK_SPEED; }
@@ -315,25 +307,26 @@ int client_connection_problems()
 static void client_send_input()
 {
 	int64 now = time_get();	
-	int i;
+	int i, size;
 
 	if(current_predtick <= 0)
 		return;
-		
+	
+	/* fetch input */	
+	size = modc_snap_input(inputs[current_input].data);
+	
 	msg_pack_start_system(NETMSG_INPUT, 0);
 	msg_pack_int(ack_game_tick);
 	msg_pack_int(current_predtick);
-	msg_pack_int(input_data_size);
+	msg_pack_int(size);
 
 	inputs[current_input].tick = current_predtick;
 	inputs[current_input].game_time = st_get(&predicted_time, now);
 	inputs[current_input].time = now;
-	
-	for(i = 0; i < input_data_size/4; i++)
-	{
-		inputs[current_input].data[i] = input_data[i];
-		msg_pack_int(input_data[i]);
-	}
+
+	/* pack it */	
+	for(i = 0; i < size/4; i++)
+		msg_pack_int(inputs[current_input].data[i]);
 	
 	current_input++;
 	current_input%=200;
@@ -875,6 +868,7 @@ static void client_update()
 	if(client_state() != CLIENTSTATE_OFFLINE && recived_snapshots >= 3)
 	{
 		int repredict = 0;
+		int64 freq = time_freq();
 		int64 now = st_get(&game_time, time_get());
 		int64 pred_now = st_get(&predicted_time, time_get());
 
@@ -917,6 +911,7 @@ static void client_update()
 			static float last_intrapred = 0;
 
 			intratick = (now - prevtick_start) / (float)(curtick_start-prevtick_start);
+			ticktime = (now - curtick_start) / (freq/(float)SERVER_TICK_SPEED);
 
 			graph_add(&intra_graph, intratick*0.25f);
 
diff --git a/src/engine/e_interface.h b/src/engine/e_interface.h
index f5920411..930d196a 100644
--- a/src/engine/e_interface.h
+++ b/src/engine/e_interface.h
@@ -742,6 +742,7 @@ void modc_statechange(int new_state, int old_state);
 void modc_connected();
 void modc_message(int msg);
 void modc_predict();
+int modc_snap_input(int *data);
 
 void mods_message(int msg, int client_id);
 void mods_connected(int client_id);
@@ -817,7 +818,11 @@ int client_send_msg();
 /* client */
 int client_tick();
 int client_predtick();
-float client_intratick();
+
+float client_intratick(); 
+
+float client_ticktime();
+
 float client_intrapredtick();
 int client_tickspeed();
 float client_frametime();
diff --git a/src/game/client/gc_client.cpp b/src/game/client/gc_client.cpp
index 88562a27..139181bb 100644
--- a/src/game/client/gc_client.cpp
+++ b/src/game/client/gc_client.cpp
@@ -30,6 +30,9 @@ enum
 
 data_container *data = 0x0;
 
+static player_input input_data = {0};
+static int input_target_lock = 0;
+
 extern void modmenu_render();
 extern void menu_init();
 
@@ -63,7 +66,7 @@ const obj_player_info *local_info = 0;
 static const obj_flag *flags[2] = {0,0};
 const obj_game *gameobj = 0;
 
-static int picked_up_weapon = 0;
+static int picked_up_weapon = -1;
 
 static struct client_data
 {
@@ -967,7 +970,7 @@ static void render_projectile(const obj_projectile *prev, const obj_projectile *
 	if(current->type != WEAPON_ROCKET)
 		gravity = -100;
 
-	float ct = (client_tick()-current->start_tick)/(float)SERVER_TICK_SPEED + client_intratick()*1/(float)SERVER_TICK_SPEED;
+	float ct = (client_tick()-current->start_tick)/(float)SERVER_TICK_SPEED + client_ticktime()*1/(float)SERVER_TICK_SPEED;
 	vec2 startpos(current->x, current->y);
 	vec2 startvel(current->vx, current->vy);
 	vec2 pos = calc_pos(startpos, startvel, gravity, ct);
@@ -2247,12 +2250,14 @@ void render_world(float center_x, float center_y, float zoom)
 	damageind.render();
 }
 
-static void do_input(int *v, int key)
+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 render_game()
@@ -2422,70 +2427,40 @@ void render_game()
 		snd_set_listener_pos(local_character_pos.x, local_character_pos.y);
 	}
 
-	// snap input
+	// update some input
 	{
-		static player_input input = {0};
-
-		input.target_x = (int)mouse_pos.x;
-		input.target_y = (int)mouse_pos.y;
-
-		if(chat_mode != CHATMODE_NONE)
-			input.state = STATE_CHATTING;
-		else if(menu_active)
-			input.state = STATE_IN_MENU;
-		else
+		if(!emoticon_selector_active)
 		{
-			input.state = STATE_PLAYING;
-			input.left = inp_key_state(config.key_move_left);
-			input.right = inp_key_state(config.key_move_right);
-			input.hook = inp_key_state(config.key_hook);
-			input.jump  = inp_key_state(config.key_jump);
-
-			if(!emoticon_selector_active)
-				do_input(&input.fire, config.key_fire);
-
-			// weapon selection
-			do_input(&input.next_weapon, config.key_next_weapon);
-			do_input(&input.prev_weapon, config.key_prev_weapon);
-
-			if(inp_key_presses(config.key_next_weapon) || inp_key_presses(config.key_prev_weapon))
-				input.wanted_weapon = 0;
-			else if (config.cl_autoswitch_weapons && picked_up_weapon)
-            {
-                input.wanted_weapon = picked_up_weapon;
-            }
-            else
+			if(do_input(&input_data.fire, config.key_fire))
 			{
-				if(inp_key_presses(config.key_weapon1)) input.wanted_weapon = 1;
-				if(inp_key_presses(config.key_weapon2)) input.wanted_weapon = 2;
-				if(inp_key_presses(config.key_weapon3)) input.wanted_weapon = 3;
-				if(inp_key_presses(config.key_weapon4)) input.wanted_weapon = 4;
-				if(inp_key_presses(config.key_weapon5)) input.wanted_weapon = 5;
-				if(inp_key_presses(config.key_weapon6)) input.wanted_weapon = 6;
+				// this is done so that we are sure to send the
+				// target when we actually fired
+				input_data.target_x = (int)mouse_pos.x;
+				input_data.target_y = (int)mouse_pos.y;
+				input_target_lock = 1;
 			}
-
-            picked_up_weapon = 0;
 		}
 
-		// stress testing
-		if(config.dbg_stress)
-		{
-			float t = client_localtime();
-			mem_zero(&input, sizeof(input));
+		// weapon selection
+		do_input(&input_data.next_weapon, config.key_next_weapon);
+		do_input(&input_data.prev_weapon, config.key_prev_weapon);
 
-			input.left = ((int)t/2)&1;
-			input.right = ((int)t/2+1)&1;
-			input.jump = ((int)t);
-			input.fire = ((int)(t*10));
-			input.hook = ((int)(t*2))&1;
-			input.wanted_weapon = ((int)t)%NUM_WEAPONS;
-			input.target_x = (int)(sinf(t*3)*100.0f);
-			input.target_y = (int)(cosf(t*3)*100.0f);
+		if(inp_key_presses(config.key_next_weapon) || inp_key_presses(config.key_prev_weapon))
+			input_data.wanted_weapon = 0;
+		else if (config.cl_autoswitch_weapons && picked_up_weapon != -1)
+			input_data.wanted_weapon = picked_up_weapon;
+		else
+		{
+			if(inp_key_presses(config.key_weapon1)) input_data.wanted_weapon = 1;
+			if(inp_key_presses(config.key_weapon2)) input_data.wanted_weapon = 2;
+			if(inp_key_presses(config.key_weapon3)) input_data.wanted_weapon = 3;
+			if(inp_key_presses(config.key_weapon4)) input_data.wanted_weapon = 4;
+			if(inp_key_presses(config.key_weapon5)) input_data.wanted_weapon = 5;
+			if(inp_key_presses(config.key_weapon6)) input_data.wanted_weapon = 6;
 		}
-
-		snap_input(&input, sizeof(input));
 	}
 
+
 	// center at char but can be moved when mouse is far away
 	float offx = 0, offy = 0;
 	if (config.cl_dynamic_camera)
@@ -3061,6 +3036,51 @@ void menu_do_disconnected();
 void menu_do_connecting();
 void menu_do_connected();
 
+extern "C" int modc_snap_input(int *data)
+{
+	picked_up_weapon = -1;
+
+	if(!input_target_lock)
+	{
+		input_data.target_x = (int)mouse_pos.x;
+		input_data.target_y = (int)mouse_pos.y;
+	}
+	input_target_lock = 0;
+
+	if(chat_mode != CHATMODE_NONE)
+		input_data.state = STATE_CHATTING;
+	else if(menu_active)
+		input_data.state = STATE_IN_MENU;
+	else
+	{
+		input_data.state = STATE_PLAYING;
+		input_data.left = inp_key_state(config.key_move_left);
+		input_data.right = inp_key_state(config.key_move_right);
+		input_data.hook = inp_key_state(config.key_hook);
+		input_data.jump  = inp_key_state(config.key_jump);
+	}
+
+	// stress testing
+	if(config.dbg_stress)
+	{
+		float t = client_localtime();
+		mem_zero(&input_data, sizeof(input_data));
+
+		input_data.left = ((int)t/2)&1;
+		input_data.right = ((int)t/2+1)&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);
+	}
+
+	// copy and return size	
+	mem_copy(data, &input_data, sizeof(input_data));
+	return sizeof(input_data);
+}
+
 extern "C" void modc_statechange(int state, int old)
 {
 	clear_object_pointers();