diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-09-23 18:27:04 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-09-23 18:27:04 +0000 |
| commit | ebbe51718e6b3ed81ee0932641e0bc4ddb805fcc (patch) | |
| tree | 4eca71f96840157c674558ad3f6a24e6118445ca | |
| parent | 1004b466c33199b4c6903bbc676b06b8a34a81d9 (diff) | |
| download | zcatch-ebbe51718e6b3ed81ee0932641e0bc4ddb805fcc.tar.gz zcatch-ebbe51718e6b3ed81ee0932641e0bc4ddb805fcc.zip | |
loads of changes. better prediction. line drawing. some nice graphs :)
| -rw-r--r-- | default.bam | 2 | ||||
| -rw-r--r-- | src/editor/editor.cpp | 24 | ||||
| -rw-r--r-- | src/engine/client/client.c | 253 | ||||
| -rw-r--r-- | src/engine/client/gfx.c | 154 | ||||
| -rw-r--r-- | src/engine/client/ui.c | 2 | ||||
| -rw-r--r-- | src/engine/interface.h | 8 | ||||
| -rw-r--r-- | src/engine/protocol.h | 1 | ||||
| -rw-r--r-- | src/engine/server/server.c | 12 | ||||
| -rw-r--r-- | src/engine/system.c | 4 | ||||
| -rw-r--r-- | src/game/client/game_client.cpp | 64 | ||||
| -rw-r--r-- | src/game/client/menu.cpp | 14 | ||||
| -rw-r--r-- | src/tools/crapnet.cpp | 6 |
12 files changed, 339 insertions, 205 deletions
diff --git a/default.bam b/default.bam index 3eb185b8..9b3f8899 100644 --- a/default.bam +++ b/default.bam @@ -225,7 +225,7 @@ function build(settings) game_server = Compile(settings, Collect("src/game/server/*.cpp"), serverdata.source, serverdata.cdata) editor = Compile(settings, Collect("src/editor/*.cpp")) - -- build tools + -- build tools (TODO: fix this so we don't get double _d_d stuff) tools_src = Collect("src/tools/*.cpp", "src/tools/*.c") objs = Compile(settings, tools_src) diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp index c2633778..6d6cea57 100644 --- a/src/editor/editor.cpp +++ b/src/editor/editor.cpp @@ -383,7 +383,7 @@ static void ui_do_frame(float x, float y, float w, float h) gfx_texture_set(-1); gfx_blend_normal(); gfx_quads_begin(); - gfx_quads_setcolor(0.0f, 0.0f, 0.0f, 1.0f); + gfx_setcolor(0.0f, 0.0f, 0.0f, 1.0f); gfx_quads_drawTL(x, y, w, h); gfx_quads_end(); gfx_blend_normal(); @@ -484,7 +484,7 @@ static int ui_do_tilemap(void *id, tilemap *tm, int flags, float x, float y, flo gfx_texture_set(-1); gfx_blend_additive(); gfx_quads_begin(); - gfx_quads_setcolor(1.0f, 0.0f, 0.0f, 0.25f); + gfx_setcolor(1.0f, 0.0f, 0.0f, 0.25f); gfx_quads_drawTL((tmx-brush.width/2)*scale, (tmy-brush.height/2)*scale, brush.width*scale, brush.height*scale); gfx_quads_end(); gfx_blend_normal(); @@ -521,7 +521,7 @@ static int ui_do_tilemap(void *id, tilemap *tm, int flags, float x, float y, flo gfx_texture_set(-1); gfx_blend_additive(); gfx_quads_begin(); - gfx_quads_setcolor(1.0f, 1.0f, 1.0f, 0.25f); + gfx_setcolor(1.0f, 1.0f, 1.0f, 0.25f); gfx_quads_drawTL(select_wx, select_wy, select_ww, select_wh); gfx_quads_end(); gfx_blend_normal(); @@ -597,11 +597,11 @@ static int ui_do_entity(void *id, entity *ent, int selected) gfx_texture_set(-1); gfx_quads_begin(); if(selected) - gfx_quads_setcolor(1.0f, 0.5f, 0.5f, 0.95f); + gfx_setcolor(1.0f, 0.5f, 0.5f, 0.95f); else if(ui_hot_item() == id) - gfx_quads_setcolor(1.0f, 1.0f, 1.0f, 0.95f); + gfx_setcolor(1.0f, 1.0f, 1.0f, 0.95f); else - gfx_quads_setcolor(0.75f, 0.75f, 0.75f, 0.95f); + gfx_setcolor(0.75f, 0.75f, 0.75f, 0.95f); gfx_quads_drawTL(x-w/2, y-w/2, w, h); gfx_quads_end(); @@ -646,11 +646,11 @@ void draw_editor_button(void *id, const char *text, int checked, float x, float gfx_texture_set(-1); gfx_quads_begin(); if(ui_hot_item() == id) - gfx_quads_setcolor(1,1,1,1); + gfx_setcolor(1,1,1,1); else if(checked) - gfx_quads_setcolor(0.75f,0.5f,0.5f,1); + gfx_setcolor(0.75f,0.5f,0.5f,1); else - gfx_quads_setcolor(0.5f,0.5f,0.5f,1); + gfx_setcolor(0.5f,0.5f,0.5f,1); gfx_quads_drawTL(x,y,w,h); gfx_quads_end(); @@ -872,7 +872,7 @@ static void editor_render() gfx_texture_set(checker_texture); gfx_blend_normal(); gfx_quads_begin(); - gfx_quads_setcolor(1.0f, 1.0f, 1.0f, 1.0f); + gfx_setcolor(1.0f, 1.0f, 1.0f, 1.0f); gfx_quads_setsubset(0,0,32.0f, 32.0f); gfx_quads_drawTL(chooser_x, chooser_y, 16*16.0f, 16*16.0f); gfx_quads_end(); @@ -1135,11 +1135,11 @@ static int editor_loop() // render butt ugly mouse cursor gfx_texture_set(-1); gfx_quads_begin(); - gfx_quads_setcolor(0,0,0,1); + gfx_setcolor(0,0,0,1); gfx_quads_draw_freeform(mx,my,mx,my, mx+7,my, mx,my+7); - gfx_quads_setcolor(1,1,1,1); + gfx_setcolor(1,1,1,1); gfx_quads_draw_freeform(mx+1,my+1,mx+1,my+1, mx+5,my+1, mx+1,my+5); diff --git a/src/engine/client/client.c b/src/engine/client/client.c index 63414f8e..26865f37 100644 --- a/src/engine/client/client.c +++ b/src/engine/client/client.c @@ -33,10 +33,6 @@ static int info_request_begin; static int info_request_end; static int snapshot_part; static int64 local_start_time; -static int64 game_start_time; - -static float snapshot_latency = 0; -static float prediction_latency = 0; static int extra_polating = 0; static int debug_font; @@ -48,6 +44,8 @@ static int window_must_refocus = 0; static int snaploss = 0; static int snapcrcerrors = 0; +static int ack_game_tick = -1; + static int current_recv_tick = 0; // current time @@ -62,10 +60,123 @@ static struct // TODO: handle input better { int data[MAX_INPUT_SIZE]; // the input data int tick; // the tick that the input is for - float latency; // prediction latency when we sent this input + int64 game_time; // prediction latency when we sent this input + int64 time; } inputs[200]; static int current_input = 0; +enum +{ + GRAPH_MAX=256, +}; + +typedef struct +{ + float min, max; + float values[GRAPH_MAX]; + int index; +} GRAPH; + +static void graph_add(GRAPH *g, float v) +{ + g->values[g->index] = v; + g->index = (g->index+1)&(GRAPH_MAX-1); +} + +static void graph_render(GRAPH *g, float x, float y, float w, float h) +{ + int i; + gfx_texture_set(-1); + + gfx_quads_begin(); + gfx_setcolor(0, 0, 0, 1); + gfx_quads_drawTL(x, y, w, h); + gfx_quads_end(); + + gfx_lines_begin(); + gfx_setcolor(0.5f, 0.5f, 0.5f, 1); + gfx_lines_draw(x, y+(h*3)/4, x+w, y+(h*3)/4); + gfx_lines_draw(x, y+h/2, x+w, y+h/2); + gfx_lines_draw(x, y+h/4, x+w, y+h/4); + for(i = 1; i < GRAPH_MAX; i++) + { + float a0 = (i-1)/(float)GRAPH_MAX; + float a1 = i/(float)GRAPH_MAX; + int i0 = (g->index+i-1)&(GRAPH_MAX-1); + int i1 = (g->index+i)&(GRAPH_MAX-1); + + float v0 = g->values[i0]; + float v1 = g->values[i1]; + + gfx_setcolor(0, 1, 0, 1); + gfx_lines_draw(x+a0*w, y+h-v0*h, x+a1*w, y+h-v1*h); + } + gfx_lines_end(); +} + +typedef struct +{ + int64 snap; + int64 current; + int64 target; + + int64 rlast; + int64 tlast; + GRAPH graph; +} SMOOTHTIME; + +static void st_init(SMOOTHTIME *st, int64 target) +{ + st->snap = time_get(); + st->current = target; + st->target = target; +} + +static int64 st_get(SMOOTHTIME *st, int64 now) +{ + int64 c = st->current + (now - st->snap); + int64 t = st->target + (now - st->snap); + + // it's faster to adjust upward instead of downward + // we might need to adjust these abit + float adjust_speed = 0.3f; + if(t < c) + adjust_speed *= 5.0f; + + float a = ((now-st->snap)/(float)time_freq())*adjust_speed; + if(a > 1) + a = 1; + + int64 r = c + (int64)((t-c)*a); + + { + int64 drt = now - st->rlast; + int64 dtt = r - st->tlast; + + st->rlast = now; + st->tlast = r; + + if(drt == 0) + graph_add(&st->graph, 0.5f); + else + graph_add(&st->graph, (((dtt/(float)drt)-1.0f)*2.5f)+0.5f); + } + + return r; +} + +static void st_update(SMOOTHTIME *st, int64 target) +{ + int64 now = time_get(); + st->current = st_get(st, now); + st->snap = now; + st->target = target; +} + +SMOOTHTIME game_time; +SMOOTHTIME predicted_time; + +GRAPH intra_graph; // --- input snapping --- static int input_data[MAX_INPUT_SIZE] = {0}; @@ -125,8 +236,7 @@ static void snap_init() snapshots[SNAP_CURRENT] = 0; snapshots[SNAP_PREV] = 0; recived_snapshots = 0; - game_start_time = -1; - + current_predtick = 0; } // ------ time functions ------ @@ -159,7 +269,6 @@ int client_send_msg() static void client_send_info() { recived_snapshots = 0; - game_start_time = -1; msg_pack_start_system(NETMSG_INFO, MSGFLAG_VITAL); msg_pack_string(modc_net_version(), 128); @@ -192,12 +301,18 @@ static void client_send_error(const char *error) static void client_send_input() { + if(current_predtick <= 0) + return; + msg_pack_start_system(NETMSG_INPUT, 0); + msg_pack_int(ack_game_tick); msg_pack_int(current_predtick); msg_pack_int(input_data_size); - + + int64 now = time_get(); inputs[current_input].tick = current_predtick; - inputs[current_input].latency = prediction_latency; + inputs[current_input].game_time = st_get(&predicted_time, now); + inputs[current_input].time = now; int i; for(i = 0; i < input_data_size/4; i++) @@ -384,9 +499,6 @@ void client_connect(const char *server_address_str) for(i = 0; i < 200; i++) inputs[i].tick = -1; current_input = 0; - - snapshot_latency = 0; - prediction_latency = 0; } void client_disconnect() @@ -424,17 +536,23 @@ static void client_debug_render() static float frametime_avg = 0; frametime_avg = frametime_avg*0.9f + frametime*0.1f; char buffer[512]; - sprintf(buffer, "send: %6d recv: %6d snaploss: %d snaplatency: %4.2f %c predlatency: %4.2f mem %dk gfxmem: %dk fps: %3d", + sprintf(buffer, "ticks: %8d %8d send: %6d recv: %6d snaploss: %d %c mem %dk gfxmem: %dk fps: %3d", + current_tick, current_predtick, (current.send_bytes-prev.send_bytes)*10, (current.recv_bytes-prev.recv_bytes)*10, snaploss, - snapshot_latency*1000.0f, extra_polating?'E':' ', - prediction_latency*1000.0f, + extra_polating?'E':' ', mem_allocated()/1024, gfx_memory_usage()/1024, (int)(1.0f/frametime_avg)); gfx_quads_text(2, 2, 16, buffer); + + // render graphs + gfx_mapscreen(0,0,400.0f,300.0f); + graph_render(&game_time.graph, 300, 10, 90, 50); + graph_render(&predicted_time.graph, 300, 10+50+10, 90, 50); + graph_render(&intra_graph, 300, 10+50+10+50+10, 90, 50); } void client_quit() @@ -597,19 +715,15 @@ static void client_process_packet(NETPACKET *packet) { if(inputs[k].tick == input_predtick) { - float wanted_latency = inputs[k].latency - time_left/1000.0f + 0.01f; - if(wanted_latency > prediction_latency) - prediction_latency = prediction_latency*0.90f + wanted_latency*0.10f; - else - prediction_latency = prediction_latency*0.95f + wanted_latency*0.05f; - //dbg_msg("DEBUG", "predlatency=%f", prediction_latency); + //-1000/50 + int margin = 1000/50; + int64 target = inputs[k].game_time + (time_get() - inputs[k].time); + st_update(&predicted_time, target - (int64)(((time_left-margin)/1000.0f)*time_freq())); break; } } } - //dbg_msg("DEBUG", "new predlatency=%f", prediction_latency); - if(snapshot_part == part && game_tick > current_recv_tick) { // TODO: clean this up abit @@ -642,10 +756,7 @@ static void client_process_packet(NETPACKET *packet) // ack snapshot // TODO: combine this with the input message - msg_pack_start_system(NETMSG_SNAPACK, 0); - msg_pack_int(-1); - msg_pack_end(); - client_send_msg(); + ack_game_tick = -1; return; } } @@ -668,18 +779,15 @@ static void client_process_packet(NETPACKET *packet) unsigned char tmpbuffer3[MAX_SNAPSHOT_SIZE]; int snapsize = snapshot_unpack_delta(deltashot, (SNAPSHOT*)tmpbuffer3, deltadata, deltasize); - if(snapshot_crc((SNAPSHOT*)tmpbuffer3) != crc) + if(msg != NETMSG_SNAPEMPTY && snapshot_crc((SNAPSHOT*)tmpbuffer3) != crc) { if(config.debug) - dbg_msg("client", "snapshot crc error\n"); + dbg_msg("client", "snapshot crc error"); snapcrcerrors++; if(snapcrcerrors > 25) { // to many errors, send reset - msg_pack_start_system(NETMSG_SNAPACK, 0); - msg_pack_int(-1); - msg_pack_end(); - client_send_msg(); + ack_game_tick = -1; snapcrcerrors = 0; } return; @@ -718,12 +826,21 @@ static void client_process_packet(NETPACKET *packet) // we got two snapshots until we see us self as connected if(recived_snapshots == 2) { + // start at 200ms and work from there + st_init(&predicted_time, (game_tick+10)*time_freq()/50); + st_init(&game_time, (game_tick-2)*time_freq()/50); snapshots[SNAP_PREV] = snapshot_storage.first; snapshots[SNAP_CURRENT] = snapshot_storage.last; local_start_time = time_get(); client_set_state(CLIENTSTATE_ONLINE); } + + st_update(&game_time, (game_tick-2)*time_freq()/50); + //client_send_input(); + //st_update(&predicted_time, game_tick*time_freq()); + + /* int64 now = time_get(); int64 t = now - game_tick*time_freq()/50; if(game_start_time == -1 || t < game_start_time) @@ -736,17 +853,16 @@ static void client_process_packet(NETPACKET *packet) int64 wanted = game_start_time+(game_tick*time_freq())/50; float current_latency = (now-wanted)/(float)time_freq(); snapshot_latency = snapshot_latency*0.95f+current_latency*0.05f; + */ // ack snapshot - msg_pack_start_system(NETMSG_SNAPACK, 0); - msg_pack_int(game_tick); - msg_pack_end(); - client_send_msg(); + //dbg_msg("snap!", "%d", game_tick); + ack_game_tick = game_tick; } } else { - dbg_msg("client", "snapshot reset!"); + dbg_msg("client", "snapsht reset!"); snapshot_part = 0; } } @@ -759,7 +875,6 @@ static void client_process_packet(NETPACKET *packet) } } - static void client_pump_network() { netclient_update(net); @@ -842,16 +957,14 @@ static void client_run(const char *direct_connect_server) if(recived_snapshots >= 3) { int repredict = 0; - int64 now = time_get(); + //int64 now = time_get(); + int64 now = st_get(&game_time, time_get()); while(1) { SNAPSTORAGE_HOLDER *cur = snapshots[SNAP_CURRENT]; - int64 tickstart = game_start_time + (cur->tick+1)*time_freq()/50; - int64 t = tickstart; - if(snapshot_latency > 0) - t += (int64)(time_freq()*(snapshot_latency*1.1f)); + int64 tickstart = (cur->tick)*time_freq()/50; - if(t < now) + if(tickstart < now) { SNAPSTORAGE_HOLDER *next = snapshots[SNAP_CURRENT]->next; if(next) @@ -880,36 +993,28 @@ static void client_run(const char *direct_connect_server) break; } } + + //tg_add(&game_time_graph, now, extra_polating); if(snapshots[SNAP_CURRENT] && snapshots[SNAP_PREV]) { - int64 curtick_start = game_start_time + (snapshots[SNAP_CURRENT]->tick+1)*time_freq()/50; - if(snapshot_latency > 0) - curtick_start += (int64)(time_freq()*(snapshot_latency*1.1f)); - - int64 prevtick_start = game_start_time + (snapshots[SNAP_PREV]->tick+1)*time_freq()/50; - if(snapshot_latency > 0) - prevtick_start += (int64)(time_freq()*(snapshot_latency*1.1f)); - + int64 curtick_start = (snapshots[SNAP_CURRENT]->tick)*time_freq()/50; + int64 prevtick_start = (snapshots[SNAP_PREV]->tick)*time_freq()/50; intratick = (now - prevtick_start) / (float)(curtick_start-prevtick_start); - - // 25 frames ahead - int64 last_pred_game_time = 0; - int64 predicted_game_time = (now - game_start_time) + (int64)(time_freq()*prediction_latency); - if(predicted_game_time < last_pred_game_time) - predicted_game_time = last_pred_game_time; - last_pred_game_time = predicted_game_time; - //int64 predictiontime = game_start_time + time_freq()+ prediction_latency*SERVER_TICK_SPEED - int new_predtick = (predicted_game_time*SERVER_TICK_SPEED) / time_freq(); + graph_add(&intra_graph, intratick*0.25f); - int64 predtick_start_time = (new_predtick*time_freq())/SERVER_TICK_SPEED; - intrapredtick = (predicted_game_time - predtick_start_time)*SERVER_TICK_SPEED/(float)time_freq(); + int64 pred_now = st_get(&predicted_time, time_get()); + //tg_add(&predicted_time_graph, pred_now, 0); + int prev_pred_tick = (int)(pred_now*50/time_freq()); + int new_pred_tick = prev_pred_tick+1; + curtick_start = new_pred_tick*time_freq()/50; + prevtick_start = prev_pred_tick*time_freq()/50; + intrapredtick = (pred_now - prevtick_start) / (float)(curtick_start-prevtick_start); - if(new_predtick > current_predtick) + if(new_pred_tick > current_predtick) { - //dbg_msg("") - current_predtick = new_predtick; + current_predtick = new_pred_tick; repredict = 1; // send input @@ -918,9 +1023,13 @@ static void client_run(const char *direct_connect_server) } //intrapredtick = current_predtick - + + // only do sane predictions if(repredict) - modc_predict(); + { + if(current_predtick > current_tick && current_predtick < current_tick+50) + modc_predict(); + } } // STRESS TEST: join the server again @@ -970,11 +1079,15 @@ static void client_run(const char *direct_connect_server) if(inp_key_pressed(KEY_F5)) { + ack_game_tick = -1; + client_send_input(); + /* // ack snapshot msg_pack_start_system(NETMSG_SNAPACK, 0); msg_pack_int(-1); msg_pack_end(); client_send_msg(); + */ } } diff --git a/src/engine/client/gfx.c b/src/engine/client/gfx.c index b48740b6..e2aa1c81 100644 --- a/src/engine/client/gfx.c +++ b/src/engine/client/gfx.c @@ -15,6 +15,12 @@ #define GL_COMPRESSED_RGB_ARB 0x84ED #define GL_COMPRESSED_RGBA_ARB 0x84EE +enum +{ + DRAWING_QUADS=1, + DRAWING_LINES=2, +}; + // typedef struct { float x, y, z; } VEC3; typedef struct { float u, v; } TEXCOORD; @@ -39,7 +45,7 @@ static int do_screenshot = 0; static int screen_width = -1; static int screen_height = -1; static float rotation = 0; -static int quads_drawing = 0; +static int drawing = 0; static float screen_x0 = 0; static float screen_y0 = 0; @@ -71,39 +77,48 @@ static const unsigned char null_texture_data[] = { 0x00,0x00,0xff,0xff, 0x00,0x00,0xff,0xff, 0xff,0xff,0x00,0xff, 0xff,0xff,0x00,0xff, }; -static void draw_quad(int _bflush) +static void flush() { - if (!_bflush && ((num_vertices + 4) < vertex_buffer_size)) - { - // Just add - num_vertices += 4; - } - else if (num_vertices) - { - if (!_bflush) - num_vertices += 4; - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glVertexPointer(3, GL_FLOAT, - sizeof(VERTEX), - (char*)vertices); - glTexCoordPointer(2, GL_FLOAT, - sizeof(VERTEX), - (char*)vertices + sizeof(float)*3); - glColorPointer(4, GL_FLOAT, - sizeof(VERTEX), - (char*)vertices + sizeof(float)*5); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glDrawArrays(GL_QUADS, 0, num_vertices); + if(num_vertices == 0) + return; - // Reset pointer - num_vertices = 0; - } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glVertexPointer(3, GL_FLOAT, + sizeof(VERTEX), + (char*)vertices); + glTexCoordPointer(2, GL_FLOAT, + sizeof(VERTEX), + (char*)vertices + sizeof(float)*3); + glColorPointer(4, GL_FLOAT, + sizeof(VERTEX), + (char*)vertices + sizeof(float)*5); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + if(drawing == DRAWING_QUADS) + glDrawArrays(GL_QUADS, 0, num_vertices); + else if(drawing == DRAWING_LINES) + glDrawArrays(GL_LINES, 0, num_vertices); + + // Reset pointer + num_vertices = 0; +} + +static void draw_line() +{ + num_vertices += 2; + if((num_vertices + 2) >= vertex_buffer_size) + flush(); +} + +static void draw_quad() +{ + num_vertices += 4; + if((num_vertices + 4) >= vertex_buffer_size) + flush(); } int gfx_init() @@ -499,7 +514,7 @@ int gfx_screenheight() void gfx_texture_set(int slot) { - dbg_assert(quads_drawing == 0, "called gfx_texture_set within quads_begin"); + dbg_assert(drawing == 0, "called gfx_texture_set within begin"); if(slot == -1) glDisable(GL_TEXTURE_2D); else @@ -551,49 +566,49 @@ void gfx_setoffset(float x, float y) void gfx_quads_begin() { - dbg_assert(quads_drawing == 0, "called quads_begin twice"); - quads_drawing++; + dbg_assert(drawing == 0, "called quads_begin twice"); + drawing = DRAWING_QUADS; gfx_quads_setsubset(0,0,1,1); gfx_quads_setrotation(0); - gfx_quads_setcolor(1,1,1,1); + gfx_setcolor(1,1,1,1); } void gfx_quads_end() { - dbg_assert(quads_drawing == 1, "called quads_end without quads_begin"); - draw_quad(1); - quads_drawing--; + dbg_assert(drawing == DRAWING_QUADS, "called quads_end without begin"); + flush(); + drawing = 0; } void gfx_quads_setrotation(float angle) { - dbg_assert(quads_drawing == 1, "called gfx_quads_setrotation without quads_begin"); + dbg_assert(drawing == DRAWING_QUADS, "called gfx_quads_setrotation without begin"); rotation = angle; } -void gfx_quads_setcolorvertex(int i, float r, float g, float b, float a) +void gfx_setcolorvertex(int i, float r, float g, float b, float a) { - dbg_assert(quads_drawing == 1, "called gfx_quads_setcolorvertex without quads_begin"); + dbg_assert(drawing != 0, "called gfx_quads_setcolorvertex without begin"); color[i].r = r; color[i].g = g; color[i].b = b; color[i].a = a; } -void gfx_quads_setcolor(float r, float g, float b, float a) +void gfx_setcolor(float r, float g, float b, float a) { - dbg_assert(quads_drawing == 1, "called gfx_quads_setcolor without quads_begin"); - gfx_quads_setcolorvertex(0, r, g, b, a); - gfx_quads_setcolorvertex(1, r, g, b, a); - gfx_quads_setcolorvertex(2, r, g, b, a); - gfx_quads_setcolorvertex(3, r, g, b, a); + dbg_assert(drawing != 0, "called gfx_quads_setcolor without begin"); + gfx_setcolorvertex(0, r, g, b, a); + gfx_setcolorvertex(1, r, g, b, a); + gfx_setcolorvertex(2, r, g, b, a); + gfx_setcolorvertex(3, r, g, b, a); } void gfx_quads_setsubset(float tl_u, float tl_v, float br_u, float br_v) { - dbg_assert(quads_drawing == 1, "called gfx_quads_setsubset without quads_begin"); + dbg_assert(drawing == DRAWING_QUADS, "called gfx_quads_setsubset without begin"); texture[0].u = tl_u; texture[0].v = tl_v; @@ -631,7 +646,7 @@ void gfx_quads_draw(float x, float y, float w, float h) void gfx_quads_drawTL(float x, float y, float width, float height) { - dbg_assert(quads_drawing == 1, "called quads_draw without quads_begin"); + dbg_assert(drawing == DRAWING_QUADS, "called quads_draw without begin"); VEC3 center; center.x = x + width/2; @@ -662,7 +677,7 @@ void gfx_quads_drawTL(float x, float y, float width, float height) vertices[num_vertices + 3].color = color[3]; rotate(¢er, &vertices[num_vertices + 3].pos); - draw_quad(0); + draw_quad(); } void gfx_quads_draw_freeform( @@ -671,7 +686,7 @@ void gfx_quads_draw_freeform( float x2, float y2, float x3, float y3) { - dbg_assert(quads_drawing == 1, "called quads_draw_freeform without quads_begin"); + dbg_assert(drawing == DRAWING_QUADS, "called quads_draw_freeform without begin"); vertices[num_vertices].pos.x = x0; vertices[num_vertices].pos.y = y0; @@ -693,7 +708,7 @@ void gfx_quads_draw_freeform( vertices[num_vertices + 3].tex = texture[3]; vertices[num_vertices + 3].color = color[3]; - draw_quad(0); + draw_quad(); } void gfx_quads_text(float x, float y, float size, const char *text) @@ -884,3 +899,36 @@ float gfx_pretty_text_width(float size, const char *text_, int length) return w; } + + + +void gfx_lines_begin() +{ + dbg_assert(drawing == 0, "called begin twice"); + drawing = DRAWING_LINES; + gfx_setcolor(1,1,1,1); +} + +void gfx_lines_end() +{ + dbg_assert(drawing == DRAWING_LINES, "called end without begin"); + flush(); + drawing = 0; +} + +void gfx_lines_draw(float x0, float y0, float x1, float y1) +{ + dbg_assert(drawing == DRAWING_LINES, "called draw without begin"); + + vertices[num_vertices].pos.x = x0; + vertices[num_vertices].pos.y = y0; + vertices[num_vertices].tex = texture[0]; + vertices[num_vertices].color = color[0]; + + vertices[num_vertices + 1].pos.x = x1; + vertices[num_vertices + 1].pos.y = y1; + vertices[num_vertices + 1].tex = texture[1]; + vertices[num_vertices + 1].color = color[1]; + + draw_line(); +} diff --git a/src/engine/client/ui.c b/src/engine/client/ui.c index c67b1b13..eb07e7b5 100644 --- a/src/engine/client/ui.c +++ b/src/engine/client/ui.c @@ -70,7 +70,7 @@ void ui_do_image(int texture, float x, float y, float w, float h) gfx_blend_normal(); gfx_texture_set(texture); gfx_quads_begin(); - gfx_quads_setcolor(1,1,1,1); + gfx_setcolor(1,1,1,1); gfx_quads_setsubset( 0.0f, // startx 0.0f, // starty diff --git a/src/engine/interface.h b/src/engine/interface.h index e1608cff..4bf25bd2 100644 --- a/src/engine/interface.h +++ b/src/engine/interface.h @@ -250,7 +250,7 @@ void gfx_quads_setrotation(float angle); The color values are from 0.0 to 1.0. The color is reset when <gfx_quads_begin> is called. */ -void gfx_quads_setcolorvertex(int i, float r, float g, float b, float a); +void gfx_setcolorvertex(int i, float r, float g, float b, float a); /* Function: gfx_quads_setcolor @@ -266,7 +266,7 @@ void gfx_quads_setcolorvertex(int i, float r, float g, float b, float a); The color values are from 0.0 to 1.0. The color is reset when <gfx_quads_begin> is called. */ -void gfx_quads_setcolor(float r, float g, float b, float a); +void gfx_setcolor(float r, float g, float b, float a); /* Function: gfx_quads_setsubset @@ -793,6 +793,10 @@ void gfx_getscreen(float *tl_x, float *tl_y, float *br_x, float *br_y); int gfx_memory_usage(); void gfx_screenshot(); +void gfx_lines_begin(); +void gfx_lines_draw(float x0, float y0, float x1, float y1); +void gfx_lines_end(); + /* server snap id */ int snap_new_id(); void snap_free_id(int id); diff --git a/src/engine/protocol.h b/src/engine/protocol.h index 81c0480c..1a41d66a 100644 --- a/src/engine/protocol.h +++ b/src/engine/protocol.h @@ -17,7 +17,6 @@ enum /* sent by client */ NETMSG_ENTERGAME, NETMSG_INPUT, - NETMSG_SNAPACK, /* sent by both */ NETMSG_ERROR, diff --git a/src/engine/server/server.c b/src/engine/server/server.c index edb3f644..293d4870 100644 --- a/src/engine/server/server.c +++ b/src/engine/server/server.c @@ -436,6 +436,11 @@ static void server_process_client_packet(NETPACKET *packet) } else if(msg == NETMSG_INPUT) { + clients[cid].last_acked_snapshot = msg_unpack_int(); + int64 tagtime; + if(snapstorage_get(&clients[cid].snapshots, clients[cid].last_acked_snapshot, &tagtime, 0) >= 0) + clients[cid].latency = (int)(((time_get()-tagtime)*1000)/time_freq()); + int tick = msg_unpack_int(); int size = msg_unpack_int(); int i; @@ -460,13 +465,6 @@ static void server_process_client_packet(NETPACKET *packet) clients[cid].current_input++; clients[cid].current_input %= 200; } - else if(msg == NETMSG_SNAPACK) - { - clients[cid].last_acked_snapshot = msg_unpack_int(); - int64 tagtime; - if(snapstorage_get(&clients[cid].snapshots, clients[cid].last_acked_snapshot, &tagtime, 0) >= 0) - clients[cid].latency = (int)(((time_get()-tagtime)*1000)/time_freq()); - } else { dbg_msg("server", "strange message cid=%d msg=%d data_size=%d", cid, msg, packet->data_size); diff --git a/src/engine/system.c b/src/engine/system.c index f5696b91..6226d4d2 100644 --- a/src/engine/system.c +++ b/src/engine/system.c @@ -258,8 +258,12 @@ int64 time_get() gettimeofday(&val, NULL); return (int64)val.tv_sec*(int64)1000000+(int64)val.tv_usec; #elif defined(CONF_FAMILY_WINDOWS) + static int64 last = 0; int64 t; QueryPerformanceCounter((PLARGE_INTEGER)&t); + if(t<last) /* for some reason, QPC can return values in the past */ + return last; + last = t; return t; #else #error not implemented diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp index 42bd119c..178330c2 100644 --- a/src/game/client/game_client.cpp +++ b/src/game/client/game_client.cpp @@ -138,38 +138,6 @@ void draw_sprite(float x, float y, float size) gfx_quads_draw(x, y, size*sprite_w_scale, size*sprite_h_scale); } -/* -void move_point(vec2 *inout_pos, vec2 *inout_vel, float elasticity) -{ - vec2 pos = *inout_pos; - vec2 vel = *inout_vel; - if(col_check_point(pos + vel)) - { - int affected = 0; - if(col_check_point(pos.x + vel.x, pos.y)) - { - inout_vel->x *= -elasticity; - affected++; - } - - if(col_check_point(pos.x, pos.y + vel.y)) - { - inout_vel->y *= -elasticity; - affected++; - } - - if(affected == 0) - { - inout_vel->x *= -elasticity; - inout_vel->y *= -elasticity; - } - } - else - { - *inout_pos = pos + vel; - } -}*/ - class damage_indicators { public: @@ -238,7 +206,7 @@ public: destroy_i(&items[i]); else { - gfx_quads_setcolor(1.0f,1.0f,1.0f, items[i].life/0.1f); + gfx_setcolor(1.0f,1.0f,1.0f, items[i].life/0.1f); gfx_quads_setrotation(items[i].startangle + items[i].life * 2.0f); select_sprite(SPRITE_STAR1); draw_sprite(pos.x, pos.y, 48.0f); @@ -341,7 +309,7 @@ public: gfx_quads_setrotation(particles[i].rot); - gfx_quads_setcolor( + gfx_setcolor( data->particles[type].color_r, data->particles[type].color_g, data->particles[type].color_b, @@ -461,7 +429,7 @@ static void render_loading(float percent) gfx_texture_set(-1); gfx_quads_begin(); - gfx_quads_setcolor(0,0,0,0.50f); + gfx_setcolor(0,0,0,0.50f); draw_round_rect(x, y, w, h, 40.0f); gfx_quads_end(); @@ -472,7 +440,7 @@ static void render_loading(float percent) gfx_texture_set(-1); gfx_quads_begin(); - gfx_quads_setcolor(1,1,1,1.0f); + gfx_setcolor(1,1,1,1.0f); draw_round_rect(x+40, y+h-75, (w-80)*percent, 25, 5.0f); gfx_quads_end(); @@ -870,7 +838,7 @@ static void render_flag(const obj_flag *prev, const obj_flag *current) pos.x += cosf(client_localtime()*2.0f+offset)*2.5f; pos.y += sinf(client_localtime()*2.0f+offset)*2.5f; - gfx_quads_setcolor(current->team ? 1 : 0,0,current->team ? 0 : 1,1); + gfx_setcolor(current->team ? 1 : 0,0,current->team ? 0 : 1,1); gfx_quads_setsubset( 0, // startx 0, // starty @@ -1338,7 +1306,7 @@ static void render_player(const obj_player *prev_obj, const obj_player *player_o p += dir * data->weapons[iw].muzzleoffsetx + diry * offsety; draw_sprite(p.x, p.y, data->weapons[iw].visual_size); - /*gfx_quads_setcolor(1.0f,1.0f,1.0f,alpha); + /*gfx_setcolor(1.0f,1.0f,1.0f,alpha); vec2 diry(-dir.y,dir.x); p += dir * muzzleparams[player.weapon].offsetx + diry * offsety; gfx_quads_draw(p.x,p.y,muzzleparams[player.weapon].sizex, muzzleparams[player.weapon].sizey);*/ @@ -1399,7 +1367,7 @@ static void render_player(const obj_player *prev_obj, const obj_player *player_o gfx_quads_setrotation(pi/6*wiggle_angle); - gfx_quads_setcolor(1.0f,1.0f,1.0f,a); + gfx_setcolor(1.0f,1.0f,1.0f,a); // client_datas::emoticon is an offset from the first emoticon select_sprite(SPRITE_OOP + client_datas[player.clientid].emoticon); gfx_quads_draw(position.x, position.y - 23 - 32*h, 64, 64*h); @@ -1415,7 +1383,7 @@ void render_sun(float x, float y) gfx_blend_additive(); gfx_quads_begin(); const int rays = 10; - gfx_quads_setcolor(1.0f,1.0f,1.0f,0.025f); + gfx_setcolor(1.0f,1.0f,1.0f,0.025f); for(int r = 0; r < rays; r++) { float a = r/(float)rays + client_localtime()*0.025f; @@ -1423,10 +1391,10 @@ void render_sun(float x, float y) vec2 dir0(sinf((a-size)*pi*2.0f), cosf((a-size)*pi*2.0f)); vec2 dir1(sinf((a+size)*pi*2.0f), cosf((a+size)*pi*2.0f)); - gfx_quads_setcolorvertex(0, 1.0f,1.0f,1.0f,0.025f); - gfx_quads_setcolorvertex(1, 1.0f,1.0f,1.0f,0.025f); - gfx_quads_setcolorvertex(2, 1.0f,1.0f,1.0f,0.0f); - gfx_quads_setcolorvertex(3, 1.0f,1.0f,1.0f,0.0f); + gfx_setcolorvertex(0, 1.0f,1.0f,1.0f,0.025f); + gfx_setcolorvertex(1, 1.0f,1.0f,1.0f,0.025f); + gfx_setcolorvertex(2, 1.0f,1.0f,1.0f,0.0f); + gfx_setcolorvertex(3, 1.0f,1.0f,1.0f,0.0f); const float range = 1000.0f; gfx_quads_draw_freeform( pos.x+dir0.x, pos.y+dir0.y, @@ -1497,7 +1465,7 @@ int emoticon_selector_render() gfx_texture_set(-1); gfx_quads_begin(); - gfx_quads_setcolor(0,0,0,0.3f); + gfx_setcolor(0,0,0,0.3f); draw_circle(200, 150, 80, 64); gfx_quads_end(); @@ -1524,7 +1492,7 @@ int emoticon_selector_render() gfx_texture_set(data->images[IMAGE_CURSOR].id); gfx_quads_begin(); - gfx_quads_setcolor(1,1,1,1); + gfx_setcolor(1,1,1,1); gfx_quads_drawTL(emoticon_selector_mouse.x+200,emoticon_selector_mouse.y+150,12,12); gfx_quads_end(); @@ -1550,7 +1518,7 @@ void render_scoreboard(obj_game *gameobj, float x, float y, float w, int team, c gfx_texture_set(-1); gfx_quads_begin(); - gfx_quads_setcolor(0,0,0,0.5f); + gfx_setcolor(0,0,0,0.5f); draw_round_rect(x-10.f, y-10.f, w, h, 40.0f); gfx_quads_end(); @@ -1620,7 +1588,7 @@ void render_scoreboard(obj_game *gameobj, float x, float y, float w, int team, c // background so it's easy to find the local player gfx_texture_set(-1); gfx_quads_begin(); - gfx_quads_setcolor(1,1,1,0.25f); + gfx_setcolor(1,1,1,0.25f); draw_round_rect(x, y, w-20, 48, 20.0f); gfx_quads_end(); } diff --git a/src/game/client/menu.cpp b/src/game/client/menu.cpp index a307d176..43b11142 100644 --- a/src/game/client/menu.cpp +++ b/src/game/client/menu.cpp @@ -61,7 +61,7 @@ void draw_area(gui_tileset_enum tileset, int areax, int areay, int areaw, int ar gfx_blend_normal(); gfx_texture_set(data->images[IMAGE_GUI_WIDGETS].id); gfx_quads_begin(); - gfx_quads_setcolor(1,1,1,1); + gfx_setcolor(1,1,1,1); gfx_quads_setsubset( ts_x, // startx ts_y, // starty @@ -180,7 +180,7 @@ void draw_background(float t) gfx_texture_set(data->images[IMAGE_MENU_BUTTERFLY].id); gfx_quads_begin(); - gfx_quads_setcolor(1, 1, 1, 1); + gfx_setcolor(1, 1, 1, 1); gfx_quads_setsubset( flip ? (frame + 1) * 0.25f : frame * 0.25f, // startx 0.0f, // starty @@ -983,7 +983,7 @@ static int settings_render(bool ingame) gfx_texture_set(-1); gfx_quads_begin(); - gfx_quads_setcolor(0,0,0,0.5f); + gfx_setcolor(0,0,0,0.5f); draw_round_rect(10, 120, 780, 460, 30.0f); gfx_quads_end(); } @@ -1066,7 +1066,7 @@ static int ingame_main_render() gfx_texture_set(-1); gfx_quads_begin(); - gfx_quads_setcolor(0,0,0,0.5f); + gfx_setcolor(0,0,0,0.5f); draw_round_rect(170, 120, 460, 360, 30.0f); gfx_quads_end(); @@ -1179,7 +1179,7 @@ static int kerning_render() gfx_blend_normal(); gfx_texture_set(-1); gfx_quads_begin(); - gfx_quads_setcolor(0,0,0,0.5); + gfx_setcolor(0,0,0,0.5); gfx_quads_drawTL(700,35*i+20,1,30); gfx_quads_drawTL(700+45*(current_font->m_CharEndTable[(int)s[0]]-current_font->m_CharStartTable[(int)s[0]]),35*i+20,1,30); gfx_quads_end(); @@ -1281,7 +1281,7 @@ int render_popup(const char *caption, const char *text, const char *button_text) gfx_texture_set(-1); gfx_quads_begin(); - gfx_quads_setcolor(0,0,0,0.50f); + gfx_setcolor(0,0,0,0.50f); draw_round_rect(x, y, w, h, 40.0f); gfx_quads_end(); @@ -1435,7 +1435,7 @@ extern "C" int modmenu_render(int ingame) // TODO: nastyness gfx_texture_set(data->images[IMAGE_CURSOR].id); gfx_quads_begin(); - gfx_quads_setcolor(1,1,1,1); + gfx_setcolor(1,1,1,1); gfx_quads_drawTL(mx,my,24,24); gfx_quads_end(); diff --git a/src/tools/crapnet.cpp b/src/tools/crapnet.cpp index 1c5e3dc3..a12b4ba4 100644 --- a/src/tools/crapnet.cpp +++ b/src/tools/crapnet.cpp @@ -100,10 +100,10 @@ int run(int port, NETADDR4 dest) net_udp4_send(socket, &p->send_to, p->data, p->data_size); // update lag - double flux = 0; //rand()/(double)RAND_MAX; + double flux = rand()/(double)RAND_MAX; int ms_spike = 0; - int ms_flux = 00; - int ms_ping = 100; + int ms_flux = 50; + int ms_ping = 50; current_latency = ((time_freq()*ms_ping)/1000) + (int64)(((time_freq()*ms_flux)/1000)*flux); // 50ms if(ms_spike && (p->id%100) == 0) |