You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

243 line
8.2 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; 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 <stdio.h>
  15. #include "caca.h"
  16. static void base_colors(void);
  17. static void emulated_colors(void);
  18. static void unused_colors(void);
  19. static int slang_assoc[16*16], palette[16*16];
  20. /* 6 colours in hue order */
  21. static enum caca_color const hue_list[] =
  22. {
  23. CACA_COLOR_RED,
  24. CACA_COLOR_BROWN,
  25. CACA_COLOR_GREEN,
  26. CACA_COLOR_CYAN,
  27. CACA_COLOR_BLUE,
  28. CACA_COLOR_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(void)
  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. * XXX: See the NOTES file for what follows
  76. */
  77. static void base_colors(void)
  78. {
  79. int i, cur = 0;
  80. /* black background colour pairs that are needed for the old renderer */
  81. for(i = 1; i < 16; i++)
  82. SETPAIR(i, CACA_COLOR_BLACK, cur++);
  83. /* gray combinations used for grayscale dithering */
  84. SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_DARKGRAY, cur++);
  85. SETPAIR(CACA_COLOR_DARKGRAY, CACA_COLOR_LIGHTGRAY, cur++);
  86. SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_DARKGRAY, cur++);
  87. SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_LIGHTGRAY, cur++);
  88. SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_WHITE, cur++);
  89. /* white/light, light/dark, lightgray/light, darkgray/dark, dark/black
  90. * combinations often used for saturation/value dithering (the two
  91. * other possible combinations, lightgray/dark and darkgray/light, are
  92. * not considered here) */
  93. for(i = 1; i < 7; i++)
  94. {
  95. SETPAIR(CACA_COLOR_WHITE, i + 8, cur++);
  96. SETPAIR(i + 8, CACA_COLOR_WHITE, cur++);
  97. SETPAIR(i, i + 8, cur++);
  98. SETPAIR(i + 8, i, cur++);
  99. SETPAIR(CACA_COLOR_LIGHTGRAY, i + 8, cur++);
  100. SETPAIR(i + 8, CACA_COLOR_LIGHTGRAY, cur++);
  101. SETPAIR(CACA_COLOR_DARKGRAY, i, cur++);
  102. SETPAIR(i, CACA_COLOR_DARKGRAY, cur++);
  103. SETPAIR(CACA_COLOR_BLACK, i, cur++);
  104. }
  105. /* next colour combinations for hue dithering (magenta/blue, blue/green
  106. * and so on) */
  107. for(i = 0; i < 6; i++)
  108. {
  109. SETPAIR(hue_list[i], hue_list[(i + 1) % 6], cur++);
  110. SETPAIR(hue_list[(i + 1) % 6], hue_list[i], cur++);
  111. SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6] + 8, cur++);
  112. SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i] + 8, cur++);
  113. }
  114. /* next colour combinations for hue/value dithering (blue/lightgreen,
  115. * green/lightblue and so on) */
  116. for(i = 0; i < 6; i++)
  117. {
  118. SETPAIR(hue_list[i], hue_list[(i + 1) % 6] + 8, cur++);
  119. SETPAIR(hue_list[(i + 1) % 6], hue_list[i] + 8, cur++);
  120. SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6], cur++);
  121. SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i], cur++);
  122. }
  123. /* black on light gray, black on white, white on dark gray, dark gray
  124. * on white, white on blue, light gray on blue (chosen arbitrarily) */
  125. SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_LIGHTGRAY, cur++);
  126. SETPAIR(CACA_COLOR_BLACK, CACA_COLOR_WHITE, cur++);
  127. SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_DARKGRAY, cur++);
  128. SETPAIR(CACA_COLOR_DARKGRAY, CACA_COLOR_WHITE, cur++);
  129. SETPAIR(CACA_COLOR_WHITE, CACA_COLOR_BLUE, cur++);
  130. SETPAIR(CACA_COLOR_LIGHTGRAY, CACA_COLOR_BLUE, cur++);
  131. }
  132. static void emulated_colors(void)
  133. {
  134. int i;
  135. /* light gray on dark colour: emulate with light colour on dark colour
  136. * white on dark colour: emulate with light gray on light colour
  137. * black on light colour: emulate with dark gray on dark colour
  138. * dark gray on light colour: emulate with dark colour on light colour
  139. * light colour on dark gray: emulate with dark colour on dark gray
  140. * dark colour on light gray: emulate with light colour on light gray
  141. * dark colour on white: emulate with light colour on white */
  142. for(i = 1; i < 7; i++)
  143. {
  144. if(i != CACA_COLOR_BLUE)
  145. {
  146. SETPAIR(CACA_COLOR_LIGHTGRAY, i, 128 +
  147. slang_assoc[i + 8 + 16 * i]);
  148. SETPAIR(CACA_COLOR_WHITE, i, 128 +
  149. slang_assoc[CACA_COLOR_LIGHTGRAY + 16 * (i + 8)]);
  150. }
  151. SETPAIR(CACA_COLOR_BLACK, i + 8,
  152. 128 + slang_assoc[CACA_COLOR_DARKGRAY + 16 * i]);
  153. SETPAIR(CACA_COLOR_DARKGRAY, i + 8,
  154. 128 + slang_assoc[i + 16 * (i + 8)]);
  155. SETPAIR(i + 8, CACA_COLOR_DARKGRAY,
  156. 128 + slang_assoc[i + 16 * CACA_COLOR_DARKGRAY]);
  157. SETPAIR(i, CACA_COLOR_LIGHTGRAY,
  158. 128 + slang_assoc[i + 8 + 16 * CACA_COLOR_LIGHTGRAY]);
  159. SETPAIR(i, CACA_COLOR_WHITE,
  160. 128 + slang_assoc[i + 8 + 16 * CACA_COLOR_WHITE]);
  161. }
  162. /* 120 degree hue pairs can be emulated as well; for instance blue on
  163. * red can be emulated using magenta on red, and blue on green using
  164. * cyan on green */
  165. for(i = 0; i < 6; i++)
  166. {
  167. SETPAIR(hue_list[(i + 2) % 6], hue_list[i],
  168. 128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i]]);
  169. SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i] + 8,
  170. 128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 136]);
  171. SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i],
  172. 128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 8]);
  173. SETPAIR(hue_list[(i + 2) % 6], hue_list[i] + 8,
  174. 128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 128]);
  175. SETPAIR(hue_list[(i + 4) % 6], hue_list[i],
  176. 128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i]]);
  177. SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i] + 8,
  178. 128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 136]);
  179. SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i],
  180. 128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 8]);
  181. SETPAIR(hue_list[(i + 4) % 6], hue_list[i] + 8,
  182. 128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 128]);
  183. }
  184. /* dark opposite on dark: emulate with dark opposite on black
  185. * light opposite on dark: emulate with light opposite on black
  186. * dark opposite on light: emulate with black on dark
  187. * light opposite on light: emulate with white on light */
  188. for(i = 0; i < 6; i++)
  189. {
  190. SETPAIR(hue_list[i], hue_list[(i + 3) % 6],
  191. 128 + slang_assoc[hue_list[i] + 16 * CACA_COLOR_BLACK]);
  192. SETPAIR(hue_list[i] + 8, hue_list[(i + 3) % 6],
  193. 128 + slang_assoc[hue_list[i] + 8 + 16 * CACA_COLOR_BLACK]);
  194. SETPAIR(hue_list[(i + 3) % 6], hue_list[i] + 8,
  195. 128 + slang_assoc[CACA_COLOR_BLACK + 16 * hue_list[i]]);
  196. SETPAIR(hue_list[(i + 3) % 6] + 8, hue_list[i] + 8,
  197. 128 + slang_assoc[CACA_COLOR_WHITE + 16 * (hue_list[i] + 8)]);
  198. }
  199. }
  200. static void unused_colors(void)
  201. {
  202. int i, j;
  203. for(i = 0, j = 0; i < 16 * 16; i++)
  204. {
  205. if(palette[i] == -1)
  206. {
  207. SETPAIR(j, j, i);
  208. j++;
  209. }
  210. }
  211. }