mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
fixed latency stuff, some gfx stuff
This commit is contained in:
parent
e588bd3b3b
commit
1d34666164
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char tmpbuffer3[MAX_SNAPSHOT_SIZE];
|
||||
int snapsize = snapshot_unpack_delta(deltashot, (snapshot*)tmpbuffer3, deltadata, deltasize);
|
||||
|
||||
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
|
||||
// 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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue