Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 
 

270 righe
5.9 KiB

  1. /*
  2. * libcaca ASCII-Art library
  3. * Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  19. * 02111-1307 USA
  20. */
  21. /** \file sprite.c
  22. * \version \$Id$
  23. * \author Sam Hocevar <sam@zoy.org>
  24. * \brief Sprite loading and blitting
  25. *
  26. * This file contains a small framework for sprite loading and blitting.
  27. */
  28. #include "config.h"
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include "caca.h"
  33. #include "caca_internals.h"
  34. struct caca_frame
  35. {
  36. int w, h;
  37. int dx, dy;
  38. char *chars;
  39. int *color;
  40. };
  41. struct caca_sprite
  42. {
  43. int nf;
  44. struct caca_frame *frames;
  45. };
  46. struct caca_sprite *caca_load_sprite(const char *file)
  47. {
  48. char buf[BUFSIZ];
  49. struct caca_sprite *sprite;
  50. FILE *fd;
  51. fd = fopen(file, "r");
  52. if(fd == NULL)
  53. return NULL;
  54. sprite = malloc(sizeof(struct caca_sprite));
  55. if(sprite == NULL)
  56. goto sprite_alloc_failed;
  57. sprite->nf = 0;
  58. sprite->frames = NULL;
  59. while(!feof(fd))
  60. {
  61. int x, y;
  62. int w = 0, h = 0, dx = 0, dy = 0;
  63. struct caca_frame *frame;
  64. /* Get width and height */
  65. if(!fgets(buf, BUFSIZ, fd))
  66. break;
  67. sscanf(buf, "%i %i %i %i", &w, &h, &dx, &dy);
  68. if(w <= 0 || h <= 0 || w > BUFSIZ / 2)
  69. break;
  70. if(sprite->nf)
  71. {
  72. void *tmp = realloc(sprite->frames,
  73. (sprite->nf + 1) * sizeof(struct caca_frame));
  74. if(tmp == NULL)
  75. goto frame_failed;
  76. sprite->frames = tmp;
  77. sprite->nf++;
  78. }
  79. else
  80. {
  81. sprite->frames = malloc((sprite->nf + 1) * sizeof(struct caca_frame));
  82. if(sprite->frames == NULL)
  83. goto sprite_failed;
  84. sprite->nf++;
  85. }
  86. frame = &sprite->frames[sprite->nf - 1];
  87. frame->w = w;
  88. frame->h = h;
  89. frame->dx = dx;
  90. frame->dy = dy;
  91. frame->chars = malloc(w * h * sizeof(char));
  92. if(frame->chars == NULL)
  93. {
  94. sprite->nf--;
  95. goto frame_failed;
  96. }
  97. frame->color = malloc(w * h * sizeof(int));
  98. if(frame->color == NULL)
  99. {
  100. free(frame->chars);
  101. sprite->nf--;
  102. goto frame_failed;
  103. }
  104. for(y = 0; y < h; y++)
  105. {
  106. if(!fgets(buf, BUFSIZ, fd))
  107. goto frame_failed;
  108. for(x = 0; x < w && buf[x] && buf[x] != '\r' && buf[x] != '\n'; x++)
  109. frame->chars[w * y + x] = buf[x];
  110. for(; x < w; x++)
  111. frame->chars[w * y + x] = ' ';
  112. }
  113. for(y = 0; y < h; y++)
  114. {
  115. if(!fgets(buf, BUFSIZ, fd))
  116. goto frame_failed;
  117. for(x = 0; x < w && buf[x] && buf[x] != '\r' && buf[x] != '\n'; x++)
  118. frame->color[w * y + x] = buf[x] - 'a';
  119. for(; x < w; x++)
  120. frame->color[w * y + x] = ' ' - 'a';
  121. }
  122. continue;
  123. }
  124. if(sprite->nf == 0)
  125. goto sprite_failed;
  126. fclose(fd);
  127. return sprite;
  128. frame_failed:
  129. while(sprite->nf)
  130. {
  131. free(sprite->frames[sprite->nf - 1].color);
  132. free(sprite->frames[sprite->nf - 1].chars);
  133. sprite->nf--;
  134. }
  135. sprite_failed:
  136. free(sprite);
  137. sprite_alloc_failed:
  138. fclose(fd);
  139. return NULL;
  140. }
  141. int caca_get_sprite_frames(struct caca_sprite *sprite)
  142. {
  143. if(sprite == NULL)
  144. return 0;
  145. return sprite->nf;
  146. }
  147. int caca_get_sprite_width(struct caca_sprite *sprite, int f)
  148. {
  149. if(sprite == NULL)
  150. return 0;
  151. if(f < 0 || f >= sprite->nf)
  152. return 0;
  153. return sprite->frames[f].w;
  154. }
  155. int caca_get_sprite_height(struct caca_sprite *sprite, int f)
  156. {
  157. if(sprite == NULL)
  158. return 0;
  159. if(f < 0 || f >= sprite->nf)
  160. return 0;
  161. return sprite->frames[f].h;
  162. }
  163. int caca_get_sprite_dx(struct caca_sprite *sprite, int f)
  164. {
  165. if(sprite == NULL)
  166. return 0;
  167. if(f < 0 || f >= sprite->nf)
  168. return 0;
  169. return sprite->frames[f].dx;
  170. }
  171. int caca_get_sprite_dy(struct caca_sprite *sprite, int f)
  172. {
  173. if(sprite == NULL)
  174. return 0;
  175. if(f < 0 || f >= sprite->nf)
  176. return 0;
  177. return sprite->frames[f].dy;
  178. }
  179. void caca_draw_sprite(int x, int y, struct caca_sprite *sprite, int f)
  180. {
  181. int i, j, oldcol;
  182. struct caca_frame *frame;
  183. if(sprite == NULL)
  184. return;
  185. if(f < 0 || f >= sprite->nf)
  186. return;
  187. frame = &sprite->frames[f];
  188. oldcol = caca_get_color();
  189. for(j = 0; j < frame->h; j++)
  190. {
  191. for(i = 0; i < frame->w; i++)
  192. {
  193. int col = frame->color[frame->w * j + i];
  194. if(col >= 0)
  195. {
  196. caca_set_color(col);
  197. caca_putchar(x + i - frame->dx, y + j - frame->dy,
  198. frame->chars[frame->w * j + i]);
  199. }
  200. }
  201. }
  202. caca_set_color(oldcol);
  203. }
  204. void caca_free_sprite(struct caca_sprite *sprite)
  205. {
  206. int i;
  207. if(sprite == NULL)
  208. return;
  209. for(i = sprite->nf; i--;)
  210. {
  211. struct caca_frame *frame = &sprite->frames[i];
  212. free(frame->chars);
  213. free(frame->color);
  214. }
  215. free(sprite->frames);
  216. free(sprite);
  217. }