From d11b83952a863bdea7a5729deb01fb623c9a46c8 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Sun, 28 Jul 2024 00:19:03 +0200 Subject: [PATCH] better color management --- block.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++ block.h | 45 +++++++++++++ color.c | 121 ++++++++++++++++++++++++++++++++++ color.h | 39 +++++++++++ constant.c | 14 ++-- display.c | 128 ++++++++++-------------------------- tetris.c | 6 +- 7 files changed, 436 insertions(+), 104 deletions(-) create mode 100644 block.c create mode 100644 block.h create mode 100644 color.c create mode 100644 color.h diff --git a/block.c b/block.c new file mode 100644 index 0000000..9c9fca8 --- /dev/null +++ b/block.c @@ -0,0 +1,187 @@ +#include + +#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 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 index 0000000..05e28fb --- /dev/null +++ b/color.c @@ -0,0 +1,121 @@ +#include + +#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 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: */ diff --git a/constant.c b/constant.c index 6eaa78c..aa9c063 100644 --- a/constant.c +++ b/constant.c @@ -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) diff --git a/display.c b/display.c index 03cc1d6..96f44db 100644 --- a/display.c +++ b/display.c @@ -3,66 +3,14 @@ #include #include +#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: */ diff --git a/tetris.c b/tetris.c index 4f74ca3..256caf7 100644 --- 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 #include -- 2.30.2