source: libcaca/trunk/libee/sprite.c @ 135

Last change on this file since 135 was 135, checked in by Sam Hocevar, 18 years ago
  • libee/sprite.c: + Added sanity checks in ee_sprite_* functions.
  • libee/conic.c: + Use ellipsepoints() in ee_draw_circle().
  • Property svn:keywords set to Id
File size: 4.1 KB
Line 
1/*
2 *   libee         ASCII-Art library
3 *   Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
4 *                 All Rights Reserved
5 *
6 *   $Id: sprite.c 135 2003-11-10 18:29:04Z 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 "ee.h"
30
31struct ee_frame
32{
33    int w, h;
34    int dx, dy;
35    char *chars;
36    int *color;
37};
38
39struct ee_sprite
40{
41    int f;
42    int nf;
43    struct ee_frame *frames;
44};
45
46struct ee_sprite *ee_load_sprite(const char *file)
47{
48    char buf[BUFSIZ];
49    struct ee_sprite *sprite;
50    FILE *fd;
51
52    fd = fopen(file, "r");
53    if(fd == NULL)
54        return NULL;
55
56    sprite = malloc(sizeof(struct ee_sprite));
57    sprite->f = 0;
58    sprite->nf = 0;
59    sprite->frames = NULL;
60
61    while(!feof(fd))
62    {
63        int x, y;
64        int w = 0, h = 0, dx = 0, dy = 0;
65        struct ee_frame *frame;
66
67        /* Get width and height */
68        if(!fgets(buf, BUFSIZ, fd))
69            break;
70
71        sscanf(buf, "%i %i %i %i", &w, &h, &dx, &dy);
72        if(w <= 0 || h <= 0 || w > BUFSIZ / 2)
73            break;
74
75        if(sprite->nf++)
76            sprite->frames = realloc(sprite->frames,
77                                     sprite->nf * sizeof(struct ee_frame));
78        else
79            sprite->frames = malloc(sprite->nf * sizeof(struct ee_frame));
80        frame = &sprite->frames[sprite->nf - 1];
81
82        frame->w = w;
83        frame->h = h;
84        frame->dx = dx;
85        frame->dy = dy;
86        frame->chars = malloc(w * h * sizeof(char));
87        frame->color = malloc(w * h * sizeof(int));
88
89        for(y = 0; y < h; y++)
90        {
91            memset(buf, ' ', w);
92            buf[w] = '\0';
93            if(!fgets(buf, BUFSIZ, fd))
94                goto failed;
95
96            for(x = 0; x < w; x++)
97                frame->chars[w * y + x] = buf[x];
98        }
99
100        for(y = 0; y < h; y++)
101        {
102            memset(buf, ' ', w);
103            buf[w] = '\0';
104            if(!fgets(buf, BUFSIZ, fd))
105                goto failed;
106
107            for(x = 0; x < w; x++)
108                frame->color[w * y + x] = buf[x] - 'a';
109        }
110
111        continue;
112
113    failed:
114        free(sprite->frames[sprite->nf - 1].chars);
115        free(sprite->frames[sprite->nf - 1].color);
116        sprite->nf--;
117        break;
118    }
119
120    fclose(fd);
121
122    if(sprite->nf == 0)
123    {
124        free(sprite);
125        return NULL;
126    }
127
128    return sprite;
129}
130
131void ee_set_sprite_frame(struct ee_sprite *sprite, int f)
132{
133    if(sprite == NULL)
134        return;
135
136    if(f < 0 || f >= sprite->nf)
137        return;
138
139    sprite->f = f;
140}
141
142int ee_get_sprite_frame(struct ee_sprite *sprite)
143{
144    if(sprite == NULL)
145        return -1;
146
147    return sprite->f;
148}
149
150void ee_draw_sprite(int x, int y, struct ee_sprite *sprite)
151{
152    int i, j;
153    struct ee_frame *frame;
154
155    if(sprite == NULL)
156        return;
157
158    frame = &sprite->frames[sprite->f];
159
160    for(j = 0; j < frame->h; j++)
161    {
162        for(i = 0; i < frame->w; i++)
163        {
164            int col = frame->color[frame->w * j + i];
165            if(col >= 0)
166            {
167                ee_goto(x + i - frame->dx, y + j - frame->dy);
168                ee_color(col);
169                ee_putchar(frame->chars[frame->w * j + i]);
170            }
171        }
172    }
173}
174
175void ee_free_sprite(struct ee_sprite *sprite)
176{
177    int i;
178
179    if(sprite == NULL)
180        return;
181
182    for(i = sprite->nf; i--;)
183    {
184        struct ee_frame *frame = &sprite->frames[i];
185        free(frame->chars);
186        free(frame->color);
187    }
188
189    free(sprite->frames);
190    free(sprite);
191}
192
Note: See TracBrowser for help on using the repository browser.