/****************************************************************************
- * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. *
+ * Copyright 2019-2020,2021 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
*****************************************************************************/
/*
- * Compile this with the command `cc -O blue.c -lcurses -o blue'. For best
- * results, use the ncurses(3) library. On non-Intel machines, SVr4 curses is
- * just as good.
- *
- * $Id: blue.c,v 1.32 2009/10/10 16:16:46 tom Exp $
+ * $Id: blue.c,v 1.54 2021/03/20 16:06:15 tom Exp $
*/
#include <test.priv.h>
#include <time.h>
+#if HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+
#define NOCARD (-1)
#define ACE 0
#define BLACK_ON_WHITE 2
#define BLUE_ON_WHITE 3
-static RETSIGTYPE die(int onsig) GCC_NORETURN;
+static GCC_NORETURN void die(int onsig);
static int deck_size = PACK_SIZE; /* initial deck */
static int deck[PACK_SIZE];
{' ', 'K'}
};
-/* Please note, that this is a bad example.
- Color values should not be or'ed in. This
- only works, because the characters used here
- are plain and have no color attribute themselves. */
-#ifdef COLOR_PAIR
-#define OR_COLORS(value,pair) ((value) | COLOR_PAIR(pair))
-#else
-#define OR_COLORS(value,pair) (value)
-#endif
+static int letters[4] =
+{
+ 'h', /* hearts */
+ 's', /* spades */
+ 'd', /* diamonds */
+ 'c', /* clubs */
+};
-#define PC_COLORS(value,pair) (OR_COLORS(value,pair) | A_ALTCHARSET)
+#if HAVE_LANGINFO_CODESET
-static chtype letters[4] =
+#if HAVE_TIGETSTR
+static int glyphs[] =
{
- OR_COLORS('h', RED_ON_WHITE), /* hearts */
- OR_COLORS('s', BLACK_ON_WHITE), /* spades */
- OR_COLORS('d', RED_ON_WHITE), /* diamonds */
- OR_COLORS('c', BLACK_ON_WHITE), /* clubs */
+ '\003', /* hearts */
+ '\006', /* spades */
+ '\004', /* diamonds */
+ '\005', /* clubs */
};
+#endif
-#if defined(__i386__) && defined(A_ALTCHARSET) && HAVE_TIGETSTR
-static chtype glyphs[] =
+#if USE_WIDEC_SUPPORT
+static int uglyphs[] =
{
- PC_COLORS('\003', RED_ON_WHITE), /* hearts */
- PC_COLORS('\006', BLACK_ON_WHITE), /* spades */
- PC_COLORS('\004', RED_ON_WHITE), /* diamonds */
- PC_COLORS('\005', BLACK_ON_WHITE), /* clubs */
+ 0x2665, /* hearts */
+ 0x2660, /* spades */
+ 0x2666, /* diamonds */
+ 0x2663 /* clubs */
};
-#define USE_CP437 1
-#else
-#define USE_CP437 0
-#endif /* __i386__ */
+#endif
+#endif /* HAVE_LANGINFO_CODESET */
-static chtype *suits = letters; /* this may change to glyphs below */
+static int *suits = letters; /* this may change to glyphs below */
-static RETSIGTYPE
+static void
die(int onsig)
{
(void) signal(onsig, SIG_IGN);
static void
shuffle(int size)
{
- int i, j, numswaps, swapnum, temp;
+ int numswaps, swapnum;
numswaps = size * 10; /* an arbitrary figure */
for (swapnum = 0; swapnum < numswaps; swapnum++) {
- i = rand() % size;
- j = rand() % size;
- temp = deck[i];
+ int i = rand() % size;
+ int j = rand() % size;
+ int temp = deck[i];
deck[i] = deck[j];
deck[j] = temp;
}
static void
deal_cards(void)
{
- int ptr, card = 0, value, csuit, crank, suit, aces[4];
+ int card = 0, value, csuit, crank, suit, aces[4];
memset(aces, 0, sizeof(aces));
for (suit = HEARTS; suit <= CLUBS; suit++) {
- ptr = freeptr[suit];
+ int ptr = freeptr[suit];
grid[ptr++] = NOCARD; /* 1st card space is blank */
while ((ptr % GRID_WIDTH) != 0) {
value = deck[card++];
static void
printcard(int value)
{
- (void) addch(' ');
- if (value == NOCARD)
+ AddCh(' ');
+ if (value == NOCARD) {
(void) addstr(" ");
- else {
- addch(ranks[value % SUIT_LENGTH][0] | COLOR_PAIR(BLUE_ON_WHITE));
- addch(ranks[value % SUIT_LENGTH][1] | COLOR_PAIR(BLUE_ON_WHITE));
- addch(suits[value / SUIT_LENGTH]);
+ } else {
+ int which = (value / SUIT_LENGTH);
+ int isuit = (value % SUIT_LENGTH);
+ chtype color = (chtype) COLOR_PAIR(((which % 2) == 0)
+ ? RED_ON_WHITE
+ : BLACK_ON_WHITE);
+
+ AddCh(ranks[isuit][0] | (chtype) COLOR_PAIR(BLUE_ON_WHITE));
+ AddCh(ranks[isuit][1] | (chtype) COLOR_PAIR(BLUE_ON_WHITE));
+
+#ifdef NCURSES_VERSION
+ (attron) ((int) color); /* quieter compiler warnings */
+#else
+ attron(color); /* PDCurses, etc., either no macro or wrong */
+#endif
+#if USE_WIDEC_SUPPORT
+ {
+ wchar_t values[2];
+ values[0] = (wchar_t) suits[which];
+ values[1] = 0;
+ addwstr(values);
+ }
+#else
+ AddCh(suits[which]);
+#endif
+#ifdef NCURSES_VERSION
+ (attroff) ((int) color);
+#else
+ attroff(color);
+#endif
}
- (void) addch(' ');
+ AddCh(' ');
}
static void
if (selection[i] != NOCARD) {
move(BASEROW + (selection[i] / GRID_WIDTH) * 2 + 3,
(selection[i] % GRID_WIDTH) * 5);
- (void) printw(" %c ", (char) (*lp++ = 'a' + i));
+ (void) printw(" %c ", (*lp++ = (char) ('a' + i)));
}
};
*lp = '\0';
} else {
char buf[BUFSIZ];
- (void) sprintf(buf,
- "Type [%s] to move, r to redraw, q or INTR to quit: ",
- live);
+ _nc_SPRINTF(buf, _nc_SLIMIT(sizeof(buf))
+ "Type [%s] to move, r to redraw, q or INTR to quit: ",
+ live);
do {
move(PROMPTROW, 0);
(void) addstr(buf);
move(PROMPTROW, (int) strlen(buf));
clrtoeol();
- (void) addch(' ');
+ AddCh(' ');
} while
(((c = (char) getch()) < 'a' || c > 'd')
&& (c != 'r')
static int
collect_discards(void)
{
- int row, col, cardno = 0, finish, gridno;
+ int row, col, cardno = 0, gridno;
for (row = HEARTS; row <= CLUBS; row++) {
- finish = 0;
+ int finish = 0;
for (col = 1; col < GRID_WIDTH; col++) {
gridno = row * GRID_WIDTH + col;
refresh();
}
+#if HAVE_LANGINFO_CODESET
+/*
+ * This program first appeared in ncurses in January 1995. At that point, the
+ * Linux console was able to display CP437 graphic characters, e.g., in the
+ * range 0-31. As of 2016, most Linux consoles are running with the UTF-8
+ * (partial) support. Incidentally, that makes all of the cards diamonds.
+ */
+static void
+use_pc_display(void)
+{
+ char *check = nl_langinfo(CODESET);
+ if (!strcmp(check, "UTF-8")) {
+#if USE_WIDEC_SUPPORT
+ suits = uglyphs;
+#endif
+ } else {
+#if HAVE_TIGETSTR
+ if (!strcmp(check, "IBM437") ||
+ !strcmp(check, "CP437") ||
+ !strcmp(check, "IBM850") ||
+ !strcmp(check, "CP850")) {
+ char *smacs = tigetstr("smacs");
+ char *smpch = tigetstr("smpch");
+ /*
+ * The ncurses library makes this check to decide whether to allow
+ * the alternate character set for the (normally) nonprinting codes.
+ */
+ if (smacs != 0 && smpch != 0 && !strcmp(smacs, smpch)) {
+ suits = glyphs;
+ }
+ }
+#endif
+ }
+}
+#else
+#define use_pc_display() /* nothing */
+#endif /* HAVE_LANGINFO_CODESET */
+
int
main(int argc, char *argv[])
{
- CATCHALL(die);
-
setlocale(LC_ALL, "");
- initscr();
+ use_pc_display();
+
+ InitAndCatch(initscr(), die);
- /*
- * We use COLOR_GREEN because COLOR_BLACK is wired to the wrong thing.
- */
start_color();
init_pair(RED_ON_WHITE, COLOR_RED, COLOR_WHITE);
init_pair(BLUE_ON_WHITE, COLOR_BLUE, COLOR_WHITE);
init_pair(BLACK_ON_WHITE, COLOR_BLACK, COLOR_WHITE);
-#ifndef COLOR_PAIR
- letters[0] = OR_COLORS('h', RED_ON_WHITE); /* hearts */
- letters[1] = OR_COLORS('s', BLACK_ON_WHITE); /* spades */
- letters[2] = OR_COLORS('d', RED_ON_WHITE); /* diamonds */
- letters[3] = OR_COLORS('c', BLACK_ON_WHITE); /* clubs */
-#if USE_CP437
- glyphs[0] = PC_COLORS('\003', RED_ON_WHITE); /* hearts */
- glyphs[1] = PC_COLORS('\006', BLACK_ON_WHITE); /* spades */
- glyphs[2] = PC_COLORS('\004', RED_ON_WHITE); /* diamonds */
- glyphs[3] = PC_COLORS('\005', BLACK_ON_WHITE); /* clubs */
-#endif
-#endif
-
-#if USE_CP437
- if (tigetstr("smpch"))
- suits = glyphs;
-#endif /* USE_CP437 */
-
cbreak();
if (argc == 2)