25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

314 lines
12 KiB

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