comparison event_log.c @ 1974:04b79a725b7f

Better handling of pad assignment to remotes
author Michael Pavone <pavone@retrodev.com>
date Fri, 08 May 2020 16:38:58 -0700
parents cd163b230cf9
children a042e046f7f2
comparison
equal deleted inserted replaced
1973:cd163b230cf9 1974:04b79a725b7f
77 event_log_common_init(); 77 event_log_common_init();
78 fully_active = 1; 78 fully_active = 1;
79 atexit(file_finish); 79 atexit(file_finish);
80 } 80 }
81 81
82 static int listen_sock, remotes[7]; 82 typedef struct {
83 uint8_t *send_progress;
84 int sock;
85 uint8_t players[1]; //TODO: Expand when support for multiple players per remote is added
86 uint8_t num_players;
87 } remote;
88
89 static int listen_sock;
90 static remote remotes[7];
83 static int num_remotes; 91 static int num_remotes;
92 static uint8_t available_players[7] = {2,3,4,5,6,7,8};
93 static int num_available_players = 7;
84 void event_log_tcp(char *address, char *port) 94 void event_log_tcp(char *address, char *port)
85 { 95 {
86 struct addrinfo request, *result; 96 struct addrinfo request, *result;
87 socket_init(); 97 socket_init();
88 memset(&request, 0, sizeof(request)); 98 memset(&request, 0, sizeof(request));
195 event_header(EVENT_ADJUST, cycle); 205 event_header(EVENT_ADJUST, cycle);
196 last = cycle - deduction; 206 last = cycle - deduction;
197 save_int32(&buffer, deduction); 207 save_int32(&buffer, deduction);
198 } 208 }
199 209
200 static uint8_t *remote_send_progress[7]; 210 static uint8_t next_available_player(void)
201 static uint8_t remote_needs_state[7]; 211 {
212 uint8_t lowest = 0xFF;
213 int lowest_index = -1;
214 for (int i = 0; i < num_available_players; i++)
215 {
216 if (available_players[i] < lowest) {
217 lowest = available_players[i];
218 lowest_index = i;
219 }
220 }
221 if (lowest_index >= 0) {
222 available_players[lowest_index] = available_players[num_available_players - 1];
223 --num_available_players;
224 }
225 return lowest;
226 }
227
202 static void flush_socket(void) 228 static void flush_socket(void)
203 { 229 {
204 int remote = accept(listen_sock, NULL, NULL); 230 int remote_sock = accept(listen_sock, NULL, NULL);
205 if (remote != -1) { 231 if (remote_sock != -1) {
206 if (num_remotes == 7) { 232 if (num_remotes == 7) {
207 socket_close(remote); 233 socket_close(remote_sock);
208 } else { 234 } else {
209 printf("remote %d connected\n", num_remotes); 235 printf("remote %d connected\n", num_remotes);
210 remotes[num_remotes] = remote; 236 uint8_t player = next_available_player();
211 remote_needs_state[num_remotes++] = 1; 237 remotes[num_remotes++] = (remote){
238 .sock = remote_sock,
239 .send_progress = NULL,
240 .players = {player},
241 .num_players = player == 0xFF ? 0 : 1
242 };
212 current_system->save_state = EVENTLOG_SLOT + 1; 243 current_system->save_state = EVENTLOG_SLOT + 1;
213 } 244 }
214 } 245 }
215 uint8_t *min_progress = compressed; 246 uint8_t *min_progress = compressed;
216 for (int i = 0; i < num_remotes; i++) { 247 for (int i = 0; i < num_remotes; i++) {
217 int sent = 1; 248 if (remotes[i].send_progress) {
218 if (remote_needs_state[i]) { 249 uint8_t recv_buffer[1500];
219 remote_send_progress[i] = output_stream.next_out; 250 int bytes = recv(remotes[i].sock, recv_buffer, sizeof(recv_buffer), 0);
220 } else {
221 uint8_t buffer[1500];
222 int bytes = recv(remotes[i], buffer, sizeof(buffer), 0);
223 for (int j = 0; j < bytes; j++) 251 for (int j = 0; j < bytes; j++)
224 { 252 {
225 uint8_t cmd = buffer[j]; 253 uint8_t cmd = recv_buffer[j];
226 switch(cmd) 254 switch(cmd)
227 { 255 {
228 case CMD_GAMEPAD_DOWN: 256 case CMD_GAMEPAD_DOWN:
229 case CMD_GAMEPAD_UP: { 257 case CMD_GAMEPAD_UP: {
230 ++j; 258 ++j;
231 if (j < bytes) { 259 if (j < bytes) {
232 uint8_t button = buffer[j]; 260 uint8_t button = recv_buffer[j];
233 uint8_t pad = (button >> 5) + i + 1; 261 uint8_t pad = (button >> 5) - 1;
234 button &= 0x1F; 262 button &= 0x1F;
235 if (cmd == CMD_GAMEPAD_DOWN) { 263 if (pad < remotes[i].num_players) {
236 current_system->gamepad_down(current_system, pad, button); 264 pad = remotes[i].players[pad];
237 } else { 265 if (cmd == CMD_GAMEPAD_DOWN) {
238 current_system->gamepad_up(current_system, pad, button); 266 current_system->gamepad_down(current_system, pad, button);
267 } else {
268 current_system->gamepad_up(current_system, pad, button);
269 }
239 } 270 }
240 } else { 271 } else {
241 warning("Received incomplete command %X\n", cmd); 272 warning("Received incomplete command %X\n", cmd);
242 } 273 }
243 break; 274 break;
245 default: 276 default:
246 warning("Unrecognized remote command %X\n", cmd); 277 warning("Unrecognized remote command %X\n", cmd);
247 j = bytes; 278 j = bytes;
248 } 279 }
249 } 280 }
250 } 281 int sent = 1;
251 while (sent && output_stream.next_out > remote_send_progress[i]) 282 while (sent && output_stream.next_out > remotes[i].send_progress)
252 { 283 {
253 sent = send(remotes[i], remote_send_progress[i], output_stream.next_out - remote_send_progress[i], 0); 284 sent = send(remotes[i].sock, remotes[i].send_progress, output_stream.next_out - remotes[i].send_progress, 0);
254 if (sent >= 0) { 285 if (sent >= 0) {
255 remote_send_progress[i] += sent; 286 remotes[i].send_progress += sent;
256 } else if (!socket_error_is_wouldblock()) { 287 } else if (!socket_error_is_wouldblock()) {
257 socket_close(remotes[i]); 288 socket_close(remotes[i].sock);
258 remotes[i] = remotes[num_remotes-1]; 289 for (int j = 0; j < remotes[i].num_players; j++) {
259 remote_send_progress[i] = remote_send_progress[num_remotes-1]; 290 available_players[num_available_players++] = remotes[i].players[j];
260 remote_needs_state[i] = remote_needs_state[num_remotes-1]; 291 }
261 num_remotes--; 292 remotes[i] = remotes[num_remotes-1];
262 if (!num_remotes) { 293 num_remotes--;
263 //last remote disconnected, reset buffers/deflate 294 if (!num_remotes) {
264 fully_active = 0; 295 //last remote disconnected, reset buffers/deflate
265 deflateReset(&output_stream); 296 fully_active = 0;
266 output_stream.next_out = compressed; 297 deflateReset(&output_stream);
267 output_stream.avail_out = compressed_storage; 298 output_stream.next_out = compressed;
268 buffer.size = 0; 299 output_stream.avail_out = compressed_storage;
300 buffer.size = 0;
301 }
302 i--;
303 break;
269 } 304 }
270 i--; 305 if (remotes[i].send_progress > min_progress) {
271 break; 306 min_progress = remotes[i].send_progress;
272 } 307 }
273 if (remote_send_progress[i] > min_progress) {
274 min_progress = remote_send_progress[i];
275 } 308 }
276 } 309 }
277 } 310 }
278 if (min_progress == output_stream.next_out) { 311 if (min_progress == output_stream.next_out) {
279 output_stream.next_out = compressed; 312 output_stream.next_out = compressed;
280 output_stream.avail_out = compressed_storage; 313 output_stream.avail_out = compressed_storage;
281 for (int i = 0; i < num_remotes; i++) { 314 for (int i = 0; i < num_remotes; i++) {
282 remote_send_progress[i] = compressed; 315 if (remotes[i].send_progress) {
316 remotes[i].send_progress = compressed;
317 }
283 } 318 }
284 } 319 }
285 } 320 }
286 321
287 uint8_t wrote_since_last_flush; 322 uint8_t wrote_since_last_flush;
374 compressed_storage *= 2; 409 compressed_storage *= 2;
375 compressed = realloc(compressed, compressed_storage); 410 compressed = realloc(compressed, compressed_storage);
376 output_stream.next_out = compressed + old_storage; 411 output_stream.next_out = compressed + old_storage;
377 output_stream.avail_out = old_storage; 412 output_stream.avail_out = old_storage;
378 for (int i = 0; i < num_remotes; i++) { 413 for (int i = 0; i < num_remotes; i++) {
379 if (!remote_needs_state[i]) { 414 if (remotes[i].send_progress) {
380 remote_send_progress[i] = compressed + (remote_send_progress[i] - old_compressed); 415 remotes[i].send_progress = compressed + (remotes[i].send_progress - old_compressed);
381 } 416 }
382 } 417 }
383 } 418 }
384 int result = deflate(&output_stream, full ? Z_FINISH : Z_SYNC_FLUSH); 419 int result = deflate(&output_stream, full ? Z_FINISH : Z_SYNC_FLUSH);
385 if (result != (full ? Z_STREAM_END : Z_OK)) { 420 if (result != (full ? Z_STREAM_END : Z_OK)) {
409 state->size >> 16, state->size >> 8, state->size 444 state->size >> 16, state->size >> 8, state->size
410 }; 445 };
411 uint8_t sent_system_start = 0; 446 uint8_t sent_system_start = 0;
412 for (int i = 0; i < num_remotes; i++) 447 for (int i = 0; i < num_remotes; i++)
413 { 448 {
414 if (remote_needs_state[i]) { 449 if (!remotes[i].send_progress) {
415 if (send_all(remotes[i], system_start, system_start_size, 0) == system_start_size) { 450 if (send_all(remotes[i].sock, system_start, system_start_size, 0) == system_start_size) {
416 sent_system_start = 1; 451 sent_system_start = 1;
417 } else { 452 } else {
418 socket_close(remotes[i]); 453 socket_close(remotes[i].sock);
419 remotes[i] = remotes[num_remotes-1]; 454 remotes[i] = remotes[num_remotes-1];
420 remote_send_progress[i] = remote_send_progress[num_remotes-1];
421 remote_needs_state[i] = remote_needs_state[num_remotes-1];
422 num_remotes--; 455 num_remotes--;
423 i--; 456 i--;
424 } 457 }
425 } 458 }
426 } 459 }
436 save_buffer8(&buffer, state->data, state->size); 469 save_buffer8(&buffer, state->data, state->size);
437 size_t old_compressed_size = output_stream.next_out - compressed; 470 size_t old_compressed_size = output_stream.next_out - compressed;
438 deflate_flush(1); 471 deflate_flush(1);
439 size_t state_size = output_stream.next_out - compressed - old_compressed_size; 472 size_t state_size = output_stream.next_out - compressed - old_compressed_size;
440 for (int i = 0; i < num_remotes; i++) { 473 for (int i = 0; i < num_remotes; i++) {
441 if (remote_needs_state[i]) { 474 if (!remotes[i].send_progress) {
442 if (send_all(remotes[i], compressed + old_compressed_size, state_size, 0) == state_size) { 475 if (send_all(remotes[i].sock, compressed + old_compressed_size, state_size, 0) == state_size) {
443 remote_send_progress[i] = compressed + old_compressed_size; 476 remotes[i].send_progress = compressed + old_compressed_size;
444 remote_needs_state[i] = 0; 477 socket_blocking(remotes[i].sock, 0);
445 socket_blocking(remotes[i], 0);
446 int flag = 1; 478 int flag = 1;
447 setsockopt(remotes[i], IPPROTO_TCP, TCP_NODELAY, (const char *)&flag, sizeof(flag)); 479 setsockopt(remotes[i].sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&flag, sizeof(flag));
448 fully_active = 1; 480 fully_active = 1;
449 } else { 481 } else {
450 socket_close(remotes[i]); 482 socket_close(remotes[i].sock);
451 remotes[i] = remotes[num_remotes-1]; 483 remotes[i] = remotes[num_remotes-1];
452 remote_send_progress[i] = remote_send_progress[num_remotes-1];
453 remote_needs_state[i] = remote_needs_state[num_remotes-1];
454 num_remotes--; 484 num_remotes--;
455 i--; 485 i--;
456 } 486 }
457 } 487 }
458 } 488 }