diff -r 866025982aa9 -r c4d4b8a8f902 src/game.c --- a/src/game.c Wed Apr 09 11:12:04 2014 +0200 +++ b/src/game.c Wed Apr 09 12:07:47 2014 +0200 @@ -33,6 +33,7 @@ #include #include #include +#include static const uint8_t boardx = 10, boardy = 10; static int inputy = 21; /* should be overridden on game startup */ @@ -315,6 +316,13 @@ static int recvmove(GameState *gamestate, GameInfo *gameinfo, int opponent) { + if (net_setnonblocking(opponent, 1)) { + printw("Cannot setup nonblocking IO on network socket"); + cbreak(); getch(); + exit(EXIT_FAILURE); + } + + struct timeval timeout; while (1) { timecontrol(gamestate, gameinfo); @@ -323,52 +331,66 @@ clrtoeol(); refresh(); - // TODO: nonblocking - uint32_t code = net_recieve_code(opponent); + fd_set readfds; - Move move; - switch (code) { - case NETCODE_TIMEOVER: - printw("\rYour opponent's time ran out - you win!"); - clrtoeol(); - return 1; - case NETCODE_SURRENDER: - printw("\rYour opponent surrendered!"); - clrtoeol(); - return 1; - case NETCODE_REMIS: - if (prompt_yesno( - "\rYour opponent offers remis - do you accept")) { - printw("\rRemis accepted!"); + FD_ZERO(&readfds); + FD_SET(opponent, &readfds); + timeout.tv_sec = 0; + timeout.tv_usec = 1e5; + + int result = select(opponent+1, &readfds, NULL, NULL, &timeout); + if (result == -1) { + printw("\rCannot perform asynchronous network IO"); + cbreak(); getch(); + exit(EXIT_FAILURE); + } + if (result > 0) { + uint32_t code = net_recieve_code(opponent); + + Move move; + switch (code) { + case NETCODE_TIMEOVER: + printw("\rYour opponent's time ran out - you win!"); clrtoeol(); - net_send_code(opponent, NETCODE_ACCEPT); return 1; - } else { - net_send_code(opponent, NETCODE_DECLINE); - } - break; - case NETCODE_MOVE: - net_recieve_data(opponent, &move, sizeof(Move)); - if (validate_move(gamestate, &move)) { - apply_move(gamestate, &move); - if (move.check) { - net_send_code(opponent, NETCODE_CHECK); - } else if (gamestate->checkmate) { - net_send_code(opponent, NETCODE_CHECKMATE); - printw("\rCheckmate!"); + case NETCODE_SURRENDER: + printw("\rYour opponent surrendered!"); + clrtoeol(); + return 1; + case NETCODE_REMIS: + if (prompt_yesno( + "\rYour opponent offers remis - do you accept")) { + printw("\rRemis accepted!"); clrtoeol(); - return 1; - } else if (gamestate->stalemate) { - net_send_code(opponent, NETCODE_STALEMATE); - printw("\rStalemate!"); - clrtoeol(); + net_send_code(opponent, NETCODE_ACCEPT); return 1; } else { - net_send_code(opponent, NETCODE_ACCEPT); + net_send_code(opponent, NETCODE_DECLINE); } - return 0; - } else { - net_send_code(opponent, NETCODE_DECLINE); + break; + case NETCODE_MOVE: + net_recieve_data(opponent, &move, sizeof(Move)); + if (validate_move(gamestate, &move)) { + apply_move(gamestate, &move); + if (move.check) { + net_send_code(opponent, NETCODE_CHECK); + } else if (gamestate->checkmate) { + net_send_code(opponent, NETCODE_CHECKMATE); + printw("\rCheckmate!"); + clrtoeol(); + return 1; + } else if (gamestate->stalemate) { + net_send_code(opponent, NETCODE_STALEMATE); + printw("\rStalemate!"); + clrtoeol(); + return 1; + } else { + net_send_code(opponent, NETCODE_ACCEPT); + } + return 0; + } else { + net_send_code(opponent, NETCODE_DECLINE); + } } } }