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.
 
 
 
 
 

263 lines
5.6 KiB

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