source: libcaca/trunk/libcaca/sprite.c @ 185

Last change on this file since 185 was 185, checked in by Sam Hocevar, 19 years ago
  • Renamed libee to libcaca. Far less collisions.
  • Property svn:keywords set to Id
File size: 5.7 KB
Line 
1/*
2 *   libcaca       ASCII-Art library
3 *   Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
4 *                 All Rights Reserved
5 *
6 *   $Id: sprite.c 185 2003-11-16 00:33:35Z sam $
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
23#include "config.h"
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28
29#include "caca.h"
30#include "caca_internals.h"
31
32struct caca_frame
33{
34    int w, h;
35    int dx, dy;
36    char *chars;
37    int *color;
38};
39
40struct caca_sprite
41{
42    int nf;
43    struct caca_frame *frames;
44};
45
46struct caca_sprite *caca_load_sprite(const char *file)
47{
48    char buf[BUFSIZ];
49    struct caca_sprite *sprite;
50    FILE *fd;
51
52    fd = fopen(file, "r");
53    if(fd == NULL)
54        return NULL;
55
56    sprite = malloc(sizeof(struct caca_sprite));
57    if(sprite == NULL)
58        goto sprite_alloc_failed;
59
60    sprite->nf = 0;
61    sprite->frames = NULL;
62
63    while(!feof(fd))
64    {
65        int x, y;
66        int w = 0, h = 0, dx = 0, dy = 0;
67        struct caca_frame *frame;
68
69        /* Get width and height */
70        if(!fgets(buf, BUFSIZ, fd))
71            break;
72
73        sscanf(buf, "%i %i %i %i", &w, &h, &dx, &dy);
74        if(w <= 0 || h <= 0 || w > BUFSIZ / 2)
75            break;
76
77        if(sprite->nf)
78        {
79            void *tmp = realloc(sprite->frames,
80                                (sprite->nf + 1) * sizeof(struct caca_frame));
81            if(tmp == NULL)
82                goto frame_failed;
83            sprite->frames = tmp;
84            sprite->nf++;
85        }
86        else
87        {
88            sprite->frames = malloc((sprite->nf + 1) * sizeof(struct caca_frame));
89            if(sprite->frames == NULL)
90                goto sprite_failed;
91            sprite->nf++;
92        }
93
94        frame = &sprite->frames[sprite->nf - 1];
95
96        frame->w = w;
97        frame->h = h;
98        frame->dx = dx;
99        frame->dy = dy;
100        frame->chars = malloc(w * h * sizeof(char));
101        if(frame->chars == NULL)
102        {
103            sprite->nf--;
104            goto frame_failed;
105        }
106        frame->color = malloc(w * h * sizeof(int));
107        if(frame->color == NULL)
108        {
109            free(frame->chars);
110            sprite->nf--;
111            goto frame_failed;
112        }
113
114        for(y = 0; y < h; y++)
115        {
116            if(!fgets(buf, BUFSIZ, fd))
117                goto frame_failed;
118
119            for(x = 0; x < w && buf[x] && buf[x] != '\r' && buf[x] != '\n'; x++)
120                frame->chars[w * y + x] = buf[x];
121
122            for(; x < w; x++)
123                frame->chars[w * y + x] = ' ';
124        }
125
126        for(y = 0; y < h; y++)
127        {
128            if(!fgets(buf, BUFSIZ, fd))
129                goto frame_failed;
130
131            for(x = 0; x < w && buf[x] && buf[x] != '\r' && buf[x] != '\n'; x++)
132                frame->color[w * y + x] = buf[x] - 'a';
133
134            for(; x < w; x++)
135                frame->color[w * y + x] = ' ' - 'a';
136        }
137
138        continue;
139    }
140
141    if(sprite->nf == 0)
142        goto sprite_failed;
143
144    fclose(fd);
145    return sprite;
146
147frame_failed:
148    while(sprite->nf)
149    {
150        free(sprite->frames[sprite->nf - 1].color);
151        free(sprite->frames[sprite->nf - 1].chars);
152        sprite->nf--;
153    }
154sprite_failed:
155    free(sprite);
156sprite_alloc_failed:
157    fclose(fd);
158    return NULL;
159}
160
161int caca_get_sprite_frames(struct caca_sprite *sprite)
162{
163    if(sprite == NULL)
164        return 0;
165
166    return sprite->nf;
167}
168
169int caca_get_sprite_width(struct caca_sprite *sprite, int f)
170{
171    if(sprite == NULL)
172        return 0;
173
174    if(f < 0 || f >= sprite->nf)
175        return 0;
176
177    return sprite->frames[f].w;
178}
179
180int caca_get_sprite_height(struct caca_sprite *sprite, int f)
181{
182    if(sprite == NULL)
183        return 0;
184
185    if(f < 0 || f >= sprite->nf)
186        return 0;
187
188    return sprite->frames[f].h;
189}
190
191int caca_get_sprite_dx(struct caca_sprite *sprite, int f)
192{
193    if(sprite == NULL)
194        return 0;
195
196    if(f < 0 || f >= sprite->nf)
197        return 0;
198
199    return sprite->frames[f].dx;
200}
201
202int caca_get_sprite_dy(struct caca_sprite *sprite, int f)
203{
204    if(sprite == NULL)
205        return 0;
206
207    if(f < 0 || f >= sprite->nf)
208        return 0;
209
210    return sprite->frames[f].dy;
211}
212
213void caca_draw_sprite(int x, int y, struct caca_sprite *sprite, int f)
214{
215    int i, j, oldcol;
216    struct caca_frame *frame;
217
218    if(sprite == NULL)
219        return;
220
221    if(f < 0 || f >= sprite->nf)
222        return;
223
224    frame = &sprite->frames[f];
225
226    oldcol = caca_get_color();
227
228    for(j = 0; j < frame->h; j++)
229    {
230        for(i = 0; i < frame->w; i++)
231        {
232            int col = frame->color[frame->w * j + i];
233            if(col >= 0)
234            {
235                caca_set_color(col);
236                caca_putchar(x + i - frame->dx, y + j - frame->dy,
237                           frame->chars[frame->w * j + i]);
238            }
239        }
240    }
241
242    caca_set_color(oldcol);
243}
244
245void caca_free_sprite(struct caca_sprite *sprite)
246{
247    int i;
248
249    if(sprite == NULL)
250        return;
251
252    for(i = sprite->nf; i--;)
253    {
254        struct caca_frame *frame = &sprite->frames[i];
255        free(frame->chars);
256        free(frame->color);
257    }
258
259    free(sprite->frames);
260    free(sprite);
261}
262
Note: See TracBrowser for help on using the repository browser.