1.1 --- a/src/game.c Wed Apr 09 11:12:04 2014 +0200 1.2 +++ b/src/game.c Wed Apr 09 12:07:47 2014 +0200 1.3 @@ -33,6 +33,7 @@ 1.4 #include <ncurses.h> 1.5 #include <string.h> 1.6 #include <inttypes.h> 1.7 +#include <sys/select.h> 1.8 1.9 static const uint8_t boardx = 10, boardy = 10; 1.10 static int inputy = 21; /* should be overridden on game startup */ 1.11 @@ -315,6 +316,13 @@ 1.12 1.13 static int recvmove(GameState *gamestate, GameInfo *gameinfo, int opponent) { 1.14 1.15 + if (net_setnonblocking(opponent, 1)) { 1.16 + printw("Cannot setup nonblocking IO on network socket"); 1.17 + cbreak(); getch(); 1.18 + exit(EXIT_FAILURE); 1.19 + } 1.20 + 1.21 + struct timeval timeout; 1.22 while (1) { 1.23 timecontrol(gamestate, gameinfo); 1.24 1.25 @@ -323,52 +331,66 @@ 1.26 clrtoeol(); 1.27 refresh(); 1.28 1.29 - // TODO: nonblocking 1.30 - uint32_t code = net_recieve_code(opponent); 1.31 + fd_set readfds; 1.32 1.33 - Move move; 1.34 - switch (code) { 1.35 - case NETCODE_TIMEOVER: 1.36 - printw("\rYour opponent's time ran out - you win!"); 1.37 - clrtoeol(); 1.38 - return 1; 1.39 - case NETCODE_SURRENDER: 1.40 - printw("\rYour opponent surrendered!"); 1.41 - clrtoeol(); 1.42 - return 1; 1.43 - case NETCODE_REMIS: 1.44 - if (prompt_yesno( 1.45 - "\rYour opponent offers remis - do you accept")) { 1.46 - printw("\rRemis accepted!"); 1.47 + FD_ZERO(&readfds); 1.48 + FD_SET(opponent, &readfds); 1.49 + timeout.tv_sec = 0; 1.50 + timeout.tv_usec = 1e5; 1.51 + 1.52 + int result = select(opponent+1, &readfds, NULL, NULL, &timeout); 1.53 + if (result == -1) { 1.54 + printw("\rCannot perform asynchronous network IO"); 1.55 + cbreak(); getch(); 1.56 + exit(EXIT_FAILURE); 1.57 + } 1.58 + if (result > 0) { 1.59 + uint32_t code = net_recieve_code(opponent); 1.60 + 1.61 + Move move; 1.62 + switch (code) { 1.63 + case NETCODE_TIMEOVER: 1.64 + printw("\rYour opponent's time ran out - you win!"); 1.65 clrtoeol(); 1.66 - net_send_code(opponent, NETCODE_ACCEPT); 1.67 return 1; 1.68 - } else { 1.69 - net_send_code(opponent, NETCODE_DECLINE); 1.70 - } 1.71 - break; 1.72 - case NETCODE_MOVE: 1.73 - net_recieve_data(opponent, &move, sizeof(Move)); 1.74 - if (validate_move(gamestate, &move)) { 1.75 - apply_move(gamestate, &move); 1.76 - if (move.check) { 1.77 - net_send_code(opponent, NETCODE_CHECK); 1.78 - } else if (gamestate->checkmate) { 1.79 - net_send_code(opponent, NETCODE_CHECKMATE); 1.80 - printw("\rCheckmate!"); 1.81 + case NETCODE_SURRENDER: 1.82 + printw("\rYour opponent surrendered!"); 1.83 + clrtoeol(); 1.84 + return 1; 1.85 + case NETCODE_REMIS: 1.86 + if (prompt_yesno( 1.87 + "\rYour opponent offers remis - do you accept")) { 1.88 + printw("\rRemis accepted!"); 1.89 clrtoeol(); 1.90 - return 1; 1.91 - } else if (gamestate->stalemate) { 1.92 - net_send_code(opponent, NETCODE_STALEMATE); 1.93 - printw("\rStalemate!"); 1.94 - clrtoeol(); 1.95 + net_send_code(opponent, NETCODE_ACCEPT); 1.96 return 1; 1.97 } else { 1.98 - net_send_code(opponent, NETCODE_ACCEPT); 1.99 + net_send_code(opponent, NETCODE_DECLINE); 1.100 } 1.101 - return 0; 1.102 - } else { 1.103 - net_send_code(opponent, NETCODE_DECLINE); 1.104 + break; 1.105 + case NETCODE_MOVE: 1.106 + net_recieve_data(opponent, &move, sizeof(Move)); 1.107 + if (validate_move(gamestate, &move)) { 1.108 + apply_move(gamestate, &move); 1.109 + if (move.check) { 1.110 + net_send_code(opponent, NETCODE_CHECK); 1.111 + } else if (gamestate->checkmate) { 1.112 + net_send_code(opponent, NETCODE_CHECKMATE); 1.113 + printw("\rCheckmate!"); 1.114 + clrtoeol(); 1.115 + return 1; 1.116 + } else if (gamestate->stalemate) { 1.117 + net_send_code(opponent, NETCODE_STALEMATE); 1.118 + printw("\rStalemate!"); 1.119 + clrtoeol(); 1.120 + return 1; 1.121 + } else { 1.122 + net_send_code(opponent, NETCODE_ACCEPT); 1.123 + } 1.124 + return 0; 1.125 + } else { 1.126 + net_send_code(opponent, NETCODE_DECLINE); 1.127 + } 1.128 } 1.129 } 1.130 }