changed how the input snapping works. fixed a bug in the projectile rendering when using 25 snapping rate

This commit is contained in:
Magnus Auvinen 2007-12-18 20:12:25 +00:00
parent bde0c6c6f8
commit f3a60b6df9
3 changed files with 99 additions and 79 deletions

View file

@ -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);

View file

@ -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();

View file

@ -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};
if(!emoticon_selector_active)
{
if(do_input(&input_data.fire, config.key_fire))
{
// 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;
}
}
input.target_x = (int)mouse_pos.x;
input.target_y = (int)mouse_pos.y;
// weapon selection
do_input(&input_data.next_weapon, config.key_next_weapon);
do_input(&input_data.prev_weapon, config.key_prev_weapon);
if(chat_mode != CHATMODE_NONE)
input.state = STATE_CHATTING;
else if(menu_active)
input.state = STATE_IN_MENU;
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
{
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(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;
}
picked_up_weapon = 0;
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;
}
// stress testing
if(config.dbg_stress)
{
float t = client_localtime();
mem_zero(&input, sizeof(input));
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);
}
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();