comparison event_log.c @ 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
comparison
equal deleted inserted replaced
1955:1c7af12efe8b 1956:275f1c4bdb25
102 //Single byte: 4 bit type, 4 bit delta (16-31) 102 //Single byte: 4 bit type, 4 bit delta (16-31)
103 //Three Byte: 8 bit type, 16-bit delta 103 //Three Byte: 8 bit type, 16-bit delta
104 //Four byte: 8-bit type, 24-bit signed delta 104 //Four byte: 8-bit type, 24-bit signed delta
105 #define FORMAT_3BYTE 0xE0 105 #define FORMAT_3BYTE 0xE0
106 #define FORMAT_4BYTE 0xF0 106 #define FORMAT_4BYTE 0xF0
107 static uint8_t last_event_type = 0xFF;
108 static uint32_t last_delta;
109 static uint8_t multi_count;
110 static size_t multi_start;
107 static void event_header(uint8_t type, uint32_t cycle) 111 static void event_header(uint8_t type, uint32_t cycle)
108 { 112 {
109 uint32_t delta = cycle - last; 113 uint32_t delta = cycle - last;
114 if (multi_count) {
115 if (type != last_event_type || delta != last_delta) {
116 buffer.data[multi_start] |= multi_count - 2;
117 multi_count = 0;
118 } else {
119 ++multi_count;
120 if (multi_count == 17) {
121 buffer.data[multi_start] |= multi_count - 2;
122 last_event_type = 0xFF;
123 multi_count = 0;
124 }
125 return;
126 }
127 } else if (type == last_event_type && delta == last_delta) {
128 //make some room
129 save_int8(&buffer, 0);
130 //shift existing command
131 memmove(buffer.data + multi_start + 1, buffer.data + multi_start, buffer.size - multi_start - 1);
132 buffer.data[multi_start] = EVENT_MULTI << 4;
133 multi_count = 2;
134 return;
135 }
136 multi_start = buffer.size;
137 last_event_type = type;
138 last_delta = delta;
139
110 if (delta > 65535) { 140 if (delta > 65535) {
111 save_int8(&buffer, FORMAT_4BYTE | type); 141 save_int8(&buffer, FORMAT_4BYTE | type);
112 save_int8(&buffer, delta >> 16); 142 save_int8(&buffer, delta >> 16);
113 save_int16(&buffer, delta); 143 save_int16(&buffer, delta);
114 } else if (delta >= 16 && delta < 32) { 144 } else if (delta >= 16 && delta < 32) {
200 } 230 }
201 } 231 }
202 if (min_progress == buffer.size) { 232 if (min_progress == buffer.size) {
203 buffer.size = 0; 233 buffer.size = 0;
204 memset(remote_send_progress, 0, sizeof(remote_send_progress)); 234 memset(remote_send_progress, 0, sizeof(remote_send_progress));
235 multi_count = 0;
236 last_event_type = 0xFF;
205 } 237 }
206 } 238 }
207 239
208 void event_log(uint8_t type, uint32_t cycle, uint8_t size, uint8_t *payload) 240 void event_log(uint8_t type, uint32_t cycle, uint8_t size, uint8_t *payload)
209 { 241 {
310 } 342 }
311 if (event_file) { 343 if (event_file) {
312 fwrite(buffer.data, 1, buffer.size, event_file); 344 fwrite(buffer.data, 1, buffer.size, event_file);
313 fflush(event_file); 345 fflush(event_file);
314 buffer.size = 0; 346 buffer.size = 0;
347 multi_count = 0;
348 last_event_type = 0xFF;
315 } else if (listen_sock) { 349 } else if (listen_sock) {
316 flush_socket(); 350 flush_socket();
317 } 351 }
318 } 352 }
319 353
320 void init_event_reader(event_reader *reader, uint8_t *data, size_t size) 354 void init_event_reader(event_reader *reader, uint8_t *data, size_t size)
321 { 355 {
322 reader->socket = 0; 356 reader->socket = 0;
323 reader->last_cycle = 0; 357 reader->last_cycle = 0;
358 reader->repeat_event = 0xFF;
324 init_deserialize(&reader->buffer, data, size); 359 init_deserialize(&reader->buffer, data, size);
325 } 360 }
326 361
327 void init_event_reader_tcp(event_reader *reader, char *address, char *port) 362 void init_event_reader_tcp(event_reader *reader, char *address, char *port)
328 { 363 {
359 setsockopt(reader->socket, IPPROTO_TCP, TCP_NODELAY, (const char *)&flag, sizeof(flag)); 394 setsockopt(reader->socket, IPPROTO_TCP, TCP_NODELAY, (const char *)&flag, sizeof(flag));
360 } 395 }
361 396
362 uint8_t reader_next_event(event_reader *reader, uint32_t *cycle_out) 397 uint8_t reader_next_event(event_reader *reader, uint32_t *cycle_out)
363 { 398 {
399 if (reader->repeat_remaining) {
400 reader->repeat_remaining--;
401 *cycle_out = reader->last_cycle + reader->repeat_delta;
402 reader->last_cycle = *cycle_out;
403 return reader->repeat_event;
404 }
364 if (reader->socket) { 405 if (reader->socket) {
365 uint8_t blocking = 0; 406 uint8_t blocking = 0;
366 if (reader->buffer.size - reader->buffer.cur_pos < 9) { 407 if (reader->buffer.size - reader->buffer.cur_pos < 9) {
367 //set back to block mode 408 //set back to block mode
368 socket_blocking(reader->socket, 1); 409 socket_blocking(reader->socket, 1);
392 } 433 }
393 } 434 }
394 uint8_t header = load_int8(&reader->buffer); 435 uint8_t header = load_int8(&reader->buffer);
395 uint8_t ret; 436 uint8_t ret;
396 uint32_t delta; 437 uint32_t delta;
438 uint8_t multi_start = 0;
439 if ((header & 0xF0) == (EVENT_MULTI << 4)) {
440 reader->repeat_remaining = (header & 0xF) + 1;
441 multi_start = 1;
442 header = load_int8(&reader->buffer);
443 }
397 if ((header & 0xF0) < FORMAT_3BYTE) { 444 if ((header & 0xF0) < FORMAT_3BYTE) {
398 delta = (header & 0xF) + 16; 445 delta = (header & 0xF) + 16;
399 ret = header >> 4; 446 ret = header >> 4;
400 } else if ((header & 0xF0) == FORMAT_3BYTE) { 447 } else if ((header & 0xF0) == FORMAT_3BYTE) {
401 delta = load_int16(&reader->buffer); 448 delta = load_int16(&reader->buffer);
406 if (delta & 0x800000) { 453 if (delta & 0x800000) {
407 delta |= 0xFF000000; 454 delta |= 0xFF000000;
408 } 455 }
409 delta |= load_int16(&reader->buffer); 456 delta |= load_int16(&reader->buffer);
410 ret = header & 0xF; 457 ret = header & 0xF;
458 }
459 if (multi_start) {
460 reader->repeat_event = ret;
461 reader->repeat_delta = delta;
411 } 462 }
412 *cycle_out = reader->last_cycle + delta; 463 *cycle_out = reader->last_cycle + delta;
413 reader->last_cycle = *cycle_out; 464 reader->last_cycle = *cycle_out;
414 if (ret == EVENT_ADJUST) { 465 if (ret == EVENT_ADJUST) {
415 size_t old_pos = reader->buffer.cur_pos; 466 size_t old_pos = reader->buffer.cur_pos;