diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/engine/client/ec_client.c | 64 | ||||
| -rw-r--r-- | src/engine/docs/client_time.txt | 7 | ||||
| -rw-r--r-- | src/engine/e_demorec.c | 378 | ||||
| -rw-r--r-- | src/engine/e_demorec.h | 12 | ||||
| -rw-r--r-- | src/engine/e_network.c | 11 | ||||
| -rw-r--r-- | src/engine/e_network.h | 2 | ||||
| -rw-r--r-- | src/engine/e_snapshot.c | 7 | ||||
| -rw-r--r-- | src/engine/server/es_server.c | 10 | ||||
| -rw-r--r-- | src/game/client/components/camera.cpp | 4 | ||||
| -rw-r--r-- | src/game/client/components/items.cpp | 11 | ||||
| -rw-r--r-- | src/game/client/components/players.cpp | 4 | ||||
| -rw-r--r-- | src/game/client/gameclient.cpp | 22 | ||||
| -rw-r--r-- | src/game/server/player.cpp | 2 |
13 files changed, 394 insertions, 140 deletions
diff --git a/src/engine/client/ec_client.c b/src/engine/client/ec_client.c index ece501ab..9c798c30 100644 --- a/src/engine/client/ec_client.c +++ b/src/engine/client/ec_client.c @@ -323,7 +323,7 @@ int client_send_msg() if(info->flags&MSGFLAG_RECORD) { if(demorec_isrecording()) - demorec_record_write("MESG", packet.data_size, packet.data); + demorec_record_message(packet.data, packet.data_size); } if(!(info->flags&MSGFLAG_NOSEND)) @@ -1135,15 +1135,18 @@ static void client_process_packet(NETCHUNK *packet) /* add snapshot to demo */ if(demorec_isrecording()) { - DEMOREC_TICKMARKER marker; /* write tick marker */ + /* + DEMOREC_TICKMARKER marker; marker.tick = game_tick; swap_endian(&marker, sizeof(int), sizeof(marker)/sizeof(int)); demorec_record_write("TICK", sizeof(marker), &marker); + demorec_record_write("SNAP", snapsize, tmpbuffer3); + */ /* write snapshot */ - demorec_record_write("SNAP", snapsize, tmpbuffer3); + demorec_record_snapshot(game_tick, tmpbuffer3, snapsize); } /* apply snapshot, cycle pointers */ @@ -1187,7 +1190,8 @@ static void client_process_packet(NETCHUNK *packet) { /* game message */ if(demorec_isrecording()) - demorec_record_write("MESG", packet->data_size, packet->data); + demorec_record_message(packet->data, packet->data_size); + /* demorec_record_write("MESG", packet->data_size, ); */ modc_message(msg); } @@ -1227,38 +1231,35 @@ static void client_pump_network() client_process_packet(&packet); } -static void client_democallback(DEMOREC_CHUNK chunk, void *data) +static void client_democallback_snapshot(void *data, int size) { - /* dbg_msg("client/playback", "got %c%c%c%c", chunk.type[0], chunk.type[1], chunk.type[2], chunk.type[3]); */ - /* update ticks, they could have changed */ const DEMOREC_PLAYBACKINFO *info = demorec_playback_info(); + SNAPSTORAGE_HOLDER *temp; current_tick = info->current_tick; prev_tick = info->previous_tick; - if(mem_comp(chunk.type, "SNAP", 4) == 0) - { - /* handle snapshots */ - SNAPSTORAGE_HOLDER *temp = snapshots[SNAP_PREV]; - snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT]; - snapshots[SNAP_CURRENT] = temp; - - mem_copy(snapshots[SNAP_CURRENT]->snap, data, chunk.size); - mem_copy(snapshots[SNAP_CURRENT]->alt_snap, data, chunk.size); - - modc_newsnapshot(); - modc_predict(); - } - else if(mem_comp(chunk.type, "MESG", 4) == 0) - { - /* handle messages */ - int sys = 0; - int msg = msg_unpack_start(data, chunk.size, &sys); - if(!sys) - modc_message(msg); - } + /* handle snapshots */ + temp = snapshots[SNAP_PREV]; + snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT]; + snapshots[SNAP_CURRENT] = temp; + + mem_copy(snapshots[SNAP_CURRENT]->snap, data, size); + mem_copy(snapshots[SNAP_CURRENT]->alt_snap, data, size); + + modc_newsnapshot(); + /*modc_predict();*/ +} + +static void client_democallback_message(void *data, int size) +{ + int sys = 0; + int msg = msg_unpack_start(data, size, &sys); + if(!sys) + modc_message(msg); } + const DEMOPLAYBACK_INFO *client_demoplayer_getinfo() { static DEMOPLAYBACK_INFO ret; @@ -1358,8 +1359,8 @@ static void client_update() int new_pred_tick = prev_pred_tick+1; static float last_predintra = 0; - intratick = (now - curtick_start) / (float)(curtick_start-prevtick_start); - ticktime = (now - curtick_start) / (freq/(float)SERVER_TICK_SPEED); + intratick = (now - prevtick_start) / (float)(curtick_start-prevtick_start); + ticktime = (now - prevtick_start) / (float)freq; /*(float)SERVER_TICK_SPEED);*/ graph_add(&intra_graph, intratick*0.25f); @@ -1714,7 +1715,7 @@ void client_demoplayer_play(const char *filename) client_disconnect(); /* try to start playback */ - demorec_playback_registercallback(client_democallback); + demorec_playback_registercallbacks(client_democallback_snapshot, client_democallback_message); if(demorec_playback_load(filename)) return; @@ -1803,6 +1804,7 @@ int main(int argc, char **argv) dbg_msg("client", "starting..."); engine_init("Teeworlds"); + /* register all console commands */ client_register_commands(); modc_console_init(); diff --git a/src/engine/docs/client_time.txt b/src/engine/docs/client_time.txt index 24ca2be5..bc76f91c 100644 --- a/src/engine/docs/client_time.txt +++ b/src/engine/docs/client_time.txt @@ -2,3 +2,10 @@ Title: Time on the client tick, intratick predtick, predintratick + + prevtick tick predtick + 4 8 14 + |---------------------|---------------------| + 0 <- intratick -> 1 + 0 <- ticktime(in s)-> X + 0 <- predintratick?-> 1 diff --git a/src/engine/e_demorec.c b/src/engine/e_demorec.c index 1fae2b77..07d7d628 100644 --- a/src/engine/e_demorec.c +++ b/src/engine/e_demorec.c @@ -2,12 +2,18 @@ #include <base/system.h> #include "e_demorec.h" #include "e_memheap.h" +#include "e_snapshot.h" +#include "e_compression.h" +#include "e_network.h" #include "e_if_other.h" static IOHANDLE record_file = 0; static const unsigned char header_marker[8] = {'T', 'W', 'D', 'E', 'M', 'O', 0, 1}; /* Record */ +static int record_lasttickmarker = -1; +static int record_lastkeyframe; +static unsigned char record_lastsnapshotdata[MAX_SNAPSHOT_SIZE]; int demorec_isrecording() { return record_file != 0; } @@ -37,24 +43,143 @@ int demorec_record_start(const char *filename, const char *netversion, const cha header.crc[3] = (crc)&0xff; io_write(record_file, &header, sizeof(header)); + record_lastkeyframe = -1; + record_lasttickmarker = -1; + dbg_msg("demorec/record", "Recording to '%s'", filename); return 0; } -void demorec_record_write(const char *type, int size, const void *data) +/* + Tickmarker + 7 = Always set + 6 = Keyframe flag + 0-5 = Delta tick + + Normal + 7 = Not set + 5-6 = Type + 0-4 = Size +*/ + +enum +{ + CHUNKTYPEFLAG_TICKMARKER = 0x80, + CHUNKTICKFLAG_KEYFRAME = 0x40, /* only when tickmarker is set*/ + + CHUNKMASK_TICK = 0x3f, + CHUNKMASK_TYPE = 0x60, + CHUNKMASK_SIZE = 0x1f, + + CHUNKTYPE_SNAPSHOT = 1, + CHUNKTYPE_MESSAGE = 2, + CHUNKTYPE_DELTA = 3, + + CHUNKFLAG_BIGSIZE = 0x10 +}; + +static void demorec_record_write_tickmarker(int tick, int keyframe) { - DEMOREC_CHUNK chunk; + if(record_lasttickmarker == -1 || tick-record_lasttickmarker > 63 || keyframe) + { + unsigned char chunk[5]; + chunk[0] = CHUNKTYPEFLAG_TICKMARKER; + chunk[1] = (tick>>24)&0xff; + chunk[2] = (tick>>16)&0xff; + chunk[3] = (tick>>8)&0xff; + chunk[4] = (tick)&0xff; + + if(keyframe) + chunk[0] |= CHUNKTICKFLAG_KEYFRAME; + + io_write(record_file, chunk, sizeof(chunk)); + } + else + { + unsigned char chunk[1]; + chunk[0] = CHUNKTYPEFLAG_TICKMARKER | (tick-record_lasttickmarker); + io_write(record_file, chunk, sizeof(chunk)); + } + + record_lasttickmarker = tick; +} + +static void demorec_record_write(int type, const void *data, int size) +{ + char buffer[64*1024]; + char buffer2[64*1024]; + unsigned char chunk[3]; + if(!record_file) return; + + size = intpack_compress(data, size, buffer); + size = netcommon_compress(buffer, size, buffer2, sizeof(buffer2)); + + + chunk[0] = ((type&0x3)<<5); + if(size < 30) + { + chunk[0] |= size; + io_write(record_file, chunk, 1); + } + else + { + if(size < 256) + { + chunk[0] |= 30; + chunk[1] = size&0xff; + io_write(record_file, chunk, 2); + } + else + { + chunk[0] |= 31; + chunk[1] = size&0xff; + chunk[2] = size>>8; + io_write(record_file, chunk, 3); + } + } - chunk.type[0] = type[0]; - chunk.type[1] = type[1]; - chunk.type[2] = type[2]; - chunk.type[3] = type[3]; - chunk.size = size; - swap_endian(&chunk.size, sizeof(int), 1); - io_write(record_file, &chunk, sizeof(chunk)); - io_write(record_file, data, size); + io_write(record_file, buffer2, size); +} + +void demorec_record_snapshot(int tick, const void *data, int size) +{ + record_emptydeltatick = -1; + + if(record_lastkeyframe == -1 || (tick-record_lastkeyframe) > SERVER_TICK_SPEED*5) + { + /* write full tickmarker */ + demorec_record_write_tickmarker(tick, 1); + + /* write snapshot */ + demorec_record_write(CHUNKTYPE_SNAPSHOT, data, size); + + record_lastkeyframe = tick; + mem_copy(record_lastsnapshotdata, data, size); + } + else + { + /* create delta, prepend tick */ + char delta_data[MAX_SNAPSHOT_SIZE+sizeof(int)]; + int delta_size; + + /* write tickmarker */ + demorec_record_write_tickmarker(tick, 0); + + delta_size = snapshot_create_delta((SNAPSHOT*)record_lastsnapshotdata, (SNAPSHOT*)data, &delta_data); + if(delta_size) + { + /* record delta */ + demorec_record_write(CHUNKTYPE_DELTA, delta_data, delta_size); + mem_copy(record_lastsnapshotdata, data, size); + } + } +} + +void demorec_record_message(const void *data, int size) +{ + demorec_record_write(CHUNKTYPE_MESSAGE, data, size); } int demorec_record_stop() @@ -69,7 +194,6 @@ int demorec_record_stop() } /* Playback */ - typedef struct KEYFRAME { long filepos; @@ -83,25 +207,77 @@ typedef struct KEYFRAME_SEARCH } KEYFRAME_SEARCH; static IOHANDLE play_file = 0; -static DEMOREC_PLAYCALLBACK play_callback = 0; +static DEMOREC_PLAYCALLBACK play_callback_snapshot = 0; +static DEMOREC_PLAYCALLBACK play_callback_message = 0; static KEYFRAME *keyframes = 0; static DEMOREC_PLAYBACKINFO playbackinfo; -const DEMOREC_PLAYBACKINFO *demorec_playback_info() { return &playbackinfo; } +static unsigned char playback_lastsnapshotdata[MAX_SNAPSHOT_SIZE]; +static int playback_lastsnapshotdata_size = -1; + +const DEMOREC_PLAYBACKINFO *demorec_playback_info() { return &playbackinfo; } int demorec_isplaying() { return play_file != 0; } -int demorec_playback_registercallback(DEMOREC_PLAYCALLBACK cb) +int demorec_playback_registercallbacks(DEMOREC_PLAYCALLBACK snapshot_cb, DEMOREC_PLAYCALLBACK message_cb) { - play_callback = cb; + play_callback_snapshot = snapshot_cb; + play_callback_message = message_cb; return 0; } -static int read_chunk_header(DEMOREC_CHUNK *chunk) +static int read_chunk_header(int *type, int *size, int *tick) { - if(io_read(play_file, chunk, sizeof(*chunk)) != sizeof(*chunk)) + unsigned char chunk = 0; + + *size = 0; + *type = 0; + + if(io_read(play_file, &chunk, sizeof(chunk)) != sizeof(chunk)) return -1; - swap_endian(&chunk->size, sizeof(int), 1); + + if(chunk&CHUNKTYPEFLAG_TICKMARKER) + { + /* decode tick marker */ + int tickdelta = chunk&(CHUNKMASK_TICK); + *type = chunk&(CHUNKTYPEFLAG_TICKMARKER|CHUNKTICKFLAG_KEYFRAME); + + if(tickdelta == 0) + { + unsigned char tickdata[4]; + if(io_read(play_file, tickdata, sizeof(tickdata)) != sizeof(tickdata)) + return -1; + *tick = (tickdata[0]<<24) | (tickdata[1]<<16) | (tickdata[2]<<8) | tickdata[3]; + } + else + { + *tick += tickdelta; + } + + } + else + { + /* decode normal chunk */ + *type = (chunk&CHUNKMASK_TYPE)>>5; + *size = chunk&CHUNKMASK_SIZE; + + if(*size == 30) + { + unsigned char sizedata[1]; + if(io_read(play_file, sizedata, sizeof(sizedata)) != sizeof(sizedata)) + return -1; + *size = sizedata[0]; + + } + else if(*size == 31) + { + unsigned char sizedata[2]; + if(io_read(play_file, sizedata, sizeof(sizedata)) != sizeof(sizedata)) + return -1; + *size = (sizedata[1]<<8) | sizedata[0]; + } + } + return 0; } @@ -111,7 +287,8 @@ static void scan_file() HEAP *heap = 0; KEYFRAME_SEARCH *first_key = 0; KEYFRAME_SEARCH *current_key = 0; - DEMOREC_CHUNK chunk; + /*DEMOREC_CHUNK chunk;*/ + int chunk_size, chunk_type, chunk_tick = 0; int i; heap = memheap_create(); @@ -122,37 +299,38 @@ static void scan_file() while(1) { long current_pos = io_tell(play_file); - - if(read_chunk_header(&chunk)) + + if(read_chunk_header(&chunk_type, &chunk_size, &chunk_tick)) break; /* read the chunk */ - - if(mem_comp(chunk.type, "TICK", 4) == 0) + if(chunk_type&CHUNKTYPEFLAG_TICKMARKER) { - KEYFRAME_SEARCH *key; - DEMOREC_TICKMARKER marker; - io_read(play_file, &marker, chunk.size); - swap_endian(&marker.tick, sizeof(int), 1); - - /* save the position */ - key = memheap_allocate(heap, sizeof(KEYFRAME_SEARCH)); - key->frame.filepos = current_pos; - key->frame.tick = marker.tick; - key->next = 0; - if(current_key) - current_key->next = key; - if(!first_key) - first_key = key; - current_key = key; + if(chunk_type&CHUNKTICKFLAG_KEYFRAME) + { + KEYFRAME_SEARCH *key; + + /* save the position */ + key = memheap_allocate(heap, sizeof(KEYFRAME_SEARCH)); + key->frame.filepos = current_pos; + key->frame.tick = chunk_tick; + key->next = 0; + if(current_key) + current_key->next = key; + if(!first_key) + first_key = key; + current_key = key; + playbackinfo.seekable_points++; + } if(playbackinfo.first_tick == -1) - playbackinfo.first_tick = marker.tick; - playbackinfo.last_tick = marker.tick; - playbackinfo.seekable_points++; + playbackinfo.first_tick = chunk_tick; + playbackinfo.last_tick = chunk_tick; + dbg_msg("", "%x %d", chunk_type, chunk_tick); } - else - io_skip(play_file, chunk.size); + else if(chunk_size) + io_skip(play_file, chunk_size); + } /* copy all the frames to an array instead for fast access */ @@ -167,41 +345,109 @@ static void scan_file() static void do_tick() { - static char buffer[64*1024]; - DEMOREC_CHUNK chunk; + static char compresseddata[MAX_SNAPSHOT_SIZE]; + static char decompressed[MAX_SNAPSHOT_SIZE]; + static char data[MAX_SNAPSHOT_SIZE]; + int chunk_size, chunk_type, chunk_tick; + int data_size; + int got_snapshot = 0; /* update ticks */ playbackinfo.previous_tick = playbackinfo.current_tick; playbackinfo.current_tick = playbackinfo.next_tick; + chunk_tick = playbackinfo.current_tick; while(1) { - int r = read_chunk_header(&chunk); - if(chunk.size > sizeof(buffer)) - { - dbg_msg("demorec/playback", "chunk is too big %d", chunk.size); - r = 1; - } - - if(r) + if(read_chunk_header(&chunk_type, &chunk_size, &chunk_tick)) { /* stop on error or eof */ + dbg_msg("demorec", "end of file"); demorec_playback_stop(); break; } /* read the chunk */ - io_read(play_file, buffer, chunk.size); + if(chunk_size) + { + if(io_read(play_file, compresseddata, chunk_size) != chunk_size) + { + /* stop on error or eof */ + dbg_msg("demorec", "error reading chunk"); + demorec_playback_stop(); + break; + } + + data_size = netcommon_decompress(compresseddata, chunk_size, decompressed, sizeof(decompressed)); + if(data_size < 0) + { + /* stop on error or eof */ + dbg_msg("demorec", "error during network decompression"); + demorec_playback_stop(); + break; + } - if(mem_comp(chunk.type, "TICK", 4) == 0) + data_size = intpack_decompress(decompressed, data_size, data); + + if(data_size < 0) + { + dbg_msg("demorec", "error during intpack decompression"); + demorec_playback_stop(); + break; + } + } + + if(chunk_type == CHUNKTYPE_DELTA) { - DEMOREC_TICKMARKER marker = *(DEMOREC_TICKMARKER *)buffer; - swap_endian(&marker.tick, sizeof(int), 1); - playbackinfo.next_tick = marker.tick; - break; + /* process delta snapshot */ + static char newsnap[MAX_SNAPSHOT_SIZE]; + + got_snapshot = 1; + + data_size = snapshot_unpack_delta((SNAPSHOT*)playback_lastsnapshotdata, (SNAPSHOT*)newsnap, data, data_size); + + if(data_size >= 0) + { + if(play_callback_snapshot) + play_callback_snapshot(newsnap, data_size); + + playback_lastsnapshotdata_size = data_size; + mem_copy(playback_lastsnapshotdata, newsnap, data_size); + } + else + dbg_msg("demorec", "error duing unpacking of delta, err=%d", data_size); + } + else if(chunk_type == CHUNKTYPE_SNAPSHOT) + { + /* process full snapshot */ + got_snapshot = 1; + + playback_lastsnapshotdata_size = data_size; + mem_copy(playback_lastsnapshotdata, data, data_size); + if(play_callback_snapshot) + play_callback_snapshot(data, data_size); + } + else + { + /* if there were no snapshots in this tick, replay the last one */ + if(!got_snapshot && play_callback_snapshot && playback_lastsnapshotdata_size != -1) + { + got_snapshot = 1; + play_callback_snapshot(playback_lastsnapshotdata, playback_lastsnapshotdata_size); + } + + /* check the remaining types */ + if(chunk_type&CHUNKTYPEFLAG_TICKMARKER) + { + playbackinfo.next_tick = chunk_tick; + break; + } + else if(chunk_type == CHUNKTYPE_MESSAGE) + { + if(play_callback_message) + play_callback_message(data, data_size); + } } - else if(play_callback) - play_callback(chunk, buffer); } } @@ -238,6 +484,8 @@ int demorec_playback_load(const char *filename) playbackinfo.current_tick = -1; playbackinfo.previous_tick = -1; playbackinfo.speed = 1; + + playback_lastsnapshotdata_size = -1; /* read the header */ io_read(play_file, &playbackinfo.header, sizeof(playbackinfo.header)); @@ -256,6 +504,12 @@ int demorec_playback_load(const char *filename) return 0; } +int demorec_playback_nextframe() +{ + do_tick(); + return demorec_isplaying(); +} + int demorec_playback_play() { /* fill in previous and next tick */ @@ -326,7 +580,7 @@ int demorec_playback_update() int64 curtick_start = (playbackinfo.current_tick)*freq/SERVER_TICK_SPEED; int64 prevtick_start = (playbackinfo.previous_tick)*freq/SERVER_TICK_SPEED; playbackinfo.intratick = (playbackinfo.current_time - prevtick_start) / (float)(curtick_start-prevtick_start); - playbackinfo.ticktime = (playbackinfo.current_time - prevtick_start) / (freq/(float)SERVER_TICK_SPEED); + playbackinfo.ticktime = (playbackinfo.current_time - prevtick_start) / (float)freq; } if(playbackinfo.current_tick == playbackinfo.previous_tick || diff --git a/src/engine/e_demorec.h b/src/engine/e_demorec.h index f6ceb382..bc54dddd 100644 --- a/src/engine/e_demorec.h +++ b/src/engine/e_demorec.h @@ -10,8 +10,8 @@ typedef struct DEMOREC_HEADER typedef struct DEMOREC_CHUNK { - char type[4]; - int size; + char type[2]; + unsigned short size; } DEMOREC_CHUNK; typedef struct DEMOREC_TICKMARKER @@ -44,13 +44,15 @@ typedef struct DEMOREC_PLAYBACKINFO int demorec_record_start(const char *filename, const char *netversion, const char *map, int map_crc, const char *type); int demorec_isrecording(); -void demorec_record_write(const char *type, int size, const void *data); +void demorec_record_snapshot(int tick, const void *data, int size); +void demorec_record_message(const void *data, int size); int demorec_record_stop(); -typedef void (*DEMOREC_PLAYCALLBACK)(DEMOREC_CHUNK chunk, void *data); +typedef void (*DEMOREC_PLAYCALLBACK)(void *data, int size); -int demorec_playback_registercallback(DEMOREC_PLAYCALLBACK cb); +int demorec_playback_registercallbacks(DEMOREC_PLAYCALLBACK snapshot_cb, DEMOREC_PLAYCALLBACK message_cb); int demorec_playback_load(const char *filename); +int demorec_playback_nextframe(); int demorec_playback_play(); void demorec_playback_pause(); void demorec_playback_unpause(); diff --git a/src/engine/e_network.c b/src/engine/e_network.c index 2ed45707..770cfae1 100644 --- a/src/engine/e_network.c +++ b/src/engine/e_network.c @@ -96,6 +96,16 @@ void send_packet_connless(NETSOCKET socket, NETADDR *addr, const void *data, int net_udp_send(socket, addr, buffer, 6+data_size); } +int netcommon_compress(const void *data, int data_size, void *output, int output_size) +{ + return huffman_compress(&huffmanstate, data, data_size, output, output_size); +} + +int netcommon_decompress(const void *data, int data_size, void *output, int output_size) +{ + return huffman_decompress(&huffmanstate, data, data_size, output, output_size); +} + void send_packet(NETSOCKET socket, NETADDR *addr, NETPACKETCONSTRUCT *packet) { unsigned char buffer[NET_MAX_PACKETSIZE]; @@ -207,7 +217,6 @@ void netcommon_openlog(const char *filename) datalog = io_open(filename, IOFLAG_WRITE); } - static const unsigned freq_table[256+1] = { 1<<30,4545,2657,431,1950,919,444,482,2244,617,838,542,715,1814,304,240,754,212,647,186, 283,131,146,166,543,164,167,136,179,859,363,113,157,154,204,108,137,180,202,176, diff --git a/src/engine/e_network.h b/src/engine/e_network.h index 1ac02708..4064e8d6 100644 --- a/src/engine/e_network.h +++ b/src/engine/e_network.h @@ -57,6 +57,8 @@ typedef int (*NETFUNC_NEWCLIENT)(int cid, void *user); /* both */ void netcommon_openlog(const char *filename); void netcommon_init(); +int netcommon_compress(const void *data, int data_size, void *output, int output_size); +int netcommon_decompress(const void *data, int data_size, void *output, int output_size); /* server side */ NETSERVER *netserver_open(NETADDR bindaddr, int max_clients, int flags); diff --git a/src/engine/e_snapshot.c b/src/engine/e_snapshot.c index 88949b65..cce8a06e 100644 --- a/src/engine/e_snapshot.c +++ b/src/engine/e_snapshot.c @@ -11,7 +11,6 @@ static short item_sizes[64] = {0}; void snap_set_staticsize(int itemtype, int size) { - dbg_msg("","%d = %d", itemtype, size); item_sizes[itemtype] = size; } @@ -397,12 +396,12 @@ int snapshot_unpack_delta(SNAPSHOT *from, SNAPSHOT *to, void *srcdata, int data_ else { if(data+1 > end) - return -1; + return -2; itemsize = (*data++) * 4; } snapshot_current = type; - if(range_check(end, data, itemsize) || itemsize < 0) return -1; + if(range_check(end, data, itemsize) || itemsize < 0) return -3; key = (type<<16)|id; @@ -411,7 +410,7 @@ int snapshot_unpack_delta(SNAPSHOT *from, SNAPSHOT *to, void *srcdata, int data_ if(!newdata) newdata = (int *)snapbuild_new_item(&builder, key>>16, key&0xffff, itemsize); - if(range_check(end, newdata, itemsize)) return -1; + /*if(range_check(end, newdata, itemsize)) return -4;*/ fromindex = snapshot_get_item_index(from, key); if(fromindex != -1) diff --git a/src/engine/server/es_server.c b/src/engine/server/es_server.c index 067d7a89..9c4d74c5 100644 --- a/src/engine/server/es_server.c +++ b/src/engine/server/es_server.c @@ -342,7 +342,7 @@ int server_send_msg(int client_id) /* write message to demo recorder */ if(!(info->flags&MSGFLAG_NORECORD)) - demorec_record_write("MESG", info->size, info->data); + demorec_record_message(info->data, info->size); if(!(info->flags&MSGFLAG_NOSEND)) { @@ -379,20 +379,14 @@ static void server_do_snap() { char data[MAX_SNAPSHOT_SIZE]; int snapshot_size; - DEMOREC_TICKMARKER marker; - /* write tick marker */ - marker.tick = server_tick(); - swap_endian(&marker, sizeof(int), sizeof(marker)/sizeof(int)); - demorec_record_write("TICK", sizeof(marker), &marker); - /* build snap and possibly add some messages */ snapbuild_init(&builder); mods_snap(-1); snapshot_size = snapbuild_finish(&builder, data); /* write snapshot */ - demorec_record_write("SNAP", snapshot_size, data); + demorec_record_snapshot(server_tick(), data, snapshot_size); } /* create snapshots for all clients */ diff --git a/src/game/client/components/camera.cpp b/src/game/client/components/camera.cpp index ba9aed46..7b188e00 100644 --- a/src/game/client/components/camera.cpp +++ b/src/game/client/components/camera.cpp @@ -19,7 +19,8 @@ void CAMERA::on_render() { //vec2 center; zoom = 1.0f; - + + // update camera center if(gameclient.snap.spectate) center = gameclient.controls->mouse_pos; else @@ -37,4 +38,3 @@ void CAMERA::on_render() center = gameclient.local_character_pos + camera_offset; } } - diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp index 43ad3319..c880b93e 100644 --- a/src/game/client/components/items.cpp +++ b/src/game/client/components/items.cpp @@ -14,8 +14,6 @@ void ITEMS::render_projectile(const NETOBJ_PROJECTILE *current, int itemid) { - gfx_texture_set(data->images[IMAGE_GAME].id); - gfx_quads_begin(); // get positions float curvature = 0; @@ -36,12 +34,19 @@ void ITEMS::render_projectile(const NETOBJ_PROJECTILE *current, int itemid) speed = gameclient.tuning.gun_speed; } - float ct = (client_tick()-current->start_tick)/(float)SERVER_TICK_SPEED + client_ticktime()*1/(float)SERVER_TICK_SPEED; + float ct = (client_prevtick()-current->start_tick)/(float)SERVER_TICK_SPEED + client_ticktime(); + if(ct < 0) + return; // projectile havn't been shot yet + vec2 startpos(current->x, current->y); vec2 startvel(current->vx/100.0f, current->vy/100.0f); vec2 pos = calc_pos(startpos, startvel, curvature, speed, ct); vec2 prevpos = calc_pos(startpos, startvel, curvature, speed, ct-0.001f); + + gfx_texture_set(data->images[IMAGE_GAME].id); + gfx_quads_begin(); + select_sprite(data->weapons.id[clamp(current->type, 0, NUM_WEAPONS-1)].sprite_proj); vec2 vel = pos-prevpos; //vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick()); diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index 02977632..8125b6d9 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -145,12 +145,10 @@ void PLAYERS::render_player( intratick = client_predintratick(); } } - + vec2 position = mix(vec2(prev.x, prev.y), vec2(player.x, player.y), intratick); vec2 vel = mix(vec2(prev.vx/256.0f, prev.vy/256.0f), vec2(player.vx/256.0f, player.vy/256.0f), intratick); - //dbg_msg("", "%d %d %d %d %f", prev.x, prev.y, player.x, player.y, intratick); - gameclient.flow->add(position, vel*100.0f, 10.0f); render_info.got_airjump = player.jumped&2?0:1; diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 7c9a1ed6..22800a7a 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -303,7 +303,7 @@ void GAMECLIENT::on_reset() void GAMECLIENT::update_local_character_pos() { - if(config.cl_predict) + if(config.cl_predict && client_state() != CLIENTSTATE_DEMOPLAYBACK) { if(!snap.local_character || (snap.local_character->health < 0) || (snap.gameobj && snap.gameobj->game_over)) { @@ -328,7 +328,7 @@ static void evolve(NETOBJ_CHARACTER *character, int tick) mem_zero(&tempcore, sizeof(tempcore)); tempcore.world = &tempworld; tempcore.read(character); - //tempcore.input.direction = character->wanted_direction; + while(character->tick < tick) { character->tick++; @@ -343,21 +343,6 @@ static void evolve(NETOBJ_CHARACTER *character, int tick) void GAMECLIENT::on_render() { - // perform dead reckoning - // TODO: move this to a betterlocation - /* - for(int i = 0; i < MAX_CLIENTS; i++) - { - if(!snap.characters[i].active) - continue; - - // perform dead reckoning - if(snap.characters[i].prev.tick) - evolve(&snap.characters[i].prev, client_prevtick()); - if(snap.characters[i].cur.tick) - evolve(&snap.characters[i].cur, client_tick()); - }*/ - // update the local character position update_local_character_pos(); @@ -621,9 +606,6 @@ void GAMECLIENT::on_snapshot() } } - if(client_state() == CLIENTSTATE_DEMOPLAYBACK) - gameclient.snap.spectate = true; - // setup local pointers if(snap.local_cid >= 0) { diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index b2f72d0e..02e92c36 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -130,7 +130,7 @@ void PLAYER::kill_character() //CHARACTER *chr = get_character(); if(character) { - character->die(-1, -1); + character->die(client_id, -1); delete character; character = 0; } |