Tue, 18 Sep 2018 15:02:08 +0200
adds unicode support
conf.mk | file | annotate | diff | comparison | revisions | |
src/chess/rules.c | file | annotate | diff | comparison | revisions | |
src/chess/rules.h | file | annotate | diff | comparison | revisions | |
src/game.c | file | annotate | diff | comparison | revisions | |
src/main.c | file | annotate | diff | comparison | revisions | |
src/terminal-chess.h | file | annotate | diff | comparison | revisions |
1.1 --- a/conf.mk Wed Aug 29 17:31:36 2018 +0200 1.2 +++ b/conf.mk Tue Sep 18 15:02:08 2018 +0200 1.3 @@ -32,10 +32,10 @@ 1.4 1.5 BIN = terminal-chess 1.6 CC = gcc 1.7 -CFLAGS = -O2 -std=gnu99 `pkg-config --cflags ncurses` 1.8 -CFLAGS_D = -g -std=gnu99 -Wall -pedantic `pkg-config --cflags ncurses` 1.9 +CFLAGS = -O2 -std=gnu99 `pkg-config --cflags ncursesw` 1.10 +CFLAGS_D = -g -std=gnu99 -Wall -pedantic `pkg-config --cflags ncursesw` 1.11 LD = gcc 1.12 -LDFLAGS = `pkg-config --libs ncurses` 1.13 +LDFLAGS = `pkg-config --libs ncursesw` 1.14 ARFLAGS = -r 1.15 MKDIRFLAGS = -p 1.16 RMFLAGS = -f -R
2.1 --- a/src/chess/rules.c Wed Aug 29 17:31:36 2018 +0200 2.2 +++ b/src/chess/rules.c Tue Sep 18 15:02:08 2018 +0200 2.3 @@ -204,6 +204,18 @@ 2.4 } 2.5 } 2.6 2.7 +unsigned char* getpieceunicode(uint8_t piece) { 2.8 + switch (piece & PIECE_MASK) { 2.9 + case PAWN: return "\u265f"; 2.10 + case ROOK: return "\u265c"; 2.11 + case KNIGHT: return "\u265e"; 2.12 + case BISHOP: return "\u265d"; 2.13 + case QUEEN: return "\u265b"; 2.14 + case KING: return "\u265a"; 2.15 + default: return ""; 2.16 + } 2.17 +} 2.18 + 2.19 uint8_t getpiece(char c) { 2.20 switch (c) { 2.21 case 'R': return ROOK;
3.1 --- a/src/chess/rules.h Wed Aug 29 17:31:36 2018 +0200 3.2 +++ b/src/chess/rules.h Tue Sep 18 15:02:08 2018 +0200 3.3 @@ -174,12 +174,23 @@ 3.4 * 3.5 * Does not work for pawns, scince they don't have a character. 3.6 * 3.7 - * @param piece one of ROOK, KNIGHT, BISHOP, QUEEN, KING 3.8 + * @param piece may have color or additional flags 3.9 * @return character value for the specified piece 3.10 */ 3.11 char getpiecechr(uint8_t piece); 3.12 3.13 /** 3.14 + * Maps a piece to a unicode character sequence. 3.15 + * 3.16 + * The returned unicode is for black pieces. 3.17 + * You may colorize the output by setting the terminal foreground color. 3.18 + * 3.19 + * @param piece the piece to dispaly 3.20 + * @return unicode character sequence for the specified piece 3.21 + */ 3.22 +unsigned char* getpieceunicode(uint8_t piece); 3.23 + 3.24 +/** 3.25 * Checks, if a specified field is covered by a piece of a certain color. 3.26 * 3.27 * The out-parameters may both be NULL, but if any of them is set, the other
4.1 --- a/src/game.c Wed Aug 29 17:31:36 2018 +0200 4.2 +++ b/src/game.c Tue Sep 18 15:02:08 2018 +0200 4.3 @@ -71,7 +71,9 @@ 4.4 return 0; 4.5 } 4.6 4.7 -static void draw_board(GameState *gamestate, uint8_t perspective) { 4.8 +static void draw_board(GameState *gamestate, 4.9 + uint8_t perspective, 4.10 + _Bool unicode) { 4.11 char fen[90]; 4.12 compute_fen(fen, gamestate); 4.13 mvaddstr(0, 0, fen); 4.14 @@ -80,11 +82,18 @@ 4.15 for (uint8_t x = 0 ; x < 8 ; x++) { 4.16 uint8_t col = gamestate->board[y][x] & COLOR_MASK; 4.17 uint8_t piece = gamestate->board[y][x] & PIECE_MASK; 4.18 - char piecec; 4.19 + unsigned char piecestr[5]; 4.20 if (piece) { 4.21 - piecec = piece == PAWN ? 'P' : getpiecechr(piece); 4.22 + if (unicode) { 4.23 + unsigned char* uc = getpieceunicode(piece); 4.24 + strncpy(piecestr, uc, 5); 4.25 + } else { 4.26 + piecestr[0] = piece == PAWN ? 'P' : getpiecechr(piece); 4.27 + piecestr[1] = '\0'; 4.28 + } 4.29 } else { 4.30 - piecec = ' '; 4.31 + piecestr[0] = ' '; 4.32 + piecestr[1] = '\0'; 4.33 } 4.34 4.35 _Bool boardblack = (y&1)==(x&1); 4.36 @@ -97,9 +106,7 @@ 4.37 4.38 int cy = perspective == WHITE ? boardy-y : boardy-7+y; 4.39 int cx = perspective == WHITE ? boardx+x*3 : boardx+21-x*3; 4.40 - mvaddch(cy, cx, ' '); 4.41 - mvaddch(cy, cx+1, piecec); 4.42 - mvaddch(cy, cx+2, ' '); 4.43 + mvprintw(cy, cx, " %s ", piecestr); 4.44 } 4.45 } 4.46 4.47 @@ -460,9 +467,11 @@ 4.48 } 4.49 } 4.50 4.51 -static void post_game(GameState *gamestate, GameInfo *gameinfo) { 4.52 +static void post_game(Settings* settings, GameState *gamestate) { 4.53 + GameInfo *gameinfo = &(settings->gameinfo); 4.54 + 4.55 move(0,0); 4.56 - draw_board(gamestate, WHITE); 4.57 + draw_board(gamestate, WHITE, settings->unicode); 4.58 4.59 // TODO: network connection is still open here - think about it! 4.60 4.61 @@ -520,13 +529,13 @@ 4.62 _Bool running; 4.63 do { 4.64 clear(); 4.65 - draw_board(&gamestate, curcol); 4.66 + draw_board(&gamestate, curcol, settings->unicode); 4.67 running = !domove_singlemachine(&gamestate, 4.68 &(settings->gameinfo), curcol); 4.69 curcol = opponent_color(curcol); 4.70 } while (running); 4.71 4.72 - post_game(&gamestate, &(settings->gameinfo)); 4.73 + post_game(settings, &gamestate); 4.74 } 4.75 4.76 void game_continue(Settings *settings, int opponent, GameState *gamestate) { 4.77 @@ -541,7 +550,7 @@ 4.78 _Bool running; 4.79 do { 4.80 clear(); 4.81 - draw_board(gamestate, mycolor); 4.82 + draw_board(gamestate, mycolor, settings->unicode); 4.83 if (myturn) { 4.84 running = !sendmove(gamestate, &(settings->gameinfo), 4.85 opponent, mycolor); 4.86 @@ -551,7 +560,7 @@ 4.87 myturn ^= TRUE; 4.88 } while (running); 4.89 4.90 - post_game(gamestate, &(settings->gameinfo)); 4.91 + post_game(settings, gamestate); 4.92 } 4.93 4.94 void game_start(Settings *settings, int opponent) {
5.1 --- a/src/main.c Wed Aug 29 17:31:36 2018 +0200 5.2 +++ b/src/main.c Tue Sep 18 15:02:08 2018 +0200 5.3 @@ -34,6 +34,7 @@ 5.4 #include <string.h> 5.5 #include <time.h> 5.6 #include <getopt.h> 5.7 +#include <locale.h> 5.8 5.9 int get_settings(int argc, char **argv, Settings *settings) { 5.10 char *valid; 5.11 @@ -41,7 +42,7 @@ 5.12 uint8_t timeunit = 60; 5.13 size_t len; 5.14 5.15 - for (int opt ; (opt = getopt(argc, argv, "a:bc:hp:rsS:t:v")) != -1 ;) { 5.16 + for (int opt ; (opt = getopt(argc, argv, "a:bc:hp:rsS:t:Uv")) != -1 ;) { 5.17 switch (opt) { 5.18 case 'c': 5.19 settings->continuepgn = optarg; 5.20 @@ -58,6 +59,9 @@ 5.21 case 'S': 5.22 settings->analyzepgn = optarg; 5.23 break; 5.24 + case 'U': 5.25 + settings->unicode = 0; 5.26 + break; 5.27 case 't': 5.28 case 'a': 5.29 len = strlen(optarg); 5.30 @@ -114,6 +118,7 @@ 5.31 " -r Distribute color randomly\n" 5.32 " -s Single machine mode\n" 5.33 " -t <time> Specifies time limit (default: no limit)\n" 5.34 +" -U Disables unicode pieces\n" 5.35 "\nNotes\n" 5.36 "The time unit for -a is seconds and for -t minutes by default. To " 5.37 "specify\nseconds for the -t option, use the s suffix.\n" 5.38 @@ -151,6 +156,7 @@ 5.39 memset(&settings, 0, sizeof(Settings)); 5.40 settings.gameinfo.servercolor = WHITE; 5.41 settings.port = "27015"; 5.42 + settings.unicode = !!setlocale(LC_CTYPE, "C.UTF-8"); 5.43 return settings; 5.44 } 5.45
6.1 --- a/src/terminal-chess.h Wed Aug 29 17:31:36 2018 +0200 6.2 +++ b/src/terminal-chess.h Tue Sep 18 15:02:08 2018 +0200 6.3 @@ -36,7 +36,7 @@ 6.4 #ifndef TERMINAL_CHESS_H 6.5 #define TERMINAL_CHESS_H 6.6 6.7 -#define PROGRAM_VERSION "0.9-r68" 6.8 +#define PROGRAM_VERSION "0.9-r69" 6.9 6.10 #ifdef __cplusplus 6.11 extern "C" { 6.12 @@ -49,6 +49,7 @@ 6.13 char* continuepgn; 6.14 char* analyzepgn; 6.15 _Bool singlemachine; 6.16 + _Bool unicode; 6.17 } Settings; 6.18 6.19 #define is_server(settings) !((settings)->serverhost)