Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

312 рядки
12 KiB

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