changeset 1956:275f1c4bdb25

Netplay protocol size optimization
author Michael Pavone <pavone@retrodev.com>
date Fri, 01 May 2020 23:39:45 -0700
parents 1c7af12efe8b
children ba06346611a1
files event_log.c event_log.h vdp.c
diffstat 3 files changed, 68 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- 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) {
--- 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"
--- 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;
 	}
 }