From 3ded5531b326c7de74b5689ace44654f2eff2f4a Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Mon, 3 Apr 2006 10:33:20 -0400 Subject: [PATCH] Fix engine status. Re-added the 'g'o command. Fix restoring of windows after a SIGCONT. Changed engine command 'c' to '|'. --- src/cboard.c | 148 +++++++++++++++++++++++++++++++++-------------------------- src/cboard.h | 3 +- src/engine.c | 50 +++++++++++++------- src/engine.h | 13 ++---- src/move.c | 6 +++ src/pgn.c | 2 +- 6 files changed, 129 insertions(+), 93 deletions(-) diff --git a/src/cboard.c b/src/cboard.c index 5a33c5b..e71faaa 100644 --- a/src/cboard.c +++ b/src/cboard.c @@ -104,7 +104,7 @@ static char *str_etc(const char *str, int maxlen, int rev) } /* FIXME castling */ -static void update_cursor(GAME g, int idx) +void update_cursor(GAME g, int idx) { char *p; int len; @@ -1754,23 +1754,27 @@ void update_status_window(GAME g) (d && TEST_FLAG(d->flags, CF_ENGINE_LOOP)) ? " (loop)" : ""); mvwprintw(statusw, 4, 1, "%-*s", w, buf); - switch (status.engine) { - case ENGINE_THINKING: - engine = ENGINE_THINKING_STR; - break; - case ENGINE_READY: - engine = ENGINE_READY_STR; - break; - case ENGINE_INITIALIZING: - engine = ENGINE_INITIALIZING_STR; - break; - case ENGINE_OFFLINE: - engine = ENGINE_OFFLINE_STR; - break; - default: - engine = UNKNOWN; - break; + if (d) { + switch (d->status) { + case ENGINE_THINKING: + engine = ENGINE_THINKING_STR; + break; + case ENGINE_READY: + engine = ENGINE_READY_STR; + break; + case ENGINE_INITIALIZING: + engine = ENGINE_INITIALIZING_STR; + break; + case ENGINE_OFFLINE: + engine = ENGINE_OFFLINE_STR; + break; + default: + engine = UNKNOWN; + break; + } } + else + engine = ENGINE_OFFLINE_STR; mvwprintw(statusw, 5, 1, "%*s %-*s", 7, STATUS_ENGINE_STR, w, " "); wattron(statusw, CP_STATUS_ENGINE); @@ -2297,20 +2301,25 @@ static void playmode_keys(int c) TOGGLE_FLAG(d->flags, CF_ENGINE_LOOP); update_all(game[gindex]); break; - case 'c': - if (status.engine == ENGINE_THINKING || status.engine == - ENGINE_OFFLINE) + case '|': + if (!d) break; + if (d->status == ENGINE_OFFLINE) + break; + + x = d->status; + if ((tmp = get_input_str_clear(ENGINE_CMD_TITLE, NULL)) != NULL) send_to_engine(&game[gindex], "%s\n", tmp); + d->status = x; break; case '\015': case '\n': pushkey = keycount = 0; update_status_notify(game[gindex], NULL); - if (status.engine == ENGINE_THINKING) { + if (!noengine && (!d || d->status == ENGINE_THINKING)) { beep(); break; } @@ -2351,7 +2360,7 @@ static void playmode_keys(int c) if (!editmode) wtimeout(boardw, 70); - if (sp.icon || (!editmode && status.engine == ENGINE_THINKING)) { + if (sp.icon || (!editmode && d && d->status == ENGINE_THINKING)) { beep(); break; } @@ -2411,6 +2420,12 @@ static void playmode_keys(int c) case 'p': paused = (paused) ? 0 : 1; break; + case 'g': + if (!d || d->status == ENGINE_OFFLINE) + start_chess_engine(&game[gindex]); + + send_to_engine(&game[gindex], "go\n"); + break; default: break; } @@ -2620,8 +2635,8 @@ static int globalkeys(int c) switch (c) { case 'h': if (game[gindex].mode != MODE_HISTORY) { - if (!history_total(game[gindex].hp) || status.engine == - ENGINE_THINKING) + if (!history_total(game[gindex].hp) || + (d && d->status == ENGINE_THINKING)) return 1; game[gindex].mode = MODE_HISTORY; @@ -2649,7 +2664,7 @@ static int globalkeys(int c) } if (!noengine && (!d || d->status == ENGINE_OFFLINE)) { - if (start_chess_engine() < 0) + if (start_chess_engine(&game[gindex]) < 0) return 1; pushkey = 'h'; @@ -2659,7 +2674,6 @@ static int globalkeys(int c) pushkey = 0; oldhistorytotal = history_total(game[gindex].hp); game[gindex].mode = MODE_PLAY; - status.engine = ENGINE_READY; update_all(game[gindex]); return 1; case '>': @@ -2972,7 +2986,6 @@ static int globalkeys(int c) } send_to_engine(&game[gindex], "\nnew\n"); - status.engine = ENGINE_READY; update_status_notify(game[gindex], NULL); update_all(game[gindex]); update_tag_window(game[gindex].tag); @@ -3268,20 +3281,52 @@ void usage(const char *pn, int ret) exit(ret); } +static void cleanup_all_games() +{ + int i; + + for (i = 0; i < gtotal; i++) { + struct user_data_s *d; + + if (game[i].data) { + stop_engine(&game[i]); + d = game[i].data; + + if (d->fd[ICS_FD] > 2) + close(d->fd[ICS_FD]); + + free(game[i].data); + } + } +} + +void cleanup_all() +{ + cleanup_all_games(); + pgn_free_all(); + del_panel(boardp); + del_panel(historyp); + del_panel(statusp); + del_panel(tagp); + delwin(boardw); + delwin(historyw); + delwin(statusw); + delwin(tagw); + endwin(); +} + void catch_signal(int which) { switch (which) { case SIGINT: - stop_engine(); - endwin(); - exit(EXIT_FAILURE); - break; case SIGPIPE: - if (quit) + if (which == SIGPIPE && quit) break; - cmessage(NULL, ANYKEY, "%s", E_BROKEN_PIPE); - endwin(); + if (which == SIGPIPE) + cmessage(NULL, ANYKEY, "%s", E_BROKEN_PIPE); + + cleanup_all(); exit(EXIT_FAILURE); break; case SIGSTOP: @@ -3290,6 +3335,9 @@ void catch_signal(int which) case SIGCONT: resetty(); keypad(boardw, TRUE); + curs_set(0); + cbreak(); + noecho(); break; default: break; @@ -3302,25 +3350,6 @@ static void set_defaults() set_config_defaults(); } -static void cleanup_all_games() -{ - int i; - - for (i = 0; i < gtotal; i++) { - struct user_data_s *d; - - if (game[i].data) { - stop_engine(&game[i]); - d = game[i].data; - - if (d->fd[ICS_FD] > 2) - close(d->fd[ICS_FD]); - - free(game[i].data); - } - } -} - int main(int argc, char *argv[]) { int opt; @@ -3481,18 +3510,7 @@ int main(int argc, char *argv[]) cbreak(); noecho(); draw_window_decor(); - game_loop(); - endwin(); - cleanup_all_games(); - pgn_free_all(); - del_panel(boardp); - del_panel(historyp); - del_panel(statusp); - del_panel(tagp); - delwin(boardw); - delwin(historyw); - delwin(statusw); - delwin(tagw); + cleanup_all(); exit(EXIT_SUCCESS); } diff --git a/src/cboard.h b/src/cboard.h index 3093077..fdc9ecc 100644 --- a/src/cboard.h +++ b/src/cboard.h @@ -150,7 +150,7 @@ const char *playhelp[] = { " w - switch playing side", " u - undo previous move *", " g - force engine to make the next move", - " c - send a command to the chess engine", + " | - send a command to the chess engine", " o - toggle engine looping", NULL }; @@ -235,7 +235,6 @@ struct nag_s { // Status window. struct { - char engine; // Chess engine status: ENGINE_[READY/OFFLINE]. char *notify; // The status window notification line buffer. } status; diff --git a/src/engine.c b/src/engine.c index b0686e2..c299f97 100644 --- a/src/engine.c +++ b/src/engine.c @@ -59,6 +59,11 @@ void send_to_engine(GAME *g, const char *format, ...) if (!g->data || d->status == ENGINE_OFFLINE) return; + d->status = ENGINE_THINKING; + update_status_window(*g); + update_panels(); + doupdate(); + va_start(ap, format); #ifdef HAVE_VASPRINTF len = vasprintf(&line, format, ap); @@ -197,11 +202,11 @@ static char **parseargs(char *str) } /* Is this dangerous if pty permissions are wrong? */ -pid_t init_chess_engine(GAME *g, char **args) +static pid_t init_chess_engine(GAME *g, char **args) { pid_t pid; int from[2], to[2]; - struct user_data_s *d = NULL; + struct user_data_s *d = g->data; #ifndef UNIX98 char pty[FILENAME_MAX]; @@ -261,16 +266,11 @@ pid_t init_chess_engine(GAME *g, char **args) close(to[0]); close(from[1]); - if (!g->data) - d = Calloc(1, sizeof(struct user_data_s)); - d->fd[ENGINE_IN_FD] = from[0]; d->fd[ENGINE_OUT_FD] = to[1]; fcntl(d->fd[ENGINE_IN_FD], F_SETFL, O_NONBLOCK | O_DIRECT); fcntl(d->fd[ENGINE_OUT_FD], F_SETFL, O_NONBLOCK | O_DIRECT); d->pid = pid; - d->status = ENGINE_READY; - g->data = d; return 0; } @@ -278,11 +278,10 @@ void stop_engine(GAME *g) { struct user_data_s *d = g->data; - if (!g->data || d->status == ENGINE_OFFLINE) + if (!d || d->status == ENGINE_OFFLINE) return; send_to_engine(g, "quit\n"); - d = g->data; if (kill(d->pid, 0) != -1) kill(d->pid, SIGTERM); @@ -296,20 +295,34 @@ int start_chess_engine(GAME *g) char **args; int i; int ret = 1; + struct user_data_s *d = NULL; args = parseargs(config.engine_cmd); + if (!g->data) { + d = Calloc(1, sizeof(struct user_data_s)); + g->data = d; + } + + d->status = ENGINE_INITIALIZING; + update_status_window(*g); + update_panels(); + doupdate(); + switch (init_chess_engine(g, args)) { case -1: /* Pty allocation. */ message(ERROR, ANYKEY, "Could not allocate PTY"); + d->status = ENGINE_OFFLINE; break; case -2: /* Could not execute engine. */ message(ERROR, ANYKEY, "%s: %s", args[0], strerror(errno)); + d->status = ENGINE_OFFLINE; break; default: ret = 0; + d->status = ENGINE_READY; break; } @@ -361,7 +374,7 @@ void parse_gnuchess_line(GAME *g, char *str) if (pgn_validate_move(g, g->b, p)) { invalid_move(0, p); - return; + RETURN(d); } if (history_total(g->hp) == 0 && g->side == BLACK) @@ -374,18 +387,21 @@ void parse_gnuchess_line(GAME *g, char *str) if (TEST_FLAG(g->flags, GF_GAMEOVER)) { //history_update_board(g, g.htotal); FIXME - RETURN; + RETURN(d); } - if (d && TEST_FLAG(d->flags, CF_ENGINE_LOOP)) + if (d && TEST_FLAG(d->flags, CF_ENGINE_LOOP)) { send_to_engine(g, "go\n"); + update_cursor(*g, g->hindex); + return; + } - RETURN; + RETURN(d); } if (TEST_FLAG(g->flags, GF_GAMEOVER)) { //history_update_board(g); FIXME - RETURN; + RETURN(d); } /* Miscellaneous one-liners. */ @@ -409,16 +425,16 @@ void parse_gnuchess_line(GAME *g, char *str) /* 'switch' command. */ if (strncmp(str, "White to move", 13) == 0) { g->side = g->turn = WHITE; - RETURN; + RETURN(d); } else if (strncmp(str, "Black to move", 13) == 0) { g->side = g->turn = BLACK; - RETURN; + RETURN(d); } /* Bad engine command or move. */ if (strncmp(str, "Illegal move: ", 14) == 0) { - RETURN; + RETURN(d); } } diff --git a/src/engine.h b/src/engine.h index 97c3158..6cdd4d1 100644 --- a/src/engine.h +++ b/src/engine.h @@ -19,19 +19,16 @@ #ifndef ENGINE_H #define ENGINE_H -#if 0 -#define RETURN status.engine = ENGINE_READY; \ - return -#endif -#define RETURN return +#define RETURN(d) d->status = ENGINE_READY;\ + return // This is a failsafe when resuming a game. int oldhistorytotal; void send_to_engine(GAME *g, const char *format, ...); -int start_chess_engine(); -void set_engine_defaults(); -void stop_engine(); +int start_chess_engine(GAME *); +void set_engine_defaults(char **); +void stop_engine(GAME *); int save_pgn(const char *filename, int isfifo, int saveindex); #endif diff --git a/src/move.c b/src/move.c index 6b948df..3783c9a 100644 --- a/src/move.c +++ b/src/move.c @@ -1434,8 +1434,14 @@ again: if (val_piece_side(g->turn, piece)) return 2; + /* FIXME + * this doesn't belong in the library. This should update a capture + * count or something. + */ + /* if (!validate) update_status_notify(*g, random_agony(*g)); + */ } if (!validate) { diff --git a/src/pgn.c b/src/pgn.c index 648b6af..e3a3e13 100644 --- a/src/pgn.c +++ b/src/pgn.c @@ -246,9 +246,9 @@ int history_add(GAME *g, const char *m) if ((g->hp[t] = calloc(1, sizeof(HISTORY))) == NULL) return 1; - g->hindex = t; g->hp[t++]->move = strdup(m); g->hp[t] = NULL; + g->hindex = history_total(g->hp); return 0; } -- 2.11.4.GIT