nsnake
Classic snake game for the terminal
Loading...
Searching...
No Matches
Colors.cpp
1#include <Interface/Colors.hpp>
2
3#include <cstdlib> // strtol()
4
5bool Colors::hasColors = false;
6
7bool Colors::init()
8{
9 if (has_colors() != TRUE) /* ncurses BOOL */
10 {
11 Colors::hasColors = false;
12 return false;
13 }
14 Colors::hasColors = true;
15
16 start_color();
17
18 // This is a big hack to initialize all 64
19 // possible color pairs in ncurses.
20 //
21 // The thing is, all colors are between
22 // COLOR_BLACK and COLOR_WHITE.
23 // Since I've set a large number of enums covering
24 // all possibilities, I can do it all in a for loop.
25 // Check 'man init_pair' for more details.
26 //
27 // Here's the internal value of colors,
28 // taken straight from <curses.h>:
29 //
30 // #define COLOR_BLACK 0
31 // #define COLOR_RED 1
32 // #define COLOR_GREEN 2
33 // #define COLOR_YELLOW 3
34 // #define COLOR_BLUE 4
35 // #define COLOR_MAGENTA 5
36 // #define COLOR_CYAN 6
37 // #define COLOR_WHITE 7
38 //
39 int i, j, k = 1;
40 for (i = COLOR_BLACK; i <= COLOR_WHITE; i++)
41 {
42 for (j = COLOR_BLACK; j <= COLOR_WHITE; j++)
43 {
44 init_pair(k, i, j);
45 k++;
46 }
47 }
48
49 // Besides the normal color pairs, we can use
50 // whatever colors the user has currently set to
51 // their terminal.
52 // It looks more "natural".
53 //
54 // So COLOR_PAIR(-1, -1) is the default foreground
55 // and background.
56 //
57 // Let's do it if the current terminal supports it.
58
59 if (use_default_colors() != ERR)
60 {
61 // default background
62 init_pair(64, COLOR_BLACK, COLOR_DEFAULT);
63 init_pair(65, COLOR_RED, COLOR_DEFAULT);
64 init_pair(66, COLOR_GREEN, COLOR_DEFAULT);
65 init_pair(67, COLOR_YELLOW, COLOR_DEFAULT);
66 init_pair(68, COLOR_BLUE, COLOR_DEFAULT);
67 init_pair(69, COLOR_MAGENTA, COLOR_DEFAULT);
68 init_pair(70, COLOR_CYAN, COLOR_DEFAULT);
69 init_pair(71, COLOR_WHITE, COLOR_DEFAULT);
70 }
71 return true;
72}
73
74Color Colors::rgb(short r, short g, short b)
75{
76 if (can_change_color() == FALSE)
77 return 0;
78
79 if (COLORS < 256)
80 return 0;
81
82 static int color_no = 8;
83 color_no++;
84 if (color_no >= COLORS)
85 color_no = 8;
86
87 // init_color receives values from 0 to 1000
88 int expand = 1000/255;
89
90 init_color((color_no - 1), r*expand, g*expand, b*expand);
91 return (color_no - 1);
92}
93Color Colors::hex(std::string hex)
94{
95 if (hex[0] != '#') return 0; // sorry
96 if (hex.size() != 7) return 0; // #RRGGBB format
97
98 char col[3];
99 col[2] = '\0';
100
101 col[0] = hex[1];
102 col[1] = hex[2];
103 long r = strtol(col, NULL, 16);
104
105 col[0] = hex[3];
106 col[1] = hex[4];
107 long g = strtol(col, NULL, 16);
108
109 col[0] = hex[5];
110 col[1] = hex[6];
111 long b = strtol(col, NULL, 16);
112
113 return Colors::rgb(r, g, b);
114}
115
116ColorPair Colors::pair(Color foreground, Color background, bool is_bold)
117{
118 // Basic nCurses colors
119 if ((foreground < 8) && (background < 8))
120 {
121 if (background == COLOR_DEFAULT)
122 {
123 if (is_bold)
124 return COLOR_PAIR(64 + foreground) | A_BOLD;
125 else
126 return COLOR_PAIR(64 + foreground);
127 }
128
129 if (is_bold)
130 return COLOR_PAIR(foreground*8 + background + 1) | A_BOLD;
131 else
132 return COLOR_PAIR(foreground*8 + background + 1);
133 }
134
135 if (COLORS < 256)
136 {
137 if (is_bold)
138 return COLOR_PAIR(0) | A_BOLD;
139 else
140 return COLOR_PAIR(0);
141 }
142
143 // Will create color pair
144 // (above the 64 regular ones plus 12 default = 72)
145 static int color_pair_no = 72;
146 color_pair_no++;
147 if (color_pair_no >= COLOR_PAIRS)
148 color_pair_no = 72;
149
150 init_pair((color_pair_no - 1), foreground, background);
151
152 if (is_bold)
153 return COLOR_PAIR(color_pair_no - 1) | A_BOLD;
154 else
155 return COLOR_PAIR(color_pair_no - 1);
156}
157Color Colors::fromString(std::string str)
158{
159 if (str.empty())
160 return 255;
161
162 if (str == "default") return COLOR_DEFAULT;
163 if (str == "black") return COLOR_BLACK;
164 if (str == "red") return COLOR_RED;
165 if (str == "green") return COLOR_GREEN;
166 if (str == "yellow") return COLOR_YELLOW;
167 if (str == "blue") return COLOR_BLUE;
168 if (str == "magenta") return COLOR_MAGENTA;
169 if (str == "cyan") return COLOR_CYAN;
170 if (str == "white") return COLOR_WHITE;
171
172 // keep in mind this error code
173 return 255;
174}
175
176ColorPair Colors::pairFromString(std::string foreground, std::string background, bool is_bold)
177{
178 if (foreground.empty() || background.empty())
179 return 255;
180
181 short f = Colors::fromString(foreground);
182 short b = Colors::fromString(background);
183
184 return Colors::pair(f, b, is_bold);
185}
186
187void Colors::activate(WINDOW* window, Color foreground, Color background)
188{
189 Colors::pairActivate(window, Colors::pair(foreground, background));
190}
191
192void Colors::pairActivate(WINDOW* window, ColorPair color)
193{
194 wattrset(window, color);
195}
196