better color management
authorLaurent Mazet <mazet@softndesign.org>
Sat, 27 Jul 2024 22:19:03 +0000 (00:19 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Sat, 27 Jul 2024 22:19:03 +0000 (00:19 +0200)
block.c [new file with mode: 0644]
block.h [new file with mode: 0644]
color.c [new file with mode: 0644]
color.h [new file with mode: 0644]
constant.c
display.c
tetris.c

diff --git a/block.c b/block.c
new file mode 100644 (file)
index 0000000..9c9fca8
--- /dev/null
+++ b/block.c
@@ -0,0 +1,187 @@
+#include <curses.h>
+
+#include "block.h"
+
+typedef enum {
+    _black = 0,
+    _blue,
+    _green,
+    _cyan,
+    _red,
+    _magenta,
+    _yellow,
+    _white
+} _color_t;
+
+static int _color_num (int fg, int bg)
+{
+    return (1 << 6) | ((7 & bg) << 3) | (7 & fg);
+}
+static int _color_trans (_color_t c)
+{
+    int color;
+    switch (7 & c) {
+    case _black:
+        color = COLOR_BLACK;
+        break;
+    case _blue:
+        color = COLOR_BLUE;
+        break;
+    case _green:
+        color = COLOR_GREEN;
+        break;
+    case _cyan:
+        color = COLOR_CYAN;
+        break;
+    case _red:
+        color = COLOR_RED;
+        break;
+    case _magenta:
+        color = COLOR_MAGENTA;
+        break;
+    case _yellow:
+        color = COLOR_YELLOW;
+        break;
+    case _white:
+        color = COLOR_WHITE;
+        break;
+    }
+    return color;
+}
+
+static void _init_color_pairs () {
+    int fg, bg;
+    for (bg = 0; bg < 8; bg++) {
+        for (fg = 0; fg < 8; fg ++) {
+            init_pair (_color_num (fg, bg), _color_trans (fg), _color_trans (bg));
+        }
+    }
+}
+
+void mvaddcb (int y, int x, cblock_t color)
+{
+    int init = 1;
+    if (init) {
+        _init_color_pairs ();
+        init = 0;
+    }
+
+    int symb = ACS_CKBOARD;
+    switch (color) {
+    case black:
+    case gray:
+    case blue:
+    case green:
+    case cyan:
+    case red:
+    case magenta:
+    case brown:
+        symb = ' ';
+        break;
+    default:
+        symb = ACS_CKBOARD;
+    }
+
+    int num;
+    switch (color) {
+    case black:
+    case darkgray:
+        num = _color_num (_white, _black);
+        break;
+    case gray:
+    case white:
+        num = _color_num (_white, _white);
+        break;
+    case darkerblue:
+    case darkblue:
+        num = _color_num (_blue, _black);
+        break;
+    case darkergreen:
+    case darkgreen:
+        num = _color_num (_green, _black);
+        break;
+    case darkercyan:
+    case darkcyan:
+        num = _color_num (_cyan, _black);
+        break;
+    case darkerred:
+    case darkred:
+        num = _color_num (_red, _black);
+        break;
+    case darkermagenta:
+    case darkmagenta:
+        num = _color_num (_magenta, _black);
+        break;
+    case darkbrown:
+    case darkeryellow:
+        num = _color_num (_yellow, _black);
+        break;
+    case blue:
+    case lightblue:
+    case lighterblue:
+        num = _color_num (_blue, _white);
+        break;
+    case green:
+    case lightgreen:
+    case lightergreen:
+        num = _color_num (_green, _white);
+        break;
+    case cyan:
+    case lightcyan:
+    case lightercyan:
+        num = _color_num (_cyan, _white);
+        break;
+    case red:
+    case lightred:
+    case lighterred:
+        num = _color_num (_red, _white);
+        break;
+    case magenta:
+    case lightmagenta:
+    case lightermagenta:
+        num = _color_num (_magenta, _white);
+        break;
+    case brown:
+    case darkyellow:
+    case yellow:
+        num = _color_num (_yellow, _white);
+        break;
+    //default:
+    //    num = _color_num (_white, _black);
+    }
+
+    int state;
+    switch (color) {
+    case blue:
+    case green:
+    case cyan:
+    case red:
+    case magenta:
+    case brown:
+        state = A_REVERSE;
+        break;
+    case white:
+    case darkblue:
+    case darkgreen:
+    case darkcyan:
+    case darkred:
+    case darkmagenta:
+    case darkeryellow:
+    case lighterblue:
+    case lightergreen:
+    case lightercyan:
+    case lighterred:
+    case lightermagenta:
+    case yellow:
+        state = A_BOLD;
+        break;
+    default:
+        state = A_NORMAL;
+    }
+
+    attron (COLOR_PAIR (num) | state);
+    mvaddch (y, x, symb);
+    attroff (COLOR_PAIR (num) | state);
+}
+
+/* vim: set ts=4 sw=4 et: */
diff --git a/block.h b/block.h
new file mode 100644 (file)
index 0000000..481bcc5
--- /dev/null
+++ b/block.h
@@ -0,0 +1,45 @@
+#ifndef __BLOCK_H__
+#define __BLOCK_H__
+
+typedef enum {
+    black,
+    darkgray,
+    gray,
+    white,
+    darkerblue,
+    darkblue,
+    blue,
+    lightblue,
+    lighterblue,
+    darkergreen,
+    darkgreen,
+    green,
+    lightgreen,
+    lightergreen,
+    darkercyan,
+    darkcyan,
+    cyan,
+    lightcyan,
+    lightercyan,
+    darkerred,
+    darkred,
+    red,
+    lightred,
+    lighterred,
+    darkermagenta,
+    darkmagenta,
+    magenta,
+    lightmagenta,
+    lightermagenta,
+    darkbrown,
+    brown,
+    darkeryellow,
+    darkyellow,
+    yellow,
+} cblock_t;
+
+void mvaddcb (int y, int x, cblock_t color);
+
+#endif /* __BLOCK_H__ */
+
+/* vim: set ts=4 sw=4 et: */
diff --git a/color.c b/color.c
new file mode 100644 (file)
index 0000000..05e28fb
--- /dev/null
+++ b/color.c
@@ -0,0 +1,121 @@
+#include <curses.h>
+
+#include "color.h"
+
+static void _init_color_pairs () {
+    init_pair (1, COLOR_WHITE, COLOR_BLACK);
+    init_pair (2, COLOR_BLUE, COLOR_BLACK);
+    init_pair (3, COLOR_GREEN, COLOR_BLACK);
+    init_pair (4, COLOR_CYAN, COLOR_BLACK);
+    init_pair (5, COLOR_RED, COLOR_BLACK);
+    init_pair (6, COLOR_MAGENTA, COLOR_BLACK);
+    init_pair (7, COLOR_YELLOW, COLOR_BLACK);
+    init_pair (8, COLOR_WHITE, COLOR_WHITE);
+    init_pair (9, COLOR_BLUE, COLOR_WHITE);
+    init_pair (10, COLOR_GREEN, COLOR_WHITE);
+    init_pair (11, COLOR_CYAN, COLOR_WHITE);
+    init_pair (12, COLOR_RED, COLOR_WHITE);
+    init_pair (13, COLOR_MAGENTA, COLOR_WHITE);
+    init_pair (14, COLOR_YELLOW, COLOR_WHITE);
+    init_pair (15, COLOR_BLACK, COLOR_WHITE);
+}
+
+void setcolor (ctext_t color)
+{
+    static int init = 1;
+    if (init) {
+        _init_color_pairs ();
+        init = 0;
+    }
+
+    attroff (A_BOLD);
+
+    int num;
+    switch (color) {
+    case gray_black:
+    case white_black:
+        num = 1;
+        break;
+    case blue_black:
+    case lightblue_black:
+        num = 2;
+        break;
+    case green_black:
+    case lightgreen_black:
+        num = 3;
+        break;
+    case cyan_black:
+    case lightcyan_black:
+        num = 4;
+        break;
+    case red_black:
+    case lightred_black:
+        num = 5;
+        break;
+    case magenta_black:
+    case lightmagenta_black:
+        num = 6;
+        break;
+    case brown_black:
+    case yellow_black:
+        num = 7;
+        break;
+    case white_gray:
+        num = 8;
+        break;
+    case blue_gray:
+    case lightblue_gray:
+        num = 9;
+        break;
+    case green_gray:
+    case lightgreen_gray:
+        num = 10;
+        break;
+    case cyan_gray:
+    case lightcyan_gray:
+        num = 11;
+        break;
+    case red_gray:
+    case lightred_gray:
+        num = 12;
+        break;
+    case magenta_gray:
+    case lightmagenta_gray:
+        num = 13;
+        break;
+    case brown_gray:
+    case yellow_gray:
+        num = 14;
+        break;
+    case black_gray:
+        num = 15;
+        break;
+    }
+
+    int state;
+    switch (color) {
+    case white_black:
+    case lightblue_black:
+    case lightgreen_black:
+    case lightcyan_black:
+    case lightred_black:
+    case lightmagenta_black:
+    case yellow_black:
+    case white_gray:
+    case lightblue_gray:
+    case lightgreen_gray:
+    case lightcyan_gray:
+    case lightred_gray:
+    case lightmagenta_gray:
+    case yellow_gray:
+        state = A_BOLD;
+        break;
+    default:
+        state = A_NORMAL;
+    }
+
+    attron (COLOR_PAIR (num) | state);
+
+}
+
+/* vim: set ts=4 sw=4 et: */
diff --git a/color.h b/color.h
new file mode 100644 (file)
index 0000000..0b2d25a
--- /dev/null
+++ b/color.h
@@ -0,0 +1,39 @@
+#ifndef __COLOR_H__
+#define __COLOR_H__
+
+typedef enum {
+    gray_black = 0,
+    blue_black,
+    green_black,
+    cyan_black,
+    red_black,
+    magenta_black,
+    brown_black,
+    white_black,
+    lightblue_black,
+    lightgreen_black,
+    lightcyan_black,
+    lightred_black,
+    lightmagenta_black,
+    yellow_black,
+    blue_gray,
+    green_gray,
+    cyan_gray,
+    red_gray,
+    magenta_gray,
+    brown_gray,
+    white_gray,
+    lightblue_gray,
+    lightgreen_gray,
+    lightcyan_gray,
+    lightred_gray,
+    lightmagenta_gray,
+    yellow_gray,
+    black_gray
+} ctext_t;
+
+void setcolor (ctext_t color);
+
+#endif /* __COLOR_H__ */
+
+/* vim: set ts=4 sw=4 et: */
index 6eaa78cf0edfff9dee03b251870ab3ee7ebaf291..aa9c06344ea8bd8a6462578a45725c0fb7d7be6e 100644 (file)
@@ -8,13 +8,13 @@
 #define _nb_blocks_std 7
 
 block_t _blocks_std[_nb_blocks_std] = {
-    {4, 1, 2, "...."},
-    {2, 2, 4, "...."},
-    {3, 2, 7, "... . "},
-    {3, 2, 6, "....  "},
-    {3, 2, 1, ".  ..."},
-    {3, 2, 5, "..  .."},
-    {3, 2, 3, " .... "},
+    {4, 1, 1, "...."},   // I
+    {2, 2, 2, "...."},   // O
+    {3, 2, 3, "... . "}, // T
+    {3, 2, 4, "....  "}, // L
+    {3, 2, 5, ".  ..."}, // J
+    {3, 2, 6, "..  .."}, // Z
+    {3, 2, 7, " .... "}, // S
 };
 
 block_t *getblocks (char *name, int *nb)
index 03cc1d6296454d279b938375c1c17252d75b7163..96f44dbd57b948ac8c820ea2597adbd4bffdde72 100644 (file)
--- a/display.c
+++ b/display.c
@@ -3,66 +3,14 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "block.h"
+#include "color.h"
 #include "debug.h"
 #include "function.h"
 #include "type.h"
 
 #include "display.h"
 
-typedef enum {
-    white = 1,
-    red,
-    green,
-    blue,
-    cyan,
-    magenta,
-    yellow,
-    bred,
-    bgreen,
-    bblue,
-    bcyan,
-    bmagenta,
-    byellow,
-    black,
-    wred,
-    wgreen,
-    wblue,
-    wcyan,
-    wmagenta,
-    wyellow,
-} color_t;
-
-void set_color (color_t color)
-{
-    static int init = 1;
-
-    if (init) {
-        init_pair (white, COLOR_WHITE, COLOR_BLACK);
-        init_pair (red, COLOR_RED, COLOR_BLACK);
-        init_pair (green, COLOR_GREEN, COLOR_BLACK);
-        init_pair (blue, COLOR_BLUE, COLOR_BLACK);
-        init_pair (magenta, COLOR_MAGENTA, COLOR_BLACK);
-        init_pair (yellow, COLOR_YELLOW, COLOR_BLACK);
-        init_pair (cyan, COLOR_CYAN, COLOR_BLACK);
-        init_pair (bred, COLOR_BLACK, COLOR_RED);
-        init_pair (bgreen, COLOR_BLACK, COLOR_GREEN);
-        init_pair (bblue, COLOR_BLACK, COLOR_BLUE);
-        init_pair (bmagenta, COLOR_BLACK, COLOR_MAGENTA);
-        init_pair (byellow, COLOR_BLACK, COLOR_YELLOW);
-        init_pair (bcyan, COLOR_BLACK, COLOR_CYAN);
-        init_pair (black, COLOR_BLACK, COLOR_WHITE);
-        init_pair (wred, COLOR_WHITE, COLOR_RED);
-        init_pair (wgreen, COLOR_WHITE, COLOR_GREEN);
-        init_pair (wblue, COLOR_WHITE, COLOR_BLUE);
-        init_pair (wcyan, COLOR_WHITE, COLOR_CYAN);
-        init_pair (wmagenta, COLOR_WHITE, COLOR_MAGENTA);
-        init_pair (wyellow, COLOR_WHITE, COLOR_YELLOW);
-        init = 0;
-    }
-
-    attrset (COLOR_PAIR(color));
-}
-
 int _helpwindow (char *msg, int xoffset, int yoffset, int length)
 {
     int i = 0;
@@ -118,71 +66,63 @@ int helpwindow (char *msg, int xoffset, int yoffset)
     return j;
 }
 
-void _set_symb_color (char symb)
+void _put_color_block (int y, int x, char symb)
 {
     switch (symb) {
     case ' ':
-        set_color (white);
+        mvaddcb (y, x, black);
         break;
     case '1':
-        set_color (black);
+        mvaddcb (y, x, cyan);
         break;
     case '2':
-        set_color (wred);
+        mvaddcb (y, x, yellow);
         break;
     case '3':
-        set_color (wgreen);
+        mvaddcb (y, x, magenta);
         break;
     case '4':
-        set_color (wblue);
+        mvaddcb (y, x, brown);
         break;
     case '5':
-        set_color (wcyan);
+        mvaddcb (y, x, blue);
         break;
     case '6':
-        set_color (wmagenta);
+        mvaddcb (y, x, red);
         break;
     case '7':
-        set_color (wyellow);
+        mvaddcb (y, x, green);
         break;
     }
 }
 
 void _element0 (board_t *board, int x, int y, int symb)
 {
-    _set_symb_color (symb);
-    mvaddch (board->yoffset + y, board->xoffset + x, ' ');
-    set_color (white);
+    _put_color_block (board->yoffset + y, board->xoffset + x, symb);
 }
 
 void _element1 (board_t *board, int x, int y, int symb)
 {
-    _set_symb_color (symb);
-    mvaddch (board->yoffset + y, board->xoffset + 2 * x, ' ');
-    mvaddch (board->yoffset + y, board->xoffset + 2 * x + 1, ' ');
-    set_color (white);
+    _put_color_block (board->yoffset + y, board->xoffset + 2 * x, symb);
+    _put_color_block (board->yoffset + y, board->xoffset + 2 * x + 1, symb);
 }
 
 void _element2 (board_t *board, int x, int y, int symb)
 {
-    _set_symb_color (symb);
-    mvaddch (board->yoffset + 2 * y, board->xoffset + 2 * x, ' ');
-    mvaddch (board->yoffset + 2 * y, board->xoffset + 2 * x + 1, ' ');
-    mvaddch (board->yoffset + 2 * y + 1, board->xoffset + 2 * x, ' ');
-    mvaddch (board->yoffset + 2 * y + 1, board->xoffset + 2 * x + 1, ' ');
-    set_color (white);
+    _put_color_block (board->yoffset + 2 * y, board->xoffset + 2 * x, symb);
+    _put_color_block (board->yoffset + 2 * y, board->xoffset + 2 * x + 1, symb);
+    _put_color_block (board->yoffset + 2 * y + 1, board->xoffset + 2 * x, symb);
+    _put_color_block (board->yoffset + 2 * y + 1, board->xoffset + 2 * x + 1, symb);
 }
 
 void _element3 (board_t *board, int x, int y, int symb)
 {
-    _set_symb_color (symb);
-    mvaddch (board->yoffset + 2 * y, board->xoffset + 3 * x, ' ');
-    mvaddch (board->yoffset + 2 * y, board->xoffset + 3 * x + 1, ' ');
-    mvaddch (board->yoffset + 2 * y, board->xoffset + 3 * x + 2, ' ');
-    mvaddch (board->yoffset + 2 * y + 1, board->xoffset + 3 * x, ' ');
-    mvaddch (board->yoffset + 2 * y + 1, board->xoffset + 3 * x + 1, ' ');
-    mvaddch (board->yoffset + 2 * y + 1, board->xoffset + 3 * x + 2, ' ');
-    set_color (white);
+    _put_color_block (board->yoffset + 2 * y, board->xoffset + 3 * x, symb);
+    _put_color_block (board->yoffset + 2 * y, board->xoffset + 3 * x + 1, symb);
+    _put_color_block (board->yoffset + 2 * y, board->xoffset + 3 * x + 2, symb);
+    _put_color_block (board->yoffset + 2 * y + 1, board->xoffset + 3 * x, symb);
+    _put_color_block (board->yoffset + 2 * y + 1, board->xoffset + 3 * x + 1, symb);
+    _put_color_block (board->yoffset + 2 * y + 1, board->xoffset + 3 * x + 2, symb);
 }
 
 void _element (board_t *board, int x, int y, int symb)
@@ -207,9 +147,9 @@ void boardwindow (board_t *board, int mode)
 {
     int i, j;
 
-    set_color ((mode) ? white : black);
+    setcolor (mode ? gray_black : black_gray);
     _dobound (board->xsize, board->ysize, board->xoffset, board->yoffset);
-    set_color (white);
+    setcolor (gray_black);
 
     for (i = 0; i < board->width; i++) {
         for (j = 0; j < board->height; j++) {
@@ -220,9 +160,9 @@ void boardwindow (board_t *board, int mode)
 
 void scorewindow (int xoffset, int yoffset, int length, int score, int level)
 {
-    set_color (black);
+    setcolor (black_gray);
     _dobound (length + 9, 2, xoffset, yoffset);
-    set_color (white);
+    setcolor (gray_black);
 
     char fmt[12], msg[32];
     sprintf (fmt, "%% %dd", length);
@@ -262,17 +202,17 @@ char *savewindow (int length, int xoffset, int yoffset)
     CHECKALLOC (name);
     memset (name, ' ', length);
 
-    set_color (black);
+    setcolor (black_gray);
     _dobound (length, 1, xoffset, yoffset);
-    set_color (white);
+    setcolor (gray_black);
 
     int i = 0, j;
     int stop = 0;
     while (!stop) {
         for (j = 0; j < length; j++) {
-            set_color ((j == i) ? yellow : black);
+            setcolor ((j == i) ? yellow_black : black_gray);
             mvaddch (yoffset, xoffset + j, name[j]);
-            set_color (white);
+            setcolor (gray_black);
         }
         int ch = getch ();
         switch (ch) {
@@ -330,7 +270,7 @@ char *savewindow (int length, int xoffset, int yoffset)
 
 void msgwindow (char *msg, int xoffset, int yoffset, int length)
 {
-    set_color (white);
+    setcolor (gray_black);
     _dobound ((length > 0) ? length : (int)strlen (msg), 1, xoffset, yoffset);
     if (length > 0) {
         int i;
@@ -339,7 +279,7 @@ void msgwindow (char *msg, int xoffset, int yoffset, int length)
         }
     }
     mvaddstr (yoffset, xoffset + ((length > 0) ? (length - (int)strlen (msg)) / 2 : 0), msg);
-    set_color (black);
+    setcolor (black_gray);
 }
 
 /* vim: set ts=4 sw=4 et: */
index 4f74ca3575dec44b6934340cea486bc97b62fd66..256caf792bcd13756b5f84c445f1059b8a6378c4 100644 (file)
--- a/tetris.c
+++ b/tetris.c
@@ -1,8 +1,8 @@
 /* depend: */
 /* cflags: */
-/* linker: constant.o debug.o display.o function.o -lcurses */
-/* doslnk: constant.o debug.o display.o function.o -lpdc~1 */
-/* winlnk: constant.o debug.o display.o function.o -lpdcurses */
+/* linker: block.o color.c constant.o debug.o display.o function.o -lcurses */
+/* doslnk: block.o color.c constant.o debug.o display.o function.o -lpdc~1 */
+/* winlnk: block.o color.c constant.o debug.o display.o function.o -lpdcurses */
 
 #include <curses.h>
 #include <stdio.h>