PageRenderTime 50ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/liquidwar/utils/liquidwartex.c

#
C | 447 lines | 291 code | 53 blank | 103 comment | 52 complexity | 7fd382beabadedaf95a01cabb7001a1a MD5 | raw file
Possible License(s): LGPL-2.0, GPL-2.0
  1. /********************************************************************/
  2. /* */
  3. /* L I QQ U U I DD W W A RR 555 */
  4. /* L I Q Q U U I D D W W A A R R 5 */
  5. /* L I Q Q U U I D D W W W AAA RR 55 */
  6. /* L I Q Q U U I D D WW WW A A R R 5 */
  7. /* LLL I Q Q U I DD W W A A R R 55 */
  8. /* */
  9. /* b */
  10. /* bb y y */
  11. /* b b yyy */
  12. /* bb y */
  13. /* yy */
  14. /* */
  15. /* U U FFF O O TTT */
  16. /* U U F O O O O T */
  17. /* U U TIRET FF O O O O T */
  18. /* U U F O O O O T */
  19. /* U F O O T */
  20. /* */
  21. /********************************************************************/
  22. /*****************************************************************************/
  23. /* Liquid War is a multiplayer wargame */
  24. /* Copyright (C) 1998-2013 Christian Mauduit */
  25. /* */
  26. /* This program is free software; you can redistribute it and/or modify */
  27. /* it under the terms of the GNU General Public License as published by */
  28. /* the Free Software Foundation; either version 2 of the License, or */
  29. /* (at your option) any later version. */
  30. /* */
  31. /* This program is distributed in the hope that it will be useful, */
  32. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  33. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  34. /* GNU General Public License for more details. */
  35. /* */
  36. /* You should have received a copy of the GNU General Public License */
  37. /* along with this program; if not, write to the Free Software */
  38. /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
  39. /* */
  40. /* Liquid War homepage : http://www.ufoot.org/liquidwar/v5 */
  41. /* Contact author : ufoot@ufoot.org */
  42. /*****************************************************************************/
  43. /********************************************************************/
  44. /* nom : liquidwartex.c */
  45. /* contenu : tool to generate textures */
  46. /* date de modif : March 2000 */
  47. /********************************************************************/
  48. /*=================================================================*/
  49. /* defines */
  50. /*=================================================================*/
  51. #define ALLEGRO_USE_CONSOLE
  52. /*=================================================================*/
  53. /* includes */
  54. /*=================================================================*/
  55. #include <stdio.h>
  56. #include <stdlib.h>
  57. #include <string.h>
  58. #include <fcntl.h>
  59. #include <time.h>
  60. #include <allegro.h>
  61. #include <sys/stat.h>
  62. /*=================================================================*/
  63. /* variables globales */
  64. /*=================================================================*/
  65. int ARGC;
  66. char **ARGV;
  67. int FLAG_HELP = 0;
  68. int FLAG_SILENT = 0;
  69. char *FILENAMES[65536];
  70. int NUMBER_OF_FILES = 0;
  71. PALETTE PALETTE_SRC;
  72. BITMAP *BITMAP_SRC = NULL;
  73. int DST_X, DST_Y, DST_W, DST_H, DST_SIZE;
  74. int FIRST_COLOR = 32;
  75. int COLOR_NUMBER = 32;
  76. char BUFFER[1048576];
  77. char SYSTEM_NAME[16];
  78. /*=================================================================*/
  79. /* fonctions */
  80. /*=================================================================*/
  81. /*-----------------------------------------------------------------*/
  82. /* affichages d'aide */
  83. /*-----------------------------------------------------------------*/
  84. /*-----------------------------------------------------------------*/
  85. void
  86. display_common_help (void)
  87. {
  88. printf ("liquidwartex by U-Foot (ufoot@ufoot.org).\n");
  89. printf ("This program creates textures for Liquid War.\n");
  90. printf ("It is free software, protected by the GPL.\n");
  91. printf ("It uses Allegro by Shawn Hargreaves.\n");
  92. printf ("\n");
  93. }
  94. /*-----------------------------------------------------------------*/
  95. void
  96. display_short_help (void)
  97. {
  98. display_common_help ();
  99. printf ("Type \"liquidwartex -?\" for more help.\n");
  100. }
  101. /*-----------------------------------------------------------------*/
  102. void
  103. display_long_help (void)
  104. {
  105. display_common_help ();
  106. printf
  107. ("The source must be a 256 color bitmap using color from first_color to first_color+number_of_colors-1.\n");
  108. printf ("\n");
  109. printf ("Syntax:\n");
  110. printf ("liquidwartex [options] first_color number_of_colors filenames\n");
  111. printf ("\n");
  112. printf ("Options:\n");
  113. printf ("-? -h -H : displays this help.\n");
  114. printf ("-s -S : silent mode, nothing written to the console.\n");
  115. printf ("\n");
  116. printf ("Remark: the created texture will have a .tex extension.\n");
  117. }
  118. /*-----------------------------------------------------------------*/
  119. /* lecture des parametres de la ligne de commande */
  120. /*-----------------------------------------------------------------*/
  121. /*-----------------------------------------------------------------*/
  122. int
  123. acknowledge_flag (char *str)
  124. {
  125. int found = 0;
  126. if (str[0] == '-' || str[0] == '/')
  127. {
  128. found = 1;
  129. switch (str[1])
  130. {
  131. case '?':
  132. case 'h':
  133. case 'H':
  134. FLAG_HELP = 1;
  135. break;
  136. case 's':
  137. case 'S':
  138. FLAG_SILENT = 1;
  139. break;
  140. default:
  141. found = 0;
  142. }
  143. }
  144. return found;
  145. }
  146. /*-----------------------------------------------------------------*/
  147. int
  148. read_command_line (void)
  149. {
  150. int i, j = 0, success = 1;
  151. if (ARGC <= 2)
  152. {
  153. success = 0;
  154. if (!FLAG_HELP)
  155. printf ("ERROR! Too few arguments.\n");
  156. }
  157. else
  158. {
  159. for (i = 1; i < ARGC; ++i)
  160. {
  161. if ((!acknowledge_flag (ARGV[i])))
  162. {
  163. if (j == 0)
  164. FIRST_COLOR = atoi (ARGV[i]);
  165. if (j == 1)
  166. COLOR_NUMBER = atoi (ARGV[i]);
  167. if (j >= 2)
  168. FILENAMES[j - 2] = ARGV[i];
  169. j++;
  170. }
  171. }
  172. if (COLOR_NUMBER < 8 || COLOR_NUMBER > 32)
  173. {
  174. /*
  175. * COLOR_NUMBER must be <=32 for weird implementation
  176. * reasons. There's no easy way to change this easily.
  177. */
  178. success = 0;
  179. if (!FLAG_HELP)
  180. printf ("ERROR! Color number must be between 8 and 32");
  181. }
  182. else
  183. {
  184. NUMBER_OF_FILES = j - 2;
  185. if (NUMBER_OF_FILES <= 0)
  186. {
  187. success = 0;
  188. if (!FLAG_HELP)
  189. printf ("ERROR! Too few arguments.\n");
  190. }
  191. }
  192. }
  193. return success;
  194. }
  195. /*-----------------------------------------------------------------*/
  196. /* acces disque */
  197. /*-----------------------------------------------------------------*/
  198. /*-----------------------------------------------------------------*/
  199. int
  200. load_file (char *filename)
  201. {
  202. int success;
  203. if (!FLAG_SILENT)
  204. printf ("Loading '%s'.\n", filename);
  205. if (BITMAP_SRC != NULL)
  206. destroy_bitmap (BITMAP_SRC);
  207. BITMAP_SRC = load_bitmap (filename, PALETTE_SRC);
  208. success = BITMAP_SRC != NULL;
  209. if (!success)
  210. printf ("ERROR! Unable to read '%s'.\n", filename);
  211. return success;
  212. }
  213. /*-----------------------------------------------------------------*/
  214. /* lecture des parametres du tableau */
  215. /*-----------------------------------------------------------------*/
  216. /*-----------------------------------------------------------------*/
  217. void
  218. get_range (void)
  219. {
  220. int min_x = BITMAP_SRC->w;
  221. int min_y = BITMAP_SRC->h;
  222. int max_x = -1;
  223. int max_y = -1;
  224. int x, y;
  225. for (y = 0; y < BITMAP_SRC->h; ++y)
  226. for (x = 0; x < BITMAP_SRC->w; ++x)
  227. if (getpixel (BITMAP_SRC, x, y) >= FIRST_COLOR ||
  228. getpixel (BITMAP_SRC, x, y) < FIRST_COLOR + COLOR_NUMBER)
  229. {
  230. if (min_x > x)
  231. min_x = x;
  232. if (min_y > y)
  233. min_y = y;
  234. if (max_x < x)
  235. max_x = x;
  236. if (max_y < y)
  237. max_y = y;
  238. }
  239. DST_X = min_x;
  240. DST_Y = min_y;
  241. DST_W = max_x - min_x + 1;
  242. DST_H = max_y - min_y + 1;
  243. if (DST_W < 1 || DST_H < 1)
  244. {
  245. printf ("ERROR! Texture is too small.\n");
  246. DST_W = DST_H = 1;
  247. }
  248. DST_SIZE = 3 * COLOR_NUMBER + ((DST_W * DST_H + 7) / 8) * 5;
  249. }
  250. /*-----------------------------------------------------------------*/
  251. void
  252. update_system_name (char *str)
  253. {
  254. char *search;
  255. memset (SYSTEM_NAME, 0, sizeof (SYSTEM_NAME));
  256. /*
  257. * No extension we just use the file name
  258. */
  259. strncpy (SYSTEM_NAME, str, sizeof (SYSTEM_NAME));
  260. search = strchr (SYSTEM_NAME, '.');
  261. if (search)
  262. {
  263. (*search) = '\0';
  264. }
  265. }
  266. /*-----------------------------------------------------------------*/
  267. /* conversion dans le buffer */
  268. /*-----------------------------------------------------------------*/
  269. /*-----------------------------------------------------------------*/
  270. void
  271. convert_to_buffer (void)
  272. {
  273. int pos = 0, pos8 = 0, x, y, i;
  274. char octet[5], toadd;
  275. int coul;
  276. for (i = 0; i < COLOR_NUMBER; ++i)
  277. {
  278. BUFFER[pos++] = PALETTE_SRC[FIRST_COLOR + i].r;
  279. BUFFER[pos++] = PALETTE_SRC[FIRST_COLOR + i].g;
  280. BUFFER[pos++] = PALETTE_SRC[FIRST_COLOR + i].b;
  281. }
  282. for (i = 0; i < 5; ++i)
  283. octet[i] = 0;
  284. for (y = 0; y < DST_H; ++y)
  285. for (x = 0; x < DST_W; ++x)
  286. {
  287. coul = getpixel (BITMAP_SRC, DST_X + x, DST_Y + y) - FIRST_COLOR;
  288. toadd = 1 << pos8;
  289. octet[0] |= (coul & 1) ? toadd : 0;
  290. octet[1] |= (coul & 2) ? toadd : 0;
  291. octet[2] |= (coul & 4) ? toadd : 0;
  292. octet[3] |= (coul & 8) ? toadd : 0;
  293. octet[4] |= (coul & 16) ? toadd : 0;
  294. if (pos8 == 7 || (y == DST_H - 1 && x == DST_W - 1))
  295. {
  296. for (i = 0; i < 5; ++i)
  297. {
  298. BUFFER[pos++] = octet[i];
  299. octet[i] = 0;
  300. }
  301. pos8 = 0;
  302. }
  303. else
  304. pos8++;
  305. }
  306. }
  307. /*-----------------------------------------------------------------*/
  308. /* on ecrit sur le disque */
  309. /*-----------------------------------------------------------------*/
  310. /*-----------------------------------------------------------------*/
  311. void
  312. change_ext (char *str)
  313. {
  314. char *ext;
  315. ext = strchr (str, '.');
  316. ext[1] = 't';
  317. ext[2] = 'e';
  318. ext[3] = 'x';
  319. }
  320. /*-----------------------------------------------------------------*/
  321. void
  322. write_to_disk (char *str)
  323. {
  324. FILE *f;
  325. short w, h;
  326. char header[4];
  327. if (!FLAG_SILENT)
  328. printf ("Writing %s to disk.\n", str);
  329. delete_file (str);
  330. f = fopen (str, "w");
  331. if (f != NULL)
  332. {
  333. w = DST_W;
  334. h = DST_H;
  335. /*
  336. * This is supposed to match the endianess used in
  337. * the serial.h/serial.c files of the core source.
  338. */
  339. header[0] = 0xFF & w;
  340. header[1] = w >> 8;
  341. header[2] = 0xFF & h;
  342. header[3] = h >> 8;
  343. fwrite (header, 4, 1, f);
  344. fwrite (SYSTEM_NAME, sizeof (SYSTEM_NAME), 1, f);
  345. fwrite (BUFFER, DST_SIZE, 1, f);
  346. fclose (f);
  347. }
  348. else
  349. {
  350. printf ("Unable to write %s.\n", str);
  351. }
  352. }
  353. /*=================================================================*/
  354. /* fonctions main */
  355. /*=================================================================*/
  356. /*-----------------------------------------------------------------*/
  357. int
  358. main (int argc, char **argv)
  359. {
  360. int i;
  361. ARGC = argc;
  362. ARGV = argv;
  363. #ifdef ALLEGRO_UNIX
  364. install_allegro (SYSTEM_NONE, &errno, atexit);
  365. #else
  366. allegro_init ();
  367. #endif
  368. set_color_depth (8);
  369. set_color_conversion (COLORCONV_REDUCE_TO_256);
  370. if (read_command_line ())
  371. {
  372. for (i = 0; i < NUMBER_OF_FILES; ++i)
  373. {
  374. if (load_file (FILENAMES[i]))
  375. {
  376. get_range ();
  377. convert_to_buffer ();
  378. update_system_name (FILENAMES[i]);
  379. change_ext (FILENAMES[i]);
  380. write_to_disk (FILENAMES[i]);
  381. }
  382. }
  383. }
  384. else
  385. {
  386. if (FLAG_HELP)
  387. display_long_help ();
  388. else
  389. display_short_help ();
  390. }
  391. allegro_exit ();
  392. return 0;
  393. }
  394. END_OF_MAIN ()