source: libcaca/trunk/tools/optipal.c @ 1048

Last change on this file since 1048 was 1048, checked in by Jean-Yves Lamoureux, 13 years ago
  • Updated kernel 'driver', still not working, but most of the work is done
  • Property svn:keywords set to Id
File size: 11.9 KB
Line 
1/*
2 *  optipal       S-Lang optimised palette generator for libcaca
3 *  Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: optipal.c 1048 2006-09-17 12:44:18Z jylam $
7 *
8 *  This program is free software; you can redistribute it and/or
9 *  modify it under the terms of the Do What The Fuck You Want To
10 *  Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14#include "config.h"
15#include "common.h"
16
17#if !defined(__KERNEL__)
18#   include <stdio.h>
19#endif
20
21#include "cucul.h" /* Only necessary for CUCUL_* macros */
22
23static void base_colors(void);
24static void emulated_colors(void);
25static void unused_colors(void);
26
27static int slang_assoc[16*16], palette[16*16];
28
29/* 6 colours in hue order */
30static unsigned int const hue_list[] =
31{
32    CUCUL_COLOR_RED,
33    CUCUL_COLOR_BROWN,
34    CUCUL_COLOR_GREEN,
35    CUCUL_COLOR_CYAN,
36    CUCUL_COLOR_BLUE,
37    CUCUL_COLOR_MAGENTA
38};
39
40#define SETPAIR(_fg, _bg, _n) \
41    do \
42    { \
43        int fg = _fg, bg = _bg, n = _n; \
44        slang_assoc[fg + 16 * bg] = n; \
45        palette[n] = fg + 16 * bg; \
46    } \
47    while(0);
48
49int main(int argc, char *argv[])
50{
51    int i;
52
53    for(i = 0; i < 16 * 16; i++)
54    {
55        slang_assoc[i] = -1;
56        palette[i] = -1;
57    }
58
59    /* The base colour pairs (0-127) */
60    base_colors();
61
62    /* Now the less important pairs that we can afford to emulate using
63     * previously defined colour pairs. */
64    emulated_colors();
65
66    /* Fill the rest of the palette with equal colour pairs such as black
67     * on black. They will never be used, but nevermind. */
68    unused_colors();
69
70    /* Output the palette */
71    printf("static int const slang_palette[2*16*16] =\n{\n");
72    for(i = 0; i < 16 * 16; i++)
73    {
74        if((i % 8) == 0) printf("    ");
75        printf("%2i, %2i,  ", palette[i] % 16, palette[i] / 16);
76        if((i % 8) == 7) printf("\n");
77    }
78    printf("};\n\n");
79
80    /* Output the association table */
81    printf("static int const slang_assoc[16*16] =\n{\n");
82    for(i = 0; i < 16 * 16; i++)
83    {
84        if((i % 16) == 0) printf("    ");
85        printf("%i, ", slang_assoc[i]);
86        if((i % 16) == 15) printf("\n");
87    }
88    printf("};\n");
89
90    return 0;
91}
92
93/*
94 *  256 character pairs are definable, but only 128 can be used. This is
95 *  because slsmg.c's This_Color variable uses its 8th bit to indicate an
96 *  alternate character set. Replacing a few 0x7F with 0xFF in sldisply.c
97 *  works around the problem but gets rid of the alternate charset.
98 *
99 *  We can work around this problem. See this usage grid:
100 *
101 *                  bg                         1 1 1 1 1 1
102 *    fg                  0 1 2 3 4 5 6 7  8 9 0 1 2 3 4 5
103 *
104 *    0 (black)             C C C C C C F  B c c c c c c F
105 *    1 (blue)            A   h D h D i f  C C h E h E k g
106 *    2 (green)           A h   D h i D f  C h C E h k E g
107 *    3 (cyan)            A D D   i h h f  C E E C k h h g
108 *    4 (red)             A h h i   D D f  C h h k C E E g
109 *    5 (magenta)         A D i h D   h f  C E k h E C h g
110 *    6 (brown)           A i D h D h   f  C k E h E h C g
111 *    7 (light gray)      A F a a a a a    B C C C C C C B
112 *
113 *    8 (dark gray)       A C C C C C C B    d d d d d d F
114 *    9 (light blue)      A C h E h E j C  e   h D h D l C
115 *    10 (light green)    A h C E h j E C  e h   D h l D C
116 *    11 (light cyan)     A E E C j h h C  e D D   l h h C
117 *    12 (light red)      A h h j C E E C  e h h l   D D C
118 *    13 (light magenta)  A E j h E C h C  e D l h D   h C
119 *    14 (yellow)         A j E h E h C C  e l D h D h   C
120 *    15 (white)          A F b b b b b B  F C C C C C C
121 *
122 *  ' ': useless colour pairs that can be emulated by printing a space in
123 *       any other colour pair that has the same background
124 *  'A': black background colour pairs that are needed for the old renderer
125 *  'B': gray combinations used for grayscale dithering
126 *  'C': white/light, light/dark, lightgray/light, darkgray/dark, dark/black
127 *       combinations often used for saturation/value dithering (the two
128 *       other possible combinations, lightgray/dark and darkgray/light, are
129 *       not considered here)
130 *  'D': next colour combinations for hue dithering (magenta/blue, blue/green
131 *       and so on)
132 *  'E': next colour combinations for hue/value dithering (blue/lightgreen,
133 *       green/lightblue and so on)
134 *  'F': black on light gray, black on white, white on dark gray, dark gray
135 *       on white, white on blue, light gray on blue (chosen arbitrarily)
136 *
137 *  'A': 15 colour pairs
138 *  'A'+'B': 20 colour pairs
139 *  'A'+'B'+'C': 74 colour pairs
140 *  'A'+'B'+'C'+'D': 98 colour pairs
141 *  'A'+'B'+'C'+'D'+'E': 122 colour pairs
142 *  'A'+'B'+'C'+'D'+'E'+'F': 128 colour pairs
143 *
144 *  The remaining slightly important colour pairs are:
145 *
146 *  'a': light gray on dark colour: emulate with light colour on dark colour
147 *  'b': white on dark colour: emulate with light gray on light colour
148 *  'c': black on light colour: emulate with dark gray on dark colour
149 *  'd': dark gray on light colour: emulate with dark colour on light colour
150 *  'e': light colour on dark gray: emulate with dark colour on dark gray
151 *  'f': dark colour on light gray: emulate with light colour on light gray
152 *  'g': dark colour on white: emulate with light colour on white
153 *
154 *  And now the seldom used pairs:
155 *
156 *  'h': 120 degree hue pairs can be emulated as well; for instance blue on
157 *       red can be emulated using magenta on red, and blue on green using
158 *       cyan on green
159 *
160 *  And the almost never used pairs:
161 *
162 *  'i': dark opposite on dark: emulate with dark opposite on black
163 *  'j': light opposite on dark: emulate with light opposite on black
164 *  'k': dark opposite on light: emulate with black on dark
165 *  'l': light opposite on light: emulate with white on light
166 */
167
168static void base_colors(void)
169{
170    int i, cur = 0;
171
172    /* black background colour pairs that are needed for the old renderer */
173    for(i = 1; i < 16; i++)
174        SETPAIR(i, CUCUL_COLOR_BLACK, cur++);
175
176    /* gray combinations used for grayscale dithering */
177    SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_DARKGRAY, cur++);
178    SETPAIR(CUCUL_COLOR_DARKGRAY, CUCUL_COLOR_LIGHTGRAY, cur++);
179    SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_DARKGRAY, cur++);
180    SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_LIGHTGRAY, cur++);
181    SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_WHITE, cur++);
182
183    /* white/light, light/dark, lightgray/light, darkgray/dark, dark/black
184     * combinations often used for saturation/value dithering (the two
185     * other possible combinations, lightgray/dark and darkgray/light, are
186     * not considered here) */
187    for(i = 1; i < 7; i++)
188    {
189        SETPAIR(CUCUL_COLOR_WHITE, i + 8, cur++);
190        SETPAIR(i + 8, CUCUL_COLOR_WHITE, cur++);
191        SETPAIR(i, i + 8, cur++);
192        SETPAIR(i + 8, i, cur++);
193        SETPAIR(CUCUL_COLOR_LIGHTGRAY, i + 8, cur++);
194        SETPAIR(i + 8, CUCUL_COLOR_LIGHTGRAY, cur++);
195        SETPAIR(CUCUL_COLOR_DARKGRAY, i, cur++);
196        SETPAIR(i, CUCUL_COLOR_DARKGRAY, cur++);
197        SETPAIR(CUCUL_COLOR_BLACK, i, cur++);
198    }
199
200    /* next colour combinations for hue dithering (magenta/blue, blue/green
201     * and so on) */
202    for(i = 0; i < 6; i++)
203    {
204        SETPAIR(hue_list[i], hue_list[(i + 1) % 6], cur++);
205        SETPAIR(hue_list[(i + 1) % 6], hue_list[i], cur++);
206        SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6] + 8, cur++);
207        SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i] + 8, cur++);
208    }
209
210    /* next colour combinations for hue/value dithering (blue/lightgreen,
211     * green/lightblue and so on) */
212    for(i = 0; i < 6; i++)
213    {
214        SETPAIR(hue_list[i], hue_list[(i + 1) % 6] + 8, cur++);
215        SETPAIR(hue_list[(i + 1) % 6], hue_list[i] + 8, cur++);
216        SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6], cur++);
217        SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i], cur++);
218    }
219
220    /* black on light gray, black on white, white on dark gray, dark gray
221     * on white, white on blue, light gray on blue (chosen arbitrarily) */
222    SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_LIGHTGRAY, cur++);
223    SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_WHITE, cur++);
224    SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_DARKGRAY, cur++);
225    SETPAIR(CUCUL_COLOR_DARKGRAY, CUCUL_COLOR_WHITE, cur++);
226    SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE, cur++);
227    SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLUE, cur++);
228}
229
230static void emulated_colors(void)
231{
232    int i;
233
234    /* light gray on dark colour: emulate with light colour on dark colour
235     * white on dark colour: emulate with light gray on light colour
236     * black on light colour: emulate with dark gray on dark colour
237     * dark gray on light colour: emulate with dark colour on light colour
238     * light colour on dark gray: emulate with dark colour on dark gray
239     * dark colour on light gray: emulate with light colour on light gray
240     * dark colour on white: emulate with light colour on white */
241    for(i = 1; i < 7; i++)
242    {
243        if(i != CUCUL_COLOR_BLUE)
244        {
245            SETPAIR(CUCUL_COLOR_LIGHTGRAY, i, 128 +
246                    slang_assoc[i + 8 + 16 * i]);
247            SETPAIR(CUCUL_COLOR_WHITE, i, 128 +
248                    slang_assoc[CUCUL_COLOR_LIGHTGRAY + 16 * (i + 8)]);
249        }
250        SETPAIR(CUCUL_COLOR_BLACK, i + 8,
251                128 + slang_assoc[CUCUL_COLOR_DARKGRAY + 16 * i]);
252        SETPAIR(CUCUL_COLOR_DARKGRAY, i + 8,
253                128 + slang_assoc[i + 16 * (i + 8)]);
254        SETPAIR(i + 8, CUCUL_COLOR_DARKGRAY,
255                128 + slang_assoc[i + 16 * CUCUL_COLOR_DARKGRAY]);
256        SETPAIR(i, CUCUL_COLOR_LIGHTGRAY,
257                128 + slang_assoc[i + 8 + 16 * CUCUL_COLOR_LIGHTGRAY]);
258        SETPAIR(i, CUCUL_COLOR_WHITE,
259                128 + slang_assoc[i + 8 + 16 * CUCUL_COLOR_WHITE]);
260    }
261
262    /* 120 degree hue pairs can be emulated as well; for instance blue on
263     * red can be emulated using magenta on red, and blue on green using
264     * cyan on green */
265    for(i = 0; i < 6; i++)
266    {
267        SETPAIR(hue_list[(i + 2) % 6], hue_list[i],
268            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i]]);
269        SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i] + 8,
270            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 136]);
271        SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i],
272            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 8]);
273        SETPAIR(hue_list[(i + 2) % 6], hue_list[i] + 8,
274            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 128]);
275
276        SETPAIR(hue_list[(i + 4) % 6], hue_list[i],
277            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i]]);
278        SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i] + 8,
279            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 136]);
280        SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i],
281            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 8]);
282        SETPAIR(hue_list[(i + 4) % 6], hue_list[i] + 8,
283            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 128]);
284    }
285
286    /* dark opposite on dark: emulate with dark opposite on black
287     * light opposite on dark: emulate with light opposite on black
288     * dark opposite on light: emulate with black on dark
289     * light opposite on light: emulate with white on light */
290    for(i = 0; i < 6; i++)
291    {
292        SETPAIR(hue_list[i], hue_list[(i + 3) % 6],
293                128 + slang_assoc[hue_list[i] + 16 * CUCUL_COLOR_BLACK]);
294        SETPAIR(hue_list[i] + 8, hue_list[(i + 3) % 6],
295                128 + slang_assoc[hue_list[i] + 8 + 16 * CUCUL_COLOR_BLACK]);
296        SETPAIR(hue_list[(i + 3) % 6], hue_list[i] + 8,
297                128 + slang_assoc[CUCUL_COLOR_BLACK + 16 * hue_list[i]]);
298        SETPAIR(hue_list[(i + 3) % 6] + 8, hue_list[i] + 8,
299                128 + slang_assoc[CUCUL_COLOR_WHITE + 16 * (hue_list[i] + 8)]);
300    }
301}
302
303static void unused_colors(void)
304{
305    int i, j;
306
307    for(i = 0, j = 0; i < 16 * 16; i++)
308    {
309        if(palette[i] == -1)
310        {
311            SETPAIR(j, j, i);
312            j++;
313        }
314    }
315}
316
Note: See TracBrowser for help on using the repository browser.