選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

optipal.c 12 KiB

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