Mercurial > repos > blastem
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; |