Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

optipal.c 12 KiB

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