# HG changeset patch # User Michael Pavone # Date 1588401585 25200 # Node ID 275f1c4bdb25005ae4e2c99d4bec230dd2b4c14e # Parent 1c7af12efe8bfa4bdb397fd4bb5ac2c5b07cd0dd Netplay protocol size optimization diff -r 1c7af12efe8b -r 275f1c4bdb25 event_log.c --- a/event_log.c Fri May 01 21:17:21 2020 -0700 +++ b/event_log.c Fri May 01 23:39:45 2020 -0700 @@ -104,9 +104,39 @@ //Four byte: 8-bit type, 24-bit signed delta #define FORMAT_3BYTE 0xE0 #define FORMAT_4BYTE 0xF0 +static uint8_t last_event_type = 0xFF; +static uint32_t last_delta; +static uint8_t multi_count; +static size_t multi_start; static void event_header(uint8_t type, uint32_t cycle) { uint32_t delta = cycle - last; + if (multi_count) { + if (type != last_event_type || delta != last_delta) { + buffer.data[multi_start] |= multi_count - 2; + multi_count = 0; + } else { + ++multi_count; + if (multi_count == 17) { + buffer.data[multi_start] |= multi_count - 2; + last_event_type = 0xFF; + multi_count = 0; + } + return; + } + } else if (type == last_event_type && delta == last_delta) { + //make some room + save_int8(&buffer, 0); + //shift existing command + memmove(buffer.data + multi_start + 1, buffer.data + multi_start, buffer.size - multi_start - 1); + buffer.data[multi_start] = EVENT_MULTI << 4; + multi_count = 2; + return; + } + multi_start = buffer.size; + last_event_type = type; + last_delta = delta; + if (delta > 65535) { save_int8(&buffer, FORMAT_4BYTE | type); save_int8(&buffer, delta >> 16); @@ -202,6 +232,8 @@ if (min_progress == buffer.size) { buffer.size = 0; memset(remote_send_progress, 0, sizeof(remote_send_progress)); + multi_count = 0; + last_event_type = 0xFF; } } @@ -312,6 +344,8 @@ fwrite(buffer.data, 1, buffer.size, event_file); fflush(event_file); buffer.size = 0; + multi_count = 0; + last_event_type = 0xFF; } else if (listen_sock) { flush_socket(); } @@ -321,6 +355,7 @@ { reader->socket = 0; reader->last_cycle = 0; + reader->repeat_event = 0xFF; init_deserialize(&reader->buffer, data, size); } @@ -361,6 +396,12 @@ uint8_t reader_next_event(event_reader *reader, uint32_t *cycle_out) { + if (reader->repeat_remaining) { + reader->repeat_remaining--; + *cycle_out = reader->last_cycle + reader->repeat_delta; + reader->last_cycle = *cycle_out; + return reader->repeat_event; + } if (reader->socket) { uint8_t blocking = 0; if (reader->buffer.size - reader->buffer.cur_pos < 9) { @@ -394,6 +435,12 @@ uint8_t header = load_int8(&reader->buffer); uint8_t ret; uint32_t delta; + uint8_t multi_start = 0; + if ((header & 0xF0) == (EVENT_MULTI << 4)) { + reader->repeat_remaining = (header & 0xF) + 1; + multi_start = 1; + header = load_int8(&reader->buffer); + } if ((header & 0xF0) < FORMAT_3BYTE) { delta = (header & 0xF) + 16; ret = header >> 4; @@ -409,6 +456,10 @@ delta |= load_int16(&reader->buffer); ret = header & 0xF; } + if (multi_start) { + reader->repeat_event = ret; + reader->repeat_delta = delta; + } *cycle_out = reader->last_cycle + delta; reader->last_cycle = *cycle_out; if (ret == EVENT_ADJUST) { diff -r 1c7af12efe8b -r 275f1c4bdb25 event_log.h --- a/event_log.h Fri May 01 21:17:21 2020 -0700 +++ b/event_log.h Fri May 01 23:39:45 2020 -0700 @@ -13,9 +13,9 @@ EVENT_VRAM_BYTE_AUTO = 8, EVENT_VRAM_WORD = 9, EVENT_VRAM_WORD_DELTA = 10, - EVENT_CRAM = 11, - EVENT_VSRAM = 12, - EVENT_STATE = 13 + EVENT_VDP_INTRAM = 11, + EVENT_STATE = 12, + EVENT_MULTI = 13 //14 and 15 are reserved for header types }; @@ -26,7 +26,10 @@ uint32_t last_cycle; uint32_t last_word_address; uint32_t last_byte_address; + uint32_t repeat_delta; deserialize_buffer buffer; + uint8_t repeat_event; + uint8_t repeat_remaining; } event_reader; #include "system.h" diff -r 1c7af12efe8b -r 275f1c4bdb25 vdp.c --- a/vdp.c Fri May 01 21:17:21 2020 -0700 +++ b/vdp.c Fri May 01 23:39:45 2020 -0700 @@ -939,8 +939,8 @@ } else { val = start->partial ? context->fifo[context->fifo_write].value : start->value; } - uint8_t buffer[3] = {start->address, val >> 8, val}; - event_log(EVENT_CRAM, context->cycles, sizeof(buffer), buffer); + uint8_t buffer[3] = {start->address & 127, val >> 8, val}; + event_log(EVENT_VDP_INTRAM, context->cycles, sizeof(buffer), buffer); write_cram(context, start->address, val); break; } @@ -958,8 +958,8 @@ } else { context->vsram[(start->address/2) & 63] = start->partial ? context->fifo[context->fifo_write].value : start->value; } - uint8_t buffer[3] = {(start->address/2) & 63, context->vsram[(start->address/2) & 63] >> 8, context->vsram[(start->address/2) & 63]}; - event_log(EVENT_VSRAM, context->cycles, sizeof(buffer), buffer); + uint8_t buffer[3] = {((start->address/2) & 63) + 128, context->vsram[(start->address/2) & 63] >> 8, context->vsram[(start->address/2) & 63]}; + event_log(EVENT_VDP_INTRAM, context->cycles, sizeof(buffer), buffer); } break; @@ -4590,8 +4590,7 @@ address = reader->last_word_address + load_int8(buffer); break; case EVENT_VDP_REG: - case EVENT_CRAM: - case EVENT_VSRAM: + case EVENT_VDP_INTRAM: address = load_int8(buffer); break; } @@ -4630,11 +4629,12 @@ write_vram_word(context, address, value); break; } - case EVENT_CRAM: - write_cram(context, address, load_int16(buffer)); - break; - case EVENT_VSRAM: - context->vsram[address] = load_int16(buffer); + case EVENT_VDP_INTRAM: + if (address < 128) { + write_cram(context, address, load_int16(buffer)); + } else { + context->vsram[address&63] = load_int16(buffer); + } break; } }